1. 程式人生 > >python學習之logging

python學習之logging

sat imp opened 指定 方法 逗號 ide 還需 basic

學習地址:http://blog.csdn.net/zyz511919766/article/details/25136485

首先如果我們想簡要的打印出日誌,可以:

import logging

logging.debug(i am debug)
logging.inof(i am info)
logging.warning(i am warning)
logging.error(i am error)
logging.critical( i am critical)



#打印的結果
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message

可見,默認情況下python的logging模塊將日誌打印到了標準輸出中,且只顯示了大於等於WARNING級別的日誌,這說明默認的日誌級別設置為WARNING(日誌級別等級CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),默認的日誌格式為日誌級別:Logger名稱:用戶輸出消息。

當然這只是默認的情況下打印日誌的情況,如果我們需要靈活配置日誌級別,日誌格式,輸出位置,那麽我們將如下:

#testadd.py

import logging

logging.basicConfig(level=logging.DEBUG,    #
日誌的級別 filename=./tmp/test.log, #日誌保存的位置 format=%(asctime)s %(filname)s[line:%(lineno)d] %(levelname)s %(message)s, #handler輸出的格式 filemode=w, #文件打開的方式,如果指定了filename這個參數時,默認為‘a‘ datefmt=%a,%d %b %Y %H:%M:%S, #時間的輸出格式,%a為星期,%d為日,%b為月,%Y為年
stream=sys.stdout) #用於創建streamHandler,有sys.stdout,sys.stderr兩種方式,如果指定了filename,則stream會被忽視 logging.debug(debug message) logging.info(info message) logging.warning(warning message) logging.error(error message) logging.critical(critical message) format參數中可能用到的格式化串: %(name)s Logger的名字 ;比如上面如果我使用了name,那麽會在日誌中顯示為root,因為默認的logger就為root,如果我們設置有Logger,那麽這裏會顯示我們設置的logger的名字 %(levelno)s 數字形式的日誌級別 10 20 30 40 50 %(levelname)s 文本形式的日誌級別 DEBUG<INFO<WARNING<ERROR<CRITICAL 默認情況下,日誌只會顯示大於等於WARNING的日誌 %(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有 比如這裏就是testadd.py的完整路徑 %(filename)s 調用日誌輸出函數的模塊的文件名 比如這裏就是testadd.py %(module)s 調用日誌輸出函數的模塊名 比如這裏就是testadd %(funcName)s 調用日誌輸出函數的函數名 如果有就輸出調用日誌輸出函數的函數名,如果沒有就輸出<module> %(lineno)d 調用日誌輸出函數的語句所在的代碼行 輸出日誌語句在testadd.py中的位置 %(created)f 當前時間,用UNIX標準的表示時間的浮 點數表示 %(relativeCreated)d 輸出日誌信息時的,自Logger創建以 來的毫秒數 %(asctime)s 字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒 %(thread)d 線程ID。可能沒有 %(threadName)s 線程名。可能沒有 %(process)d 進程ID。可能沒有 %(message)s用戶輸出的消息

test.log日誌文件打印的日誌如下:

Sat, 11 Nov 2017 16:31:06 testadd.py[line:12] DEBUG debug message
Sat, 11 Nov 2017 16:31:06 testadd.py[line:13] INFO info message
Sat, 11 Nov 2017 16:31:06 testadd.py[line:14] WARNING warning message
Sat, 11 Nov 2017 16:31:06 testadd.py[line:15] ERROR error message
Sat, 11 Nov 2017 16:31:06 testadd.py[line:16] CRITICAL critical message

如上只是一個簡單的日誌的配置,如果還需要更靈活的配置我們自己想要的日誌信息、格式,那麽就有必要了解下Logger,Handler,Formatter,Filter的概念。
上述幾個例子中我們了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分別用以記錄不同級別的日誌信息),logging.basicConfig()(用默認日誌格式(Formatter)為日誌系統建立一個默認的流處理器(StreamHandler),設置基礎配置(如日誌級別等)並加到root logger(根Logger)中)這幾個logging模塊級別的函數,另外還有一個模塊級別的函數是logging.getLogger([name])(返回一個logger對象,如果沒有指定名字將返回root logger

簡單介紹一,logging庫提供的多個組件:Logger、Handler、Filter、Formatter。Logger對象提供應用程序可直接使用的接口,Handler發送日誌到適當的目的地,Filter提供了過濾日誌信息的方法,Formatter指定日誌顯示格式;下面我們將仔細的來學習:

1.Logger

Logger是一個樹形層級結構,輸出信息之前都要獲得一個Logger(如果沒有顯示的獲取則自動創建並使用root Logger)。
logger = logging.getLogger()返回一個默認的Logger也即root Logger,並用默認的日誌級別(大於等於warning的)、Handler和Formatter設置(最上方的第一個例子就是使用的logging的默認配置展示出來的日誌信息)。
當然也可以通過Logger.setLevel(lel)指定最低的日誌級別,可用的日誌級別有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()輸出不同級別的日誌,只有日誌等級大於或等於設置的日誌級別的日誌才會被輸出。

技術分享
#coding:utf-8  
import logging  
  
# 創建一個logger    
logger = logging.getLogger()  
  
logger1 = logging.getLogger(mylogger)  
logger1.setLevel(logging.DEBUG)  
  
logger2 = logging.getLogger(mylogger)  
logger2.setLevel(logging.INFO)  
  
logger3 = logging.getLogger(mylogger.child1)  
logger3.setLevel(logging.WARNING)  
  
logger4 = logging.getLogger(mylogger.child1.child2)  
logger4.setLevel(logging.DEBUG)  
  
logger5 = logging.getLogger(mylogger.child1.child2.child3)  
logger5.setLevel(logging.DEBUG)  
  
# 創建一個handler,用於寫入日誌文件    
fh = logging.FileHandler(/tmp/test.log)  
  
# 再創建一個handler,用於輸出到控制臺    
ch = logging.StreamHandler()  
  
# 定義handler的輸出格式formatter    
formatter = logging.Formatter(%(asctime)s - %(name)s - %(levelname)s - %(message)s)  
fh.setFormatter(formatter)  
ch.setFormatter(formatter)  
  
#定義一個filter  
#filter = logging.Filter(‘mylogger.child1.child2‘)  
#fh.addFilter(filter)    
  
# 給logger添加handler    
#logger.addFilter(filter)  
logger.addHandler(fh)  
logger.addHandler(ch)  
  
#logger1.addFilter(filter)  
logger1.addHandler(fh)  
logger1.addHandler(ch)  
  
logger2.addHandler(fh)  
logger2.addHandler(ch)  
  
#logger3.addFilter(filter)  
logger3.addHandler(fh)  
logger3.addHandler(ch)  
  
#logger4.addFilter(filter)  
logger4.addHandler(fh)  
logger4.addHandler(ch)  
  
logger5.addHandler(fh)  
logger5.addHandler(ch)  
  
# 記錄一條日誌    
logger.debug(logger debug message)  
logger.info(logger info message)  
logger.warning(logger warning message)  
logger.error(logger error message)  
logger.critical(logger critical message)  
  
logger1.debug(logger1 debug message)  
logger1.info(logger1 info message)  
logger1.warning(logger1 warning message)  
logger1.error(logger1 error message)  
logger1.critical(logger1 critical message)  
  
logger2.debug(logger2 debug message)  
logger2.info(logger2 info message)  
logger2.warning(logger2 warning message)  
logger2.error(logger2 error message)  
logger2.critical(logger2 critical message)  
  
logger3.debug(logger3 debug message)  
logger3.info(logger3 info message)  
logger3.warning(logger3 warning message)  
logger3.error(logger3 error message)  
logger3.critical(logger3 critical message)  
  
logger4.debug(logger4 debug message)  
logger4.info(logger4 info message)  
logger4.warning(logger4 warning message)  
logger4.error(logger4 error message)  
logger4.critical(logger4 critical message)  
  
logger5.debug(logger5 debug message)  
logger5.info(logger5 info message)  
logger5.warning(logger5 warning message)  
logger5.error(logger5 error message)  
logger5.critical(logger5 critical message) 
View Code

輸出的結果如下:

技術分享
2014-05-06 12:54:43,222 - root - WARNING - logger warning message
2014-05-06 12:54:43,223 - root - ERROR - logger error message
2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
2014-05-06 12:54:43,224 - mylogger - INFO - logger1 info message
2014-05-06 12:54:43,224 - mylogger - INFO - logger1 info message
2014-05-06 12:54:43,225 - mylogger - WARNING - logger1 warning message
2014-05-06 12:54:43,225 - mylogger - WARNING - logger1 warning message
2014-05-06 12:54:43,226 - mylogger - ERROR - logger1 error message
2014-05-06 12:54:43,226 - mylogger - ERROR - logger1 error message
2014-05-06 12:54:43,227 - mylogger - CRITICAL - logger1 critical message
2014-05-06 12:54:43,227 - mylogger - CRITICAL - logger1 critical message
2014-05-06 12:54:43,228 - mylogger - INFO - logger2 info message
2014-05-06 12:54:43,228 - mylogger - INFO - logger2 info message
2014-05-06 12:54:43,229 - mylogger - WARNING - logger2 warning message
2014-05-06 12:54:43,229 - mylogger - WARNING - logger2 warning message
2014-05-06 12:54:43,230 - mylogger - ERROR - logger2 error message
2014-05-06 12:54:43,230 - mylogger - ERROR - logger2 error message
2014-05-06 12:54:43,231 - mylogger - CRITICAL - logger2 critical message
2014-05-06 12:54:43,231 - mylogger - CRITICAL - logger2 critical message
2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
2014-05-06 12:54:43,232 - mylogger.child1 - WARNING - logger3 warning message
2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
2014-05-06 12:54:43,234 - mylogger.child1 - ERROR - logger3 error message
2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
2014-05-06 12:54:43,235 - mylogger.child1 - CRITICAL - logger3 critical message
2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 12:54:43,237 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 12:54:43,239 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 12:54:43,240 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 12:54:43,242 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 12:54:43,243 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,244 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,246 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,247 - mylogger.child1.child2.child3 - WARNING - logger5 warning message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,249 - mylogger.child1.child2.child3 - ERROR - logger5 error message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
2014-05-06 12:54:43,250 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message
View Code

從輸出的結果中我們可以看出:

1.從這個輸出可以看出logger = logging.getLogger()返回的Logger名為root。這裏沒有用logger.setLevel()顯示的為logger設置日誌級別,所以使用默認的日誌級別WARNIING,故結果只輸出了大於等於WARNIING級別的信息。

2.另外,我們明明通過logger1.setLevel(logging.DEBUG)將logger1的日誌級別設置為了DEBUG,為何顯示的時候沒有顯示出DEBUG級別的日誌信息,而是從INFO級別的日誌開始顯示呢?原來logger1和logger2對應的是同一個Logger實例,只要logging.getLogger(name)中名稱參數name相同則返回的Logger實例就是同一個,且僅有一個,也即name與Logger實例一一對應。在logger2實例中通過logger2.setLevel(logging.INFO)設置mylogger的日誌級別為logging.INFO,所以最後logger1的輸出遵從了後來設置的日誌級別

3.為什麽logger1、logger2對應的每個輸出分別顯示兩次,logger3對應的輸出顯示3次,logger4對應的輸出顯示4次......呢?

這是因為我們通過logger = logging.getLogger()顯示的創建了root Logger,而logger1 = logging.getLogger(‘mylogger‘)創建了root Logger的孩子(root.)mylogger,

logger2也是同樣的道理,所以logger2也會輸出兩次。
logger3 = logging.getLogger(‘mylogger.child1‘)創建了(root.)mylogger.child1 只要使用了上一個的name再加上.號就表示是上一個的下一級
logger4 = logging.getLogger(‘mylogger.child1.child2‘)創建了(root.)mylogger.child1.child2
logger5 = logging.getLogger(‘mylogger.child1.child2.child3‘)創建了(root.)mylogger.child1.child2.child3

而孩子,孫子,重孫……既會將消息分發給他自己本身的handler進行處理也會傳遞給所有的祖先Logger的handler處理

如果在代碼中,我們註銷了r

#logger.addHandler(fh)

這麽一句

python學習之logging