使用python的logging模組

2021-08-26 04:12:00 字數 4185 閱讀 6192

一、從乙個使用場景開始

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

import logging

# 建立乙個logger

logger = logging.getlogger('mylogger')

logger.setlevel(logging.debug)

# 建立乙個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.addhandler(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 logger建立乙個streamhandler,

設定預設的格式。

* 這些函式: logging.debug()、logging.info()、logging.warning()、

logging.error()、logging.critical() 

如果呼叫的時候發現root logger沒有任何

handler, 會自動呼叫basicconfig新增乙個handler

* 如果root logger已有handler, 這個函式不做任何事情

使用basicconfig來配置root logger的輸出格式和level:

import logging

logging.basicconfig(format='%(levelname)s:%(message)s', level=logging.debug)

三、關於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例項。

預設的levelroot 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,一定設定過level。預設為logging.warning

child 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')

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

許多應用程式中都會有日誌模組,用於記錄系統在執行過程中的一些關鍵資訊,以便於對系統的執行狀況進行跟蹤。在.net平台中,有非常著名的第三方開源日誌元件log4net,c 中,有人們熟悉的log4cpp,而在python中,我們不需要第三方的日誌元件,因為它已經為我們提供了簡單易用 且功能強大的日誌模...

記憶碎片之scrapy中使用logging模快

settings.py log level warning 設定日誌顯示的等級 log file a.log 設定日誌儲存的位置,設定後介面不會顯示日誌內容 spider.py import logging import logging logging.basicconfig函式各引數 filena...

python元類的使用 python使用元類

原文 type 動態語言和靜態語言最大的不同,就是函式和類的定義,不是編譯時定義的,而是執行時動態建立的。比方說我們要定義乙個hello的class,就寫乙個hello.py模組 當python直譯器載入hello模組時,就會依次執行該模組的所有語句,執行結果就是動態建立出乙個hello的class...