Python logging日志模塊使用指南
Python logging 模塊定義了為應(yīng)用程序和庫(kù)實(shí)現(xiàn)靈活的事件日志記錄的函數(shù)和類。
程序開(kāi)發(fā)過(guò)程中,很多程序都有記錄日志的需求,并且日志包含的信息有正常的程序訪問(wèn)日志還可能有錯(cuò)誤、警告等信息輸出,Python 的 logging 模塊提供了標(biāo)準(zhǔn)的日志接口,可以通過(guò)它存儲(chǔ)各種格式的日志,日志記錄提供了一組便利功能,用于簡(jiǎn)單的日志記錄用法。
- 使用 Python Logging 模塊的主要好處是所有 Python 模塊都可以參與日志記錄
- Logging 模塊提供了大量具有靈活性的功能
日志記錄函數(shù)以它們用來(lái)跟蹤的事件的級(jí)別或嚴(yán)重性命名。下面描述了標(biāo)準(zhǔn)級(jí)別及其適用性(從高到低的順序):
日志等級(jí)(level) | 描述 |
---|---|
DEBUG | 最詳細(xì)的日志信息,典型應(yīng)用場(chǎng)景是 問(wèn)題診斷 |
INFO | 信息詳細(xì)程度僅次于DEBUG,通常只記錄關(guān)鍵節(jié)點(diǎn)信息,用于確認(rèn)一切都是按照我們預(yù)期的那樣進(jìn)行工作 |
WARNING | 當(dāng)某些不期望的事情發(fā)生時(shí)記錄的信息(如,磁盤可用空間較低),但是此時(shí)應(yīng)用程序還是正常運(yùn)行的 |
ERROR | 由于一個(gè)更嚴(yán)重的問(wèn)題導(dǎo)致某些功能不能正常運(yùn)行時(shí)記錄的信息 |
CRITICAL | 當(dāng)發(fā)生嚴(yán)重錯(cuò)誤,導(dǎo)致應(yīng)用程序不能繼續(xù)運(yùn)行時(shí)記錄的信息 |
日志級(jí)別等級(jí)排序:critical > error > warning > info > debug
級(jí)別越高打印的日志越少,反之亦然,即
- debug : 打印全部的日志( notset 等同于 debug )
- info : 打印 info, warning, error, critical 級(jí)別的日志
- warning : 打印 warning, error, critical 級(jí)別的日志
- error : 打印 error, critical 級(jí)別的日志
- critical : 打印 critical 級(jí)別
一、 Logging 模塊日志記錄方式
Logging 模塊提供了兩種日志記錄方式:
- 一種方式是使用 Logging 提供的模塊級(jí)別的函數(shù)
- 另一種方式是使用 Logging 日志系統(tǒng)的四大組件記錄
1、Logging 定義的模塊級(jí)別函數(shù)
函數(shù) | 說(shuō)明 |
---|---|
logging.debug(msg, *args, **kwargs) | 創(chuàng)建一條嚴(yán)重級(jí)別為DEBUG的日志記錄 |
logging.info(msg, *args, **kwargs) | 創(chuàng)建一條嚴(yán)重級(jí)別為INFO的日志記錄 |
logging.warning(msg, *args, **kwargs) | 創(chuàng)建一條嚴(yán)重級(jí)別為WARNING的日志記錄 |
logging.error(msg, *args, **kwargs) | 創(chuàng)建一條嚴(yán)重級(jí)別為ERROR的日志記錄 |
logging.critical(msg, *args, **kwargs) | 創(chuàng)建一條嚴(yán)重級(jí)別為CRITICAL的日志記錄 |
logging.log(level, *args, **kwargs) | 創(chuàng)建一條嚴(yán)重級(jí)別為level的日志記錄 |
logging.basicConfig(**kwargs) | 對(duì)root logger進(jìn)行一次性配置 |
簡(jiǎn)單打印日志:
import logging # 打印日志級(jí)別 def test_logging(): logging.debug('Python debug') logging.info('Python info') logging.warning('Python warning') logging.error('Python Error') logging.critical('Python critical') test_logging()
輸出結(jié)果:
WARNING:root:Python warning
ERROR:root:Python Error
CRITICAL:root:Python critical
當(dāng)指定一個(gè)日志級(jí)別之后,會(huì)記錄大于或等于這個(gè)日志級(jí)別的日志信息,小于的將會(huì)被丟棄, ==默認(rèn)情況下日志打印只顯示大于等于 WARNING 級(jí)別的日志。==
1.1 設(shè)置日志顯示級(jí)別
通過(guò) logging.basicConfig() 可以設(shè)置 root 的日志級(jí)別,和日志輸出格式。
logging.basicConfig() 關(guān)鍵字參數(shù):
關(guān)鍵字 | 描述 |
---|---|
filename | 創(chuàng)建一個(gè) FileHandler,使用指定的文件名,而不是使用 StreamHandler。 |
filemode | 如果指明了文件名,指明打開(kāi)文件的模式(如果沒(méi)有指明 filemode,默認(rèn)為 ‘a’)。 |
format | handler 使用指明的格式化字符串。 |
datefmt | handler 使用指明的格式化字符串。 |
level | 指明根 logger 的級(jí)別。 |
stream | 使用指明的流來(lái)初始化 StreamHandler。該參數(shù)與 ‘filename’ 不兼容,如果兩個(gè)都有,’stream’ 被忽略。 |
format 格式
格式 | 描述 |
---|---|
%(levelno)s | 打印日志級(jí)別的數(shù)值 |
%(levelname)s | 打印日志級(jí)別名稱 |
%(pathname)s | 打印當(dāng)前執(zhí)行程序的路徑 |
%(filename)s | 打印當(dāng)前執(zhí)行程序名稱 |
%(funcName)s | 打印日志的當(dāng)前函數(shù) |
%(lineno)d | 打印日志的當(dāng)前行號(hào) |
%(asctime)s | 打印日志的時(shí)間 |
%(thread)d | 打印線程 ID |
%(threadName)s | 打印線程名稱 |
%(process)d | 打印進(jìn)程 ID |
%(message)s | 打印日志信息 |
注意:Logging.basicConfig() 需要在開(kāi)頭就設(shè)置,在中間設(shè)置并無(wú)作用
實(shí)例
import logging # 打印日志級(jí)別 def test(): logging.basicConfig(level=logging.DEBUG) logging.debug('Python debug') logging.info('Python info') logging.warning('Python warning') logging.error('Python Error') logging.critical('Python critical') logging.log(2,'test') test()
輸出:
DEBUG:root:Python debug
INFO:root:Python info
WARNING:root:Python warning
ERROR:root:Python Error
CRITICAL:root:Python critical
1.2 將日志信息記錄到文件
# 日志信息記錄到文件 logging.basicConfig(filename='F:/example.log', level=logging.DEBUG) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too')
在相應(yīng)的路徑下會(huì)有 example.log 日志文件,內(nèi)容如下:
DEBUG:root:This message should go to the log file INFO:root:So should this WARNING:root:And this, too
1.3 多個(gè)模塊記錄日志信息
如果程序包含多個(gè)模塊,則用以下實(shí)例來(lái)顯示日志信息: 實(shí)例中有兩個(gè)模塊,一個(gè)模塊通過(guò)導(dǎo)入另一個(gè)模塊的方式用日志顯示另一個(gè)模塊的信息:
myapp.py 模塊
import logging import mylib def main(): logging.basicConfig(filename='myapp.log',level=logging.DEBUG) logging.info('Started') mylib.do_something() logging.info('Finished') if __name__ == '__main__': main()
mylib.py 模塊
import logging def do_something(): logging.info('Doing something')
執(zhí)行 myapp.py 模塊會(huì)打印相應(yīng)日志,在文件 myapp.log 中顯示信息如下:
INFO:root:Started INFO:root:Doing something INFO:root:Finishe
1.4 顯示信息的日期及更改顯示消息格式
顯示消息日期
import logging # 顯示消息時(shí)間 logging.basicConfig(format='%(asctime)s %(message)s') logging.warning('is when this event was logged.') logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') logging.warning('is when this event was logged.')
結(jié)果:
2019-10-16 18:57:45,988 is when this event was logged.
2019-10-16 18:57:45,988 is when this event was logged.
更改顯示消息格式
import logging # 更改顯示消息的格式 logging.basicConfig(format='%(levelname)s:%(message)s',level=logging.DEBUG) logging.debug('Python message format Debug') logging.info('Python message format Info') logging.warning('Python message format Warning')
結(jié)果:
DEBUG:Python message format Debug
INFO:Python message format Info
WARNING:Python message format Warning
==注意==:顯示結(jié)果只顯示級(jí)別和具體信息,之前顯示的 “根” 已經(jīng)消失,重新定義的格式修改了默認(rèn)輸出方式。
2、logging 模塊四大組件
組件名稱 | 對(duì)應(yīng)類名 | 功能描述 |
---|---|---|
日志器 | Logger | 暴露函數(shù)給應(yīng)用程序,基于日志記錄器和過(guò)濾器級(jí)別決定哪些日志有效 |
處理器 | Handler | 將 logger 創(chuàng)建的日志記錄發(fā)送到合適的目的輸出 |
過(guò)濾器 | Filter | 提供了更細(xì)粒度的控制工具來(lái)決定輸出哪條日志記錄,丟棄哪條日志記錄 |
格式器 | Formatter | 決定日志記錄的最終輸出格式 |
2.1 日志器- Logger
Logger 持有日志記錄器的方法,日志記錄器不直接實(shí)例化,而是通過(guò)模塊級(jí)函數(shù) logger.getlogger (name) 來(lái)實(shí)例化,使用相同的名稱多次調(diào)用 getLogger() 總是會(huì)返回對(duì)相同 Logger 對(duì)象的引用。
- 應(yīng)用程序代碼能直接調(diào)用日志接口。
- Logger最常用的操作有兩類:配置和發(fā)送日志消息。
- 初始化 logger = logging.getLogger(“endlesscode”),獲取 logger 對(duì)象,getLogger() 方法后面最好加上所要日志記錄的模塊名字,配置文件和打印日志格式中的 %(name)s 對(duì)應(yīng)的是這里的模塊名字,如果不指定name則返回root對(duì)象。
- logger.setLevel(logging.DEBUG),Logging 中有 NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL這幾種級(jí)別,日志會(huì)記錄設(shè)置級(jí)別以上的日志
- 多次使用相同的name調(diào)用 getLogger 方法返回同一個(gè) looger 對(duì)象;
Logger是一個(gè)樹(shù)形層級(jí)結(jié)構(gòu),在使用接口 debug,info,warn,error,critical 之前必須創(chuàng)建 Logger 實(shí)例:
創(chuàng)建方法: logger = logging.getLogger(logger_name)?
創(chuàng)建Logger實(shí)例后,可以使用以下方法進(jìn)行日志級(jí)別設(shè)置,增加處理器 Handler:
- logger.setLevel(logging.ERROR) # 設(shè)置日志級(jí)別為 ERROR,即只有日志級(jí)別大于等于 ERROR 的日志才會(huì)輸出
- logger.addHandler(handler_name) # 為 Logger 實(shí)例增加一個(gè)處理器
- logger.removeHandler(handler_name) # 為 Logger 實(shí)例刪除一個(gè)處理器
2.2 處理器- Handler
Handler 處理器類型有很多種,比較常用的有三個(gè),StreamHandler,F(xiàn)ileHandler,NullHandler
StreamHandler
創(chuàng)建方法:sh = logging.StreamHandler(stream=None)?
創(chuàng)建 StreamHandler 之后,可以通過(guò)使用以下方法設(shè)置日志級(jí)別,設(shè)置格式化器 Formatter,增加或刪除過(guò)濾器 Filter:
ch.setLevel(logging.WARN) # 指定日志級(jí)別,低于WARN級(jí)別的日志將被忽略 ch.setFormatter(formatter_name) # 設(shè)置一個(gè)格式化器formatter ch.addFilter(filter_name) # 增加一個(gè)過(guò)濾器,可以增加多個(gè) ch.removeFilter(filter_name) # 刪除一個(gè)過(guò)濾器
2.3 過(guò)濾器- Filter
Handlers 和 Loggers 可以使用 Filters 來(lái)完成比級(jí)別更復(fù)雜的過(guò)濾。 Filter 基類只允許特定 Logger 層次以下的事件。 例如用 ‘A.B’ 初始化的 Filter 允許Logger ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’ 等記錄的事件,logger‘A.BB’, ‘B.A.B’ 等就不行。 如果用空字符串來(lái)初始化,所有的事件都接受。
創(chuàng)建方法: filter = logging.Filter(name='')
2.4 格式器- Formatter
使用Formatter對(duì)象設(shè)置日志信息最后的規(guī)則、結(jié)構(gòu)和內(nèi)容,默認(rèn)的時(shí)間格式為%Y-%m-%d %H:%M:%S。
創(chuàng)建方法: formatter = logging.Formatter(fmt=None, datefmt=None)
其中,fmt 是消息的格式化字符串,datefmt 是日期字符串。如果不指明 fmt,將使用 ‘%(message)s’ 。如果不指明 datefmt,將使用 ISO8601 日期格式。
2.5 組件之間的關(guān)聯(lián)關(guān)系
- 日志器(logger)需要通過(guò)處理器(handler)將日志信息輸出到目標(biāo)位置,不同的處理器(handler)可以將日志輸出到不同的位置;
- 日志器(logger)可以設(shè)置多個(gè)處理器(handler)將同一條日志記錄輸出到不同的位置;
- 每個(gè)處理器(handler)都可以設(shè)置自己的過(guò)濾器(filter)實(shí)現(xiàn)日志過(guò)濾,從而只保留感興趣的日志;
- 每個(gè)處理器(handler)都可以設(shè)置自己的格式器(formatter)實(shí)現(xiàn)同一條日志以不同的格式輸出到不同的地方。
簡(jiǎn)明了說(shuō)就是:日志器(logger)是入口,真正干活兒的是處理器(handler),處理器(handler)還可以通過(guò)過(guò)濾器(filter)和格式器(formatter)對(duì)要輸出的日志內(nèi)容做過(guò)濾和格式化等處理操作。
- Logger 可以包含一個(gè)或多個(gè) Handler 和 Filter
- Logger 與 Handler 或 Fitler 是一對(duì)多的關(guān)系
- 一個(gè) Logger 實(shí)例可以新增多 個(gè) Handler,一個(gè) Handler 可以新增多個(gè)格式化器或多個(gè)過(guò)濾器,而且日志級(jí)別將會(huì)繼承。
二、Logging 日志工作流程
1、Logging 模塊使用過(guò)程
1)第一次導(dǎo)入 logging 模塊或使用 reload 函數(shù)重新導(dǎo)入 logging 模塊,logging 模塊中的代碼將被執(zhí)行,這個(gè)過(guò)程中將產(chǎn)生 logging 日志系統(tǒng)的默認(rèn)配置。
2)自定義配置(可選),logging標(biāo)準(zhǔn)模塊支持三種配置方式: dictConfig,fileConfig,listen。其中,dictConfig 是通過(guò)一個(gè)字典進(jìn)行配置 Logger,Handler,F(xiàn)ilter,F(xiàn)ormatter;fileConfig 則是通過(guò)一個(gè)文件進(jìn)行配置;而 listen 則監(jiān)聽(tīng)一個(gè)網(wǎng)絡(luò)端口,通過(guò)接收網(wǎng)絡(luò)數(shù)據(jù)來(lái)進(jìn)行配置。當(dāng)然,除了以上集體化配置外,也可以直接調(diào)用 Logger,Handler 等對(duì)象中的方法在代碼中來(lái)顯式配置。
3)使用 logging 模塊的全局作用域中的 getLogger 函數(shù)來(lái)得到一個(gè) Logger 對(duì)象實(shí)例(其參數(shù)即是一個(gè)字符串,表示 Logger 對(duì)象實(shí)例的名字,即通過(guò)該名字來(lái)得到相應(yīng)的 Logger 對(duì)象實(shí)例)。4)使用 Logger 對(duì)象中的 debug,info,error,warn,critical 等方法記錄日志信息。
2、Logging 模塊處理流程
流程描述:
- 判斷日志的等級(jí)是否大于 Logger 對(duì)象的等級(jí),如果大于,則往下執(zhí)行,否則,流程結(jié)束。
- 產(chǎn)生日志:第一步,判斷是否有異常,如果有,則添加異常信息。 第二步,處理日志記錄方法(如 debug,info 等)中的占位符,即一般的字符串格式化處理。
- 使用注冊(cè)到 Logger 對(duì)象中的 Filters 進(jìn)行過(guò)濾。如果有多個(gè)過(guò)濾器,則依次過(guò)濾;只要有一個(gè)過(guò)濾器返回假,則過(guò)濾結(jié)束,且該日志信息將丟棄,不再處理,而處理流程也至此結(jié)束。否則,處理流程往下執(zhí)行。
- 在當(dāng)前 Logger 對(duì)象中查找 Handlers,如果找不到任何 Handler,則往上到該 Logger 對(duì)象的父 Logger 中查找;如果找到一個(gè)或多個(gè) Handler,則依次用 Handler 來(lái)處理日志信息。但在每個(gè) Handler 處理日志信息過(guò)程中,會(huì)首先判斷日志信息的等級(jí)是否大于該 Handler 的等級(jí),如果大于,則往下執(zhí)行(由 Logger 對(duì)象進(jìn)入 Handler 對(duì)象中),否則,處理流程結(jié)束。
- 執(zhí)行 Handler 對(duì)象中的 filter 方法,該方法會(huì)依次執(zhí)行注冊(cè)到該 Handler 對(duì)象中的 Filter。如果有一個(gè) Filter 判斷該日志信息為假,則此后的所有 Filter 都不再執(zhí)行,而直接將該日志信息丟棄,處理流程結(jié)束。
- 使用 Formatter 類格式化最終的輸出結(jié)果。 注:Formatter 同上述第 2 步的字符串格式化不同,它會(huì)添加額外的信息,比如日志產(chǎn)生的時(shí)間,產(chǎn)生日志的源代碼所在的源文件的路徑等等。
- 真正地輸出日志信息(到網(wǎng)絡(luò),文件,終端,郵件等)。至于輸出到哪個(gè)目的地,由 Handler 的種類來(lái)決定。
三、配置日志
程序員可以通過(guò)三種方式配置日志記錄:
1、使用配置方法的 Python 代碼顯式創(chuàng)建記錄器,處理程序和格式化程序。
2、創(chuàng)建日志記錄配置文件并使用該 fileConfig() 功能讀取它。
3、創(chuàng)建配置信息字典并將其傳遞給 dictConfig()函數(shù)。
下面使用 Python 代碼配置一個(gè)非常簡(jiǎn)單的記錄器,一個(gè)控制臺(tái)處理程序和一個(gè)簡(jiǎn)單的格式化程序:
logging.conf 配置文件:
[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=
config_logging.py 配置器:
import logging # create logger logger = logging.getLogger('simple_example') logger.setLevel(logging.DEBUG) # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # add formatter to ch ch.setFormatter(formatter) # add ch to logger logger.addHandler(ch) # 'application' code logger.debug('debug message') logger.info('info message') logger.warning('warn message') logger.error('error message') logger.critical('critical message')
recorder 記錄器:
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.warning('warn message') logger.error('error message') logger.critical('critical message')
運(yùn)行結(jié)果:
2019-10-16 19:45:34,440 - simple_example - DEBUG - debug message
2019-10-16 19:45:34,440 - simple_example - INFO - info message
2019-10-16 19:45:34,440 - simple_example - WARNING - warn message
2019-10-16 19:45:34,440 - simple_example - ERROR - error message
2019-10-16 19:45:34,441 - simple_example - CRITICAL - critical message
總結(jié)
本章節(jié)給大家介紹了 Python 標(biāo)準(zhǔn)庫(kù)中 Logging 模塊的詳細(xì)介紹與使用,對(duì) Python 工程師使用該模塊提供更好的支撐
以上就是Python logging日志模塊使用指南的詳細(xì)內(nèi)容,更多關(guān)于Python logging模塊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Pytorch中的自動(dòng)求梯度機(jī)制和Variable類實(shí)例
今天小編就為大家分享一篇Pytorch中的自動(dòng)求梯度機(jī)制和Variable類實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02思考分析Python運(yùn)算中?a+=b?和?a=a+b是否相等
這篇文章主要為大家介紹了Python運(yùn)算中a+=b和a=a+b是否相等及原理思考分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Python+selenium實(shí)現(xiàn)截圖圖片并保存截取的圖片
這篇文章介紹如何利用Selenium的方法進(jìn)行截圖并保存截取的圖片,需要的朋友參考下本文2018-01-01利用Python實(shí)時(shí)獲取steam特惠游戲數(shù)據(jù)
Steam是由美國(guó)電子游戲商Valve于2003年9月12日推出的數(shù)字發(fā)行平臺(tái),被認(rèn)為是計(jì)算機(jī)游戲界最大的數(shù)碼發(fā)行平臺(tái)之一。本文將利用Python實(shí)時(shí)獲取steam特惠游戲數(shù)據(jù),感興趣的可以嘗試一下2022-06-06基于Python pip用國(guó)內(nèi)鏡像下載的方法
今天小編就為大家分享一篇基于Python pip用國(guó)內(nèi)鏡像下載的方法。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06python實(shí)現(xiàn)百度文庫(kù)自動(dòng)化爬取
項(xiàng)目是合法項(xiàng)目,只是進(jìn)行數(shù)據(jù)解析而已,不能下載看不到的內(nèi)容.部分文檔在電腦端不能預(yù)覽,但是在手機(jī)端可以預(yù)覽,所有本項(xiàng)目把瀏覽器瀏覽格式改成手機(jī)端,支持Windows和Ubuntu. 本項(xiàng)目使用的是chromedriver來(lái)控制chrome來(lái)模擬人來(lái)操作來(lái)進(jìn)行文檔爬取2021-04-04python末尾逗號(hào)導(dǎo)致返回結(jié)果是一個(gè)元組的問(wèn)題
在Python中,除非特別需要返回或傳參元組,一般不推薦在語(yǔ)句末尾添加逗號(hào),應(yīng)該注意檢查是否存在末尾逗號(hào)導(dǎo)致的這些副作用,這篇文章主要介紹了python末尾逗號(hào)導(dǎo)致返回結(jié)果是一個(gè)元組,需要的朋友可以參考下2023-09-09Python reversed反轉(zhuǎn)序列并生成可迭代對(duì)象
這篇文章主要介紹了Python reversed反轉(zhuǎn)序列并生成可迭代對(duì)象,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10