一、從乙個使用場景開始
開發乙個日誌系統, 既要把日誌輸出到控制台, 還要寫入日誌檔案
import logging
# 建立乙個logger
logger = logging.getlogger('mylogger')
logger.setlevel(logging.de程式設計客棧bug)
# 建立乙個handler,用於寫入日誌檔案
fh = logging.filehandler('test.log')
fh.setlevel(logging.debug)
# 再建立乙個handler,用於輸出到控制台
ch = logging.streamhandler()
ch.setlevel(logging.debug)
# 定義handler的輸出格式
formatter = logging.formatter('%(asctime)s - %(name)s - %(levelname)s - 程式設計客棧%(message)s')
fh.setformatter(formatter)
ch.setformatter(formatter)
# 給logger新增handler
logger.addhan程式設計客棧dler(fh)
logger.addhandler(ch)
# 記錄一條日誌
logger.info('foorbar')
執行後, 在控制台和日誌檔案都有一條日誌:
2011-08-31 19:18:29,816 - mylogger - info - foorbar
二、logging模組的api
結合上面的例子,我們說下幾個最常使用的api
logging.getlogger([name])返回乙個logger例項,如果沒有指定name,返回root logger。只要name相同,返回的logger例項都是同乙個而且只有乙個,即name和logger例項是一一對應的。這意味著,無需把logger例項在各個模組中傳遞。只要知道name,就能得到同乙個logger例項
logger.setlevel(lvl)設定logger的level, level有以下幾個級別:
notset < debug < info < warning < error < critical
如果把looger的級別設定為info, 那麼小於info級別的日誌都不輸出, 大於等於info級別的日誌都輸出
logger.debug("foobar") # 不輸出
logger.info("foobar") # 輸出
logger.warning("foobar") # 輸出
logger.error("foobar") # 輸出
logger.critical("foobar") # 輸出
logger.addhandler(hdlr)logger可以僱傭handler來幫它處理日誌, handler主要有以下幾種:streamhandler : 輸出到控制台filehandler : 輸出到檔案handler還可以設定自己的level以及輸出格式。
logging.basicconfig([**kwargs])
這個函式用來配置root logger, 可以看它的原始碼,還是挺簡單的。它首先檢查root是否有handler,如果沒有,那這個函式會建立乙個streamhandler,並設定預設的formatter。
然後將該handler新增到root。如果呼叫logging.basicconfig([**kwargs])的時候發現root logger已經有了handler,那該函式沒有任何操作。
三、關於root logger以及logger的父子關係
前面多次提到root logger, 實際上logger例項之間還有父子關係, root logger就是處於最頂層的logger, 它是所有logger的祖先。如下圖:
root logger是預設的logger,如果不建立logger例項, 直接呼叫logging.debug()、logging.info()logging.warning()、logging.error()、logging.critical()這些函式,那麼使用的logger就是 root logger, 它可以自動建立,也是單例項的。
如何得到root logger通過logging.getlogger()或者logging.getlogger("")得到root logger例項。
預設的level:root logger預設的level是logging.warning
如何表示父子關係logger的name的命名方式可以表示logger之間的父子關係. 比如:parent_logger = logging.getlogger('foo')child_logger = logging.getlogger('foo.bar')
什麼是effective levellogger有乙個概念,叫effective level。 如果乙個logger沒有顯示地設定level,那麼它就用父親的level。如果父親也沒有顯示地設定level, 就用父親的父親的level,以此推....最後到達root logger,一定設定過lev程式設計客棧el。預設為logging.warningchild loggers得到訊息後,既把訊息分發給它的handler處理,也會傳遞給所有祖先logger處理,
來看乙個例子
import logging
# 設定root logger
r = logging.getlogger()
ch = logging.streamhandler()
ch.setlevel(logging.debug)
formatter = logging.formatter('%(asctime)s - %(levelname)s - %(message)s')
ch.setformatter(formatter)
r.addhandler(ch)
# 建立乙個logger作為父親
p = logging.getlogger('foo'yvmator)
p.setlevel(logging.debug)
ch = logging.streamhandler()
ch.setlevel(logging.debug)
formatter = logging.formatter('%(asctime)s - %(message)s')
ch.setformatter(formatter)
p.addhandler(ch)
# 建立乙個孩子logger
c = logging.getlogger('foo.bar')
c.debug('foo')
輸出如下:
2011-08-31 21:04:29,893 - foo
2011-08-31 21:04:29,893 - debug - foo
可見, 孩子logger沒有任何handler,所以對訊息不做處理。但是它把訊息**給了它的父親以及root logger。最後輸出兩條日誌。
Python 日誌 logging 模組
對於小型專案而言,大家習慣於使用print語句列印資訊到終端進行除錯,然而,當專案 量擴大到了一定級別後,列印除錯的方法就顯得很凌亂了,更重要的是,當debug完成後,甄別並刪除 或注釋 除錯用的列印語句變得非常令人頭痛。而使用日誌模組則能很好地解決這些問題。日誌 logging 是在程式執行過程中...
python 日誌使用logging
將日誌列印入檔案,同時列印在控制台 logfile.py coding utf 8 import sys import logging from logging.handlers import timedrotatingfilehandler def getlogconfig name defaul...
Python日誌模組logging
logging分為4個模組 loggers,handlers,filters,and formatters.logger logger.setlevel 設定日誌級別 logger.addhandler 和logger.removehandler 增加和刪除日誌處理器 logger.addfilte...