轉載至http://blog.chinaunix.net/uid-26000296-id-4372063.html
一、簡單將日志打印到屏幕:
- import logging
- logging.debug('debug message')
- logging.info('info message')
- logging.warning('warning message')
- logging.error('error message')
- logging.critical('critical message')
輸出:
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
可見,默認情況下python的logging模塊將日志打印到了標准輸出中,且只顯示了大於等於WARNING級別的日志,
這說明默認的日志級別設置為WARNING(日志級別等級CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),
默認的日志格式為:
日志級別:Logger名稱:用戶輸出消息。
二、靈活配置日志級別,日志格式,輸出位置
- import logging
- logging.basicConfig(level=logging.DEBUG,
- format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
- datefmt='%a, %d %b %Y %H:%M:%S',
- filename='/tmp/test.log',
- filemode='w')
- logging.debug('debug message')
- logging.info('info message')
- logging.warning('warning message')
- logging.error('error message')
- logging.critical('critical message')
cat /tmp/test.log
Mon, 05 May 2014 16:29:53 test_logging.py[line:9] DEBUG debug message
Mon, 05 May 2014 16:29:53 test_logging.py[line:10] INFO info message
Mon, 05 May 2014 16:29:53 test_logging.py[line:11] WARNING warning message
Mon, 05 May 2014 16:29:53 test_logging.py[line:12] ERROR error message
Mon, 05 May 2014 16:29:53 test_logging.py[line:13] CRITICAL critical message
可見在logging.basicConfig()函數中可通過具體參數來更改logging模塊默認行為,可用參數有
filename: 用指定的文件名創建FiledHandler(后邊會具體講解handler的概念),這樣日志會被存儲在指定的文件中。
filemode: 文件打開方式,在指定了filename時使用這個參數,默認值為“a”還可指定為“w”。
format: 指定handler使用的日志顯示格式。
datefmt: 指定日期時間格式。
level: 設置rootlogger(后邊會講解具體概念)的日志級別
stream: 用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件,默認為sys.stderr。
若同時列出了filename和stream兩個參數,則stream參數會被忽略。
format參數中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 數字形式的日志級別
%(levelname)s 文本形式的日志級別
%(pathname)s 調用日志輸出函數的模塊的完整路徑名,可能沒有
%(filename)s 調用日志輸出函數的模塊的文件名
%(module)s 調用日志輸出函數的模塊名
%(funcName)s 調用日志輸出函數的函數名
%(lineno)d 調用日志輸出函數的語句所在的代碼行
%(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 用戶輸出的消息
若要對logging進行更多靈活的控制有必要了解一下
三、 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)
先看一個具體的例子
- #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')
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
先簡單介紹一下,logging庫提供了多個組件:Logger、Handler、Filter、Formatter。
Logger 對象提供應用程序可直接使用的接口,
Handler 發送日志到適當的目的地,
Filter 提供了過濾日志信息的方法,
Formatter 指定日志顯示格式。
1. Logger
Logger是一個樹形層級結構,輸出信息之前都要獲得一個Logger(如果沒有顯示的獲取則自動創建並使用root Logger,如第一個例子所示)。logger = logging.getLogger() 返回一個默認的Logger也即root Logger,並應用默認的日志級別、Handler和Formatter設置。
當然也可以通過Logger.setLevel(lel)指定最低的日志級別,可用的日志級別有:
logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()
輸出不同級別的日志,只有日志等級大於或等於設置的日志級別的日志才會被輸出。
我們看到程序中
- 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')
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
從這個輸出可以看出logger = logging.getLogger()返回的Logger名為root。
這里沒有用logger.setLevel()顯示的為logger設置日志級別,所以使用默認的日志級別WARNIING,
故結果只輸出了大於等於WARNIING級別的信息。
另外,我們明明通過 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的輸出遵從了后來設置的日志級別。
- logger1 = logging.getLogger('mylogger')
- logger1.setLevel(logging.DEBUG)
- logger2 = logging.getLogger('mylogger')
- logger2.setLevel(logging.INFO)
這是因為我們通過logger = logging.getLogger()顯示的創建了root Logger,
而logger1 = logging.getLogger('mylogger')創建了root Logger的孩子(root.)mylogger,logger2同樣。
logger3 = logging.getLogger('mylogger.child1')創建了(root.)mylogger.child1
logger4 = logging.getLogger('mylogger.child1.child2')創建了(root.)mylogger.child1.child2
logger5 = logging.getLogger('mylogger.child1.child2.child3')創建了(root.)mylogger.child1.child2.child3
而孩子,孫子,重孫……既會將消息分發給他的handler進行處理也會傳遞給所有的祖先Logger處理。
試着注釋掉如下一行程序,觀察程序輸出
- #logger.addHandler(fh)
2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message
2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message
……
而在文件輸出中每條記錄對應一行(因為我們注釋掉了logger.addHandler(fh),沒有對root Logger啟用FileHandler)
2014-05-06 15:10:10,980 - mylogger - INFO - logger1 info message
2014-05-06 15:10:10,981 - mylogger - WARNING - logger1 warning message
2014-05-06 15:10:10,982 - mylogger - ERROR - logger1 error message
2014-05-06 15:10:10,984 - mylogger - CRITICAL - logger1 critical message
孩子,孫子,重孫……可逐層繼承來自祖先的日志級別、Handler、Filter設置,
也可以通過Logger.setLevel(lel)、Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)、Logger.addFilter(filt)、Logger.removeFilter(filt)。
設置自己特別的日志級別、Handler、Filter。若不設置則使用繼承來的值。
2. Handler
上述例子的輸出在標准輸出和指定的日志文件中均可以看到,這是因為我們定義並使用了兩種Handler。- fh = logging.FileHandler('/tmp/test.log')
- ch = logging.StreamHandler()
Handler.setLevel(lel): 指定日志級別,低於lel級別的日志將被忽略
Handler.setFormatter(): 給這個handler選擇一個Formatter
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或刪除一個filter對象
可以通過addHandler()方法為Logger添加多個Handler:
- logger.addHandler(fh)
- logger.addHandler(ch)
有多中可用的Handler:
logging.StreamHandler 可以向類似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息logging.FileHandler 用於向一個文件輸出日志信息
logging.handlers.RotatingFileHandler 類似於上面的FileHandler,但是它可以管理文件大小。
當文件達到一定大小之后,它會自動將當前日志文件改名,然后創建一個新的同名日志文件繼續輸出
logging.handlers.TimedRotatingFileHandler 和RotatingFileHandler類似,不過,它沒有通過判斷文件大小來決定何時重新創建日志文件,而是間隔一定時間就自動創建新的日志文件
logging.handlers.SocketHandler 使用TCP協議,將日志信息發送到網絡。
logging.handlers.DatagramHandler 使用UDP協議,將日志信息發送到網絡。
logging.handlers.SysLogHandler 日志輸出到syslog
logging.handlers.NTEventLogHandler 遠程輸出日志到Windows NT/2000/XP的事件日志
logging.handlers.SMTPHandler 遠程輸出日志到郵件地址
logging.handlers.MemoryHandler 日志輸出到內存中的制定buffer
logging.handlers.HTTPHandler 通過"GET"或"POST"遠程輸出到HTTP服務器
各個Handler的具體用法可查看參考書冊:
https://docs.python.org/2/library/logging.handlers.html#module-logging.handlers
3. Formatter
Formatter對象設置日志信息最后的規則、結構和內容,默認的時間格式為%Y-%m-%d %H:%M:%S。- #定義Formatter
- formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
- #為Handler添加Formatter
- fh.setFormatter(formatter)
- ch.setFormatter(formatter)
4. Filter
限制只有滿足過濾規則的日志才會輸出。比如我們定義了filter = logging.Filter('a.b.c'),並將這個Filter添加到了一個Handler上,
則使用該Handler的Logger中只有名字帶a.b.c前綴的Logger才能輸出其日志。
取消下列兩行程序的注釋
- #filter = logging.Filter('mylogger.child1.child2')
- #fh.addFilter(filter)
2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:27:36,227 - mylogger.child1.child2 - DEBUG - logger4 debug message
2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:27:36,228 - mylogger.child1.child2 - INFO - logger4 info message
2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:27:36,230 - mylogger.child1.child2 - WARNING - logger4 warning message
2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:27:36,232 - mylogger.child1.child2 - ERROR - logger4 error message
2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:27:36,233 - mylogger.child1.child2 - CRITICAL - logger4 critical message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,235 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message
2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message
2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message 2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message 2014-05-06 15:27:36,236 - mylogger.child1.child2.child3 - INFO - logger5 info message 2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:27:36,238 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:27:36,240 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 2014-05-06 15:27:36,242 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 當然也可以直接給Logger加Filter。 若為Handler加Filter則所有使用了該Handler的Logger都會受到影響。而為Logger添加Filter只會影響到自身。 注釋掉 [python] view plaincopy #fh.addFilter(filter) 並取消如下幾行的注釋 [python] view plaincopy #logger.addFilter(filter) #logger1.addFilter(filter) #logger3.addFilter(filter) #logger4.addFilter(filter) 輸出結果 2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message 2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message 2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message 2014-05-06 15:32:10,746 - mylogger.child1.child2 - DEBUG - logger4 debug message 2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message 2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message 2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message 2014-05-06 15:32:10,748 - mylogger.child1.child2 - INFO - logger4 info message 2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message 2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message 2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message 2014-05-06 15:32:10,751 - mylogger.child1.child2 - WARNING - logger4 warning message 2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message 2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message 2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message 2014-05-06 15:32:10,753 - mylogger.child1.child2 - ERROR - logger4 error message 2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message 2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message 2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message 2014-05-06 15:32:10,754 - mylogger.child1.child2 - CRITICAL - logger4 critical message 2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message 2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message 2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message 2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message 2014-05-06 15:32:10,755 - mylogger.child1.child2.child3 - DEBUG - logger5 debug message 2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message 2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message 2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message 2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message 2014-05-06 15:32:10,757 - mylogger.child1.child2.child3 - INFO - logger5 info message 2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:32:10,759 - mylogger.child1.child2.child3 - WARNING - logger5 warning message 2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:32:10,761 - mylogger.child1.child2.child3 - ERROR - logger5 error message 2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 2014-05-06 15:32:10,762 - mylogger.child1.child2.child3 - CRITICAL - logger5 critical message 發現root、mylogger、mylogger.child1的輸出全部被過濾掉了。 除了直接在程序中設置Logger,Handler,Filter,Formatter外還可以 四、將這些信息寫進配置文件中。 例如典型的logging.conf [python] view plaincopy [loggers] keys=root,simpleExample [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=consoleHandler [logger_simpleExample] level=DEBUG handlers=consoleHandler qualname=simpleExample propagate=0 [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s datefmt= 程序可以這么寫 [python] view plaincopy import logging import logging.config logging.config.fileConfig("logging.conf") # 采用配置文件 # create logger logger = logging.getLogger("simpleExample") # "application" code logger.debug("debug message") logger.info("info message") logger.warn("warn message") logger.error("error message") logger.critical("critical message") 五、多模塊使用logging logging模塊保證在同一個python解釋器內,多次調用logging.getLogger('log_name')都會返回同一個logger實例,即使是在多個模塊的情況下。 所以典型的多模塊場景下使用logging的方式是在main模塊中配置logging,這個配置會作用於多個的子模塊, 然后在其他模塊中直接通過getLogger獲取Logger對象即可。 main.py: [python] view plaincopy import logging import logging.config logging.config.fileConfig('logging.conf') root_logger = logging.getLogger('root') root_logger.debug('test root logger...') logger = logging.getLogger('main') logger.info('test main logger') logger.info('start import module \'mod\'...') import mod logger.debug('let\'s test mod.testLogger()') mod.testLogger() root_logger.info('finish test...') 子模塊mod.py: [python] view plaincopy import logging import submod logger = logging.getLogger('main.mod') logger.info('logger of mod say something...') def testLogger(): logger.debug('this is mod.testLogger...') submod.tst() 子子模塊submod.py: [python] view plaincopy import logging logger = logging.getLogger('main.mod.submod') logger.info('logger of submod say something...') def tst(): logger.info('this is submod.tst()...') [python] view plaincopy