python logging模組使用教程

來源:互聯網
上載者:User

標籤:lib   com   目的   ofo   cursor   table   gem   arc   ble   

 簡單使用
#!/usr/local/bin/python# -*- coding:utf-8 -*-import logginglogging.debug(‘debug message‘)logging.info(‘info message‘)logging.warn(‘warn message‘)logging.error(‘error message‘)logging.critical(‘critical message‘) 

輸出:

WARNING:root:warn message
ERROR:root:error message
CRITICAL:root:critical message

預設情況下,logging模組將日誌列印到螢幕上(stdout),記錄層級為WARNING(即只有記錄層級高於WARNING的日誌資訊才會輸出),日誌格式如所示:

default_logging_format.png

問題來了

  1. 記錄層級等級及設定是怎樣的?
  2. 怎樣設定日誌的輸出方式?比如輸出到記錄檔中?
簡單配置記錄層級
層級 何時使用
DEBUG 詳細資料,典型地調試問題時會感興趣。
INFO 證明事情按預期工作。
WARNING 表明發生了一些意外,或者不久的將來會發生問題(如‘磁碟滿了’)。軟體還是在正常工作。
ERROR 由於更嚴重的問題,軟體已不能執行一些功能了。
CRITICAL 嚴重錯誤,表明軟體已不能繼續運行了。
簡單配置
#!/usr/local/bin/python# -*- coding:utf-8 -*-import logging# 通過下面的方式進行簡單配置輸出方式與記錄層級logging.basicConfig(filename=‘logger.log‘, level=logging.INFO)logging.debug(‘debug message‘)logging.info(‘info message‘)logging.warn(‘warn message‘)logging.error(‘error message‘)logging.critical(‘critical message‘)

輸出:
標準輸出(螢幕)未顯示任何資訊,發現當前工作目錄下產生了logger.log,內容如下:

INFO:root:info message
WARNING:root:warn message
ERROR:root:error message
CRITICAL:root:critical message

因為通過level=logging.INFO設定記錄層級為INFO,所以所有的日誌資訊均輸出出來了。

問題又來了

  1. 通過上述配置方法都可以配置那些資訊?

在解決以上問題之前,需要先瞭解幾個比較重要的概念,LoggerHandlerFormatterFilter

幾個重要的概念
  • Logger 記錄器,暴露了應用程式代碼能直接使用的介面。
  • Handler 處理器,將(記錄器產生的)日誌記錄發送至合適的目的地。
  • Filter 過濾器,提供了更好的粒度控制,它可以決定輸出哪些日誌記錄。
  • Formatter 格式化器,指明了最終輸出中日誌記錄的布局。
Logger 記錄器

Logger是一個樹形層級結構,在使用介面debug,info,warn,error,critical之前必須建立Logger執行個體,即建立一個記錄器,如果沒有顯式的進行建立,則預設建立一個root logger,並應用預設的記錄層級(WARN),處理器Handler(StreamHandler,即將日誌資訊列印輸出在標準輸出上),和格式化器Formatter(預設的格式即為第一個簡單使用程式中輸出的格式)。

建立方法: logger = logging.getLogger(logger_name)

建立Logger執行個體後,可以使用以下方法進行記錄層級設定,增加處理器Handler。

  • logger.setLevel(logging.ERROR) # 設定記錄層級為ERROR,即只有記錄層級大於等於ERROR的日誌才會輸出
  • logger.addHandler(handler_name) # 為Logger執行個體增加一個處理器
  • logger.removeHandler(handler_name) # 為Logger執行個體刪除一個處理器
Handler 處理器

Handler處理器類型有很多種,比較常用的有三個,StreamHandlerFileHandlerNullHandler,詳情可以訪問Python logging.handlers

建立StreamHandler之後,可以通過使用以下方法設定記錄層級,設定格式化器Formatter,增加或刪除過濾器Filter。

  • ch.setLevel(logging.WARN) # 指定記錄層級,低於WARN層級的日誌將被忽略
  • ch.setFormatter(formatter_name) # 設定一個格式化器formatter
  • ch.addFilter(filter_name) # 增加一個過濾器,可以增加多個
  • ch.removeFilter(filter_name) # 刪除一個過濾器
StreamHandler

建立方法: sh = logging.StreamHandler(stream=None)

FileHandler

建立方法: fh = logging.FileHandler(filename, mode=‘a‘, encoding=None, delay=False)

NullHandler

NullHandler類位於核心logging包,不做任何的格式化或者輸出。
本質上它是個“什麼都不做”的handler,由庫開發人員使用。

Formatter 格式化器

使用Formatter對象設定日誌資訊最後的規則、結構和內容,預設的時間格式為%Y-%m-%d %H:%M:%S。

建立方法: formatter = logging.Formatter(fmt=None, datefmt=None)

其中,fmt是訊息的格式化字串,datefmt是日期文字。如果不指明fmt,將使用‘%(message)s‘。如果不指明datefmt,將使用ISO8601日期格式。

Filter 過濾器

Handlers和Loggers可以使用Filters來完成比層級更複雜的過濾。Filter基類只允許特定Logger層次以下的事件。例如用‘A.B’初始化的Filter允許Logger ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’等記錄的事件,logger‘A.BB’, ‘B.A.B’ 等就不行。 如果用Null 字元串來初始化,所有的事件都接受。

建立方法: filter = logging.Filter(name=‘‘)

以下是相關概念總結:

熟悉了這些概念之後,有另外一個比較重要的事情必須清楚,即Logger是一個樹形層級結構;
Logger可以包含一個或多個Handler和Filter,即Logger與Handler或Fitler是一對多的關係;
一個Logger執行個體可以新增多個Handler,一個Handler可以新增多個格式化器或多個過濾器,而且記錄層級將會繼承。

element_relation.jpgLogging工作流程logging模組使用過程
  1. 第一次匯入logging模組或使用reload函數重新匯入logging模組,logging模組中的代碼將被執行,這個過程中將產生logging日誌系統的預設配置。
  2. 自訂配置(可選)。logging標準模組支援三種配置方式: dictConfig,fileConfig,listen。其中,dictConfig是通過一個字典進行配置Logger,Handler,Filter,Formatter;fileConfig則是通過一個檔案進行配置;而listen則監聽一個網路連接埠,通過接收網路資料來進行配置。當然,除了以上集體化配置外,也可以直接調用Logger,Handler等對象中的方法在代碼中來顯式配置。
  3. 使用logging模組的全域範圍中的getLogger函數來得到一個Logger對象執行個體(其參數即是一個字串,表示Logger對象執行個體的名字,即通過該名字來得到相應的Logger對象執行個體)。
  4. 使用Logger對象中的debug,info,error,warn,critical等方法記錄日誌資訊。
logging模組處理流程logging_flow.png
  1. 判斷日誌的等級是否大於Logger對象的等級,如果大於,則往下執行,否則,流程結束。
  2. 產生日誌。第一步,判斷是否有異常,如果有,則添加異常資訊。第二步,處理日誌記錄方法(如debug,info等)中的預留位置,即一般的字串格式化處理。
  3. 使用註冊到Logger對象中的Filters進行過濾。如果有多個過濾器,則依次過濾;只要有一個過濾器返回假,則過濾結束,且該日誌資訊將丟棄,不再處理,而處理流程也至此結束。否則,處理流程往下執行。
  4. 在當前Logger對象中尋找Handlers,如果找不到任何Handler,則往上到該Logger對象的父Logger中尋找;如果找到一個或多個Handler,則依次用Handler來處理日誌資訊。但在每個Handler處理日誌資訊過程中,會首先判斷日誌資訊的等級是否大於該Handler的等級,如果大於,則往下執行(由Logger對象進入Handler對象中),否則,處理流程結束。
  5. 執行Handler對象中的filter方法,該方法會依次執行註冊到該Handler對象中的Filter。如果有一個Filter判斷該日誌資訊為假,則此後的所有Filter都不再執行,而直接將該日誌資訊丟棄,處理流程結束。
  6. 使用Formatter類格式化最終的輸出結果。 註:Formatter同上述第2步的字串格式化不同,它會添加額外的資訊,比如日誌產生的時間,產生日誌的原始碼所在的源檔案的路徑等等。
  7. 真正地輸出日誌資訊(到網路,檔案,終端,郵件等)。至於輸出到哪個目的地,由Handler的種類來決定。

註:以上內容摘抄自第三條參考資料,內容略有改動,轉載特此聲明。

再看日誌配置配置方式
  • 顯式建立記錄器Logger、處理器Handler和格式化器Formatter,並進行相關設定;
  • 通過簡單方式進行配置,使用basicConfig()函數直接進行配置;
  • 通過設定檔進行配置,使用fileConfig()函數讀取設定檔;
  • 通過配置字典進行配置,使用dictConfig()函數讀取配置資訊;
  • 通過網路進行配置,使用listen()函數進行網路設定。
basicConfig關鍵字參數
關鍵字 描述
filename 建立一個FileHandler,使用指定的檔案名稱,而不是使用StreamHandler。
filemode 如果指明了檔案名稱,指明開啟檔案的模式(如果沒有指明filemode,預設為‘a‘)。
format handler使用指明的格式化字串。
datefmt 使用指明的日期/時間格式。
level 指明根logger的層級。
stream 使用指明的流來初始化StreamHandler。該參數與‘filename‘不相容,如果兩個都有,‘stream‘被忽略。
有用的format格式
格式 描述
%(levelno)s 列印記錄層級的數值
%(levelname)s 列印記錄層級名稱
%(pathname)s 列印當前執行程式的路徑
%(filename)s 列印當前執行程式名稱
%(funcName)s 列印日誌的當前函數
%(lineno)d 列印日誌的當前行號
%(asctime)s 列印日誌的時間
%(thread)d 列印線程id
%(threadName)s 列印線程名稱
%(process)d 列印進程ID
%(message)s 列印日誌資訊
有用的datefmt格式

參考time.strftime

配置樣本顯式配置

使用程式logger.py如下:

# -*- encoding:utf-8 -*-import logging# create loggerlogger_name = "example"logger = logging.getLogger(logger_name)logger.setLevel(logging.DEBUG)# create file handlerlog_path = "./log.log"fh = logging.FileHandler(log_path)fh.setLevel(logging.WARN)# create formatterfmt = "%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s"datefmt = "%a %d %b %Y %H:%M:%S"formatter = logging.Formatter(fmt, datefmt)# add handler and formatter to loggerfh.setFormatter(formatter)logger.addHandler(fh)# print log infologger.debug(‘debug message‘)logger.info(‘info message‘)logger.warn(‘warn message‘)logger.error(‘error message‘)logger.critical(‘critical message‘)```##### 檔案配置設定檔logging.conf如下:```[loggers]keys=root,example01[logger_root]level=DEBUGhandlers=hand01,hand02[logger_example01]handlers=hand01,hand02qualname=example01propagate=0[handlers]keys=hand01,hand02[handler_hand01]class=StreamHandlerlevel=INFOformatter=form02args=(sys.stderr,)[handler_hand02]class=FileHandlerlevel=DEBUGformatter=form01args=(‘log.log‘, ‘a‘)[formatters]keys=form01,form02[formatter_form01]format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s```使用程式logger.py如下:```#!/usr/bin/python# -*- encoding:utf-8 -*-import loggingimport logging.configlogging.config.fileConfig("./logging.conf")# create loggerlogger_name = "example"logger = logging.getLogger(logger_name)logger.debug(‘debug message‘)logger.info(‘info message‘)logger.warn(‘warn message‘)logger.error(‘error message‘)logger.critical(‘critical message‘)```##### 字典配置有興趣的童靴可以使用```logging.config.dictConfig(config)```編寫一個樣本程式發給我,以提供給我進行完善本文。##### 監聽配置有興趣的童靴可以使用```logging.config.listen(port=DEFAULT_LOGGING_CONFIG_PORT)```編寫一個樣本程式發給我,以提供給我進行完善本文。更多詳細內容參考[logging.config日誌配置](http://python.usyiyi.cn/python_278/library/logging.config.html#module-logging.config)### 參考資料* [英文Python logging HOWTO](https://docs.python.org/2/howto/logging.html#logging-basic-tutorial)* [中文Python 日誌 HOWTO](http://python.usyiyi.cn/python_278/howto/logging.html#logging-basic-tutorial)* [Python日誌系統Logging](http://www.52ij.com/jishu/666.html)* [logging模組學習筆記:basicConfig設定檔](http://www.cnblogs.com/bjdxy/archive/2013/04/12/3016820.html)* 其他一些前輩部落格相關文章

python logging模組使用教程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.