python日誌logging模組使用方法分析

2022-10-04 17:30:12 字數 3459 閱讀 6547

一、從乙個使用場景開始

開發乙個日誌系統, 既要把日誌輸出到控制台, 還要寫入日誌檔案

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...