Python logging 模塊詳解

2021-02-19 吾非同

Python logging 模塊定義了為應用程式和庫實現靈活的事件日誌記錄的函數和類。

程序開發過程中,很多程序都有記錄日誌的需求,並且日誌包含的信息有正常的程序訪問日誌還可能有錯誤、警告等信息輸出,Python 的 logging 模塊提供了標準的日誌接口,可以通過它存儲各種格式的日誌,日誌記錄提供了一組便利功能,用於簡單的日誌記錄用法。

日誌記錄函數以它們用來跟蹤的事件的級別或嚴重性命名。下面描述了標準級別及其適用性(從高到低的順序):

日誌等級(level)描述DEBUG最詳細的日誌信息,典型應用場景是 問題診斷INFO信息詳細程度僅次於DEBUG,通常只記錄關鍵節點信息,用於確認一切都是按照我們預期的那樣進行工作WARNING當某些不期望的事情發生時記錄的信息(如,磁碟可用空間較低),但是此時應用程式還是正常運行的ERROR由於一個更嚴重的問題導致某些功能不能正常運行時記錄的信息CRITICAL當發生嚴重錯誤,導致應用程式不能繼續運行時記錄的信息

日誌級別等級排序:critical > error > warning > info > debug

級別越高列印的日誌越少,反之亦然,即

debug    : 列印全部的日誌( notset 等同於 debug )

info     : 列印 info, warning, error, critical 級別的日誌

warning  : 列印 warning, error, critical 級別的日誌

error    : 列印 error, critical 級別的日誌

critical : 列印 critical 級別

一、 Logging 模塊日誌記錄方式

Logging 模塊提供了兩種日誌記錄方式:

1、Logging 定義的模塊級別函數函數說明logging.debug(msg, *args, **kwargs)創建一條嚴重級別為DEBUG的日誌記錄logging.info(msg, *args, **kwargs)創建一條嚴重級別為INFO的日誌記錄logging.warning(msg, *args, **kwargs)創建一條嚴重級別為WARNING的日誌記錄logging.error(msg, *args, **kwargs)創建一條嚴重級別為ERROR的日誌記錄logging.critical(msg, *args, **kwargs)創建一條嚴重級別為CRITICAL的日誌記錄logging.log(level, *args, **kwargs)創建一條嚴重級別為level的日誌記錄logging.basicConfig(**kwargs)對root logger進行一次性配置

簡單列印日誌:

import logging
# 列印日誌級別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()

輸出結果:

WARNING:root:Python warningERROR:root:Python ErrorCRITICAL:root:Python critical

當指定一個日誌級別之後,會記錄大於或等於這個日誌級別的日誌信息,小於的將會被丟棄,==默認情況下日誌列印只顯示大於等於 WARNING 級別的日誌。==

1.1 設置日誌顯示級別

通過 logging.basicConfig() 可以設置 root 的日誌級別,和日誌輸出格式。

logging.basicConfig() 關鍵字參數

關鍵字描述filename創建一個 FileHandler,使用指定的文件名,而不是使用 StreamHandler。filemode如果指明了文件名,指明打開文件的模式(如果沒有指明 filemode,默認為 'a')。formathandler 使用指明的格式化字符串。datefmthandler 使用指明的格式化字符串。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列印日誌信息

注意:Logging.basicConfig() 需要在開頭就設置,在中間設置並無作用

實例

import logging
# 列印日誌級別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 debugINFO:root:Python infoWARNING:root:Python warningERROR:root:Python ErrorCRITICAL: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')

在相應的路徑下會有 example.log 日誌文件,內容如下:

DEBUG:root:This message should go to the log fileINFO:root:So should thisWARNING:root:And this, too

1.3 多個模塊記錄日誌信息

如果程序包含多個模塊,則用以下實例來顯示日誌信息:實例中有兩個模塊,一個模塊通過導入另一個模塊的方式用日誌顯示另一個模塊的信息:

myapp.py 模塊

import loggingimport mylibdef 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')

執行 myapp.py 模塊會列印相應日誌,在文件 myapp.log 中顯示信息如下:

INFO:root:StartedINFO:root:Doing somethingINFO:root:Finishe

1.4 顯示信息的日期及更改顯示消息格式

顯示消息日期

import logging# 顯示消息時間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.')

結果:

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

結果:

DEBUG:Python message format DebugINFO:Python message format InfoWARNING:Python message format Warning

==注意==:顯示結果只顯示級別和具體信息,之前顯示的 「根」 已經消失,重新定義的格式修改了默認輸出方式。

2、logging 模塊四大組件組件名稱對應類名功能描述日誌器Logger暴露函數給應用程式,基於日誌記錄器和過濾器級別決定哪些日誌有效處理器Handler將 logger 創建的日誌記錄發送到合適的目的輸出過濾器Filter提供了更細粒度的控制工具來決定輸出哪條日誌記錄,丟棄哪條日誌記錄格式器Formatter決定日誌記錄的最終輸出格式2.1 日誌器- Logger

Logger 持有日誌記錄器的方法,日誌記錄器不直接實例化,而是通過模塊級函數 logger.getlogger (name) 來實例化,使用相同的名稱多次調用 getLogger() 總是會返回對相同 Logger 對象的引用。

應用程式代碼能直接調用日誌接口。

Logger最常用的操作有兩類:配置和發送日誌消息。

初始化 logger = logging.getLogger("endlesscode"),獲取 logger 對象,getLogger() 方法後面最好加上所要日誌記錄的模塊名字,配置文件和列印日誌格式中的 %(name)s 對應的是這裡的模塊名字,如果不指定name則返回root對象。

logger.setLevel(logging.DEBUG),Logging 中有 NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL這幾種級別,日誌會記錄設置級別以上的日誌

多次使用相同的name調用 getLogger 方法返回同一個 looger 對象;

Logger是一個樹形層級結構,在使用接口 debug,info,warn,error,critical 之前必須創建 Logger 實例:

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

創建Logger實例後,可以使用以下方法進行日誌級別設置,增加處理器 Handler:

logger.setLevel(logging.ERROR) # 設置日誌級別為 ERROR,即只有日誌級別大於等於 ERROR 的日誌才會輸出

logger.addHandler(handler_name) # 為 Logger 實例增加一個處理器

logger.removeHandler(handler_name) # 為 Logger 實例刪除一個處理器

2.2 處理器- Handler

Handler 處理器類型有很多種,比較常用的有三個,StreamHandler,FileHandler,NullHandler

StreamHandler

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

創建 StreamHandler 之後,可以通過使用以下方法設置日誌級別,設置格式化器 Formatter,增加或刪除過濾器 Filter:

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

2.3 過濾器- 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』 等就不行。如果用空字符串來初始化,所有的事件都接受。

創建方法: filter = logging.Filter(name='')

2.4 格式器- Formatter

使用Formatter對象設置日誌信息最後的規則、結構和內容,默認的時間格式為%Y-%m-%d %H:%M:%S。

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

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

2.5 組件之間的關聯關係

日誌器(logger)需要通過處理器(handler)將日誌信息輸出到目標位置,不同的處理器(handler)可以將日誌輸出到不同的位置;

日誌器(logger)可以設置多個處理器(handler)將同一條日誌記錄輸出到不同的位置;

每個處理器(handler)都可以設置自己的過濾器(filter)實現日誌過濾,從而只保留感興趣的日誌;

每個處理器(handler)都可以設置自己的格式器(formatter)實現同一條日誌以不同的格式輸出到不同的地方。

簡明了說就是:日誌器(logger)是入口,真正幹活兒的是處理器(handler),處理器(handler)還可以通過過濾器(filter)和格式器(formatter)對要輸出的日誌內容做過濾和格式化等處理操作。

Logger 可以包含一個或多個 Handler 和 Filter

Logger 與 Handler 或 Fitler 是一對多的關係

一個 Logger 實例可以新增多 個 Handler,一個 Handler 可以新增多個格式化器或多個過濾器,而且日誌級別將會繼承。

二、Logging 日誌工作流程1、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 等方法記錄日誌信息。

2、Logging 模塊處理流程                                            logging 處理流程

流程描述:

判斷日誌的等級是否大於 Logger 對象的等級,如果大於,則往下執行,否則,流程結束。

產生日誌:第一步,判斷是否有異常,如果有,則添加異常信息。第二步,處理日誌記錄方法(如 debug,info 等)中的佔位符,即一般的字符串格式化處理。

使用註冊到 Logger 對象中的 Filters 進行過濾。如果有多個過濾器,則依次過濾;只要有一個過濾器返回假,則過濾結束,且該日誌信息將丟棄,不再處理,而處理流程也至此結束。否則,處理流程往下執行。

在當前 Logger 對象中查找 Handlers,如果找不到任何 Handler,則往上到該 Logger 對象的父 Logger 中查找;如果找到一個或多個 Handler,則依次用 Handler 來處理日誌信息。但在每個 Handler 處理日誌信息過程中,會首先判斷日誌信息的等級是否大於該 Handler 的等級,如果大於,則往下執行(由 Logger 對象進入 Handler 對象中),否則,處理流程結束。

執行 Handler 對象中的 filter 方法,該方法會依次執行註冊到該 Handler 對象中的 Filter。如果有一個 Filter 判斷該日誌信息為假,則此後的所有 Filter 都不再執行,而直接將該日誌信息丟棄,處理流程結束。

使用 Formatter 類格式化最終的輸出結果。註:Formatter 同上述第 2 步的字符串格式化不同,它會添加額外的信息,比如日誌產生的時間,產生日誌的原始碼所在的源文件的路徑等等。

真正地輸出日誌信息(到網絡,文件,終端,郵件等)。至於輸出到哪個目的地,由 Handler 的種類來決定。

三、配置日誌

程式設計師可以通過三種方式配置日誌記錄:

1、使用配置方法的 Python 代碼顯式創建記錄器,處理程序和格式化程序。

2、創建日誌記錄配置文件並使用該 fileConfig() 功能讀取它。

3、創建配置信息字典並將其傳遞給 dictConfig()函數。

下面使用 Python 代碼配置一個非常簡單的記錄器,一個控制臺處理程序和一個簡單的格式化程序:

logging.conf 配置文件

[loggers]keys=root,simpleExample
[handlers]keys=consoleHandler
[formatters]keys=simpleFormatter
[logger_root]level=DEBUGhandlers=consoleHandler
[logger_simpleExample]level=DEBUGhandlers=consoleHandlerqualname=simpleExamplepropagate=0
[handler_consoleHandler]class=StreamHandlerlevel=DEBUGformatter=simpleFormatterargs=(sys.stdout,)
[formatter_simpleFormatter]format=%(asctime)s - %(name)s - %(levelname)s - %(message)sdatefmt=

config_logging.py 配置器

import logging# create loggerlogger = logging.getLogger('simple_example')logger.setLevel(logging.DEBUG)
# create console handler and set level to debugch = logging.StreamHandler()ch.setLevel(logging.DEBUG)
# create formatterformatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# add formatter to chch.setFormatter(formatter)
# add ch to loggerlogger.addHandler(ch)
# 'application' codelogger.debug('debug message')logger.info('info message')logger.warning('warn message')logger.error('error message')logger.critical('critical message')

recorder 記錄器

import loggingimport logging.config
logging.config.fileConfig('logging.conf')
# create loggerlogger = logging.getLogger('simpleExample')
# 'application' codelogger.debug('debug message')logger.info('info message')logger.warning('warn message')logger.error('error message')logger.critical('critical message')

運行結果:

2019-10-16 19:45:34,440 - simple_example - DEBUG - debug message2019-10-16 19:45:34,440 - simple_example - INFO - info message2019-10-16 19:45:34,440 - simple_example - WARNING - warn message2019-10-16 19:45:34,440 - simple_example - ERROR - error message2019-10-16 19:45:34,441 - simple_example - CRITICAL - critical message

總結

本章節給大家介紹了 Python 標準庫中 Logging 模塊的詳細介紹與使用,對 Python 工程師使用該模塊提供更好的支撐

參考:https://docs.python.org/3.6/library/logging.html?highlight=logging#integration-with-the-warnings-modulehttps://www.jianshu.com/p/feb86c06c4f4
https://cloud.tencent.com/developer/article/1354396


相關焦點

  • python中logging模塊詳解
    為什麼需要logging模塊用python寫代碼的時候,想看哪裡的輸出直接print就可以了。
  • Python之日誌處理(logging模塊)
    Logging 中幾種級別:DEBUG < INFO < WARNING < ERROR < CRITICALlogging模塊是python內置的標準模塊,主要用於輸出運行日誌,可以設置輸出日誌的等級、日誌保存路徑、日誌文件和回滾等;可以說,logging模塊主要由4部分組成:
  • Python Logging 模塊完全解讀
    你也可以在 logging 中包含 traceback 信息。不管是小項目還是大項目,都推薦在 Python 程序中使用 logging。本文將簡單清晰地介紹如何使用 logging 模塊。為什麼使用 logging?當你運行一個 Python 腳本時,你可能想要知道腳本的哪個部分在執行,並且檢視變量的當前值。通常,可以只使用 print() 列印出你想要的信息。
  • Python的logging詳解
    Print不用的好好的麼,為什麼要用logging?因為調試時,print語句需要改動代碼,調試完你還得刪除掉,萬一忘記怎麼辦?還有線上代碼運行時你想知道當時發生了什麼,logging是最好的辦法。先看下logging的簡單用法:import logginglogging.basicConfig(level=logging.DEBUG)logger = logging.getLogger(__name__)logger.info('Start logging')msg = 'test'logger.debug('message: %s', msg)logger.info
  • 有了它,可以把Python裡Logging模塊扔掉了!
    logging 模塊,要實現既在終端輸出,又能寫文件,並且日誌文件還能 rotate ,代碼需要十多行:import loggingfrom logging.handlers import RotatingFileHandleros.makedirs('Logs', exists_ok=True)logger = logging.getLogger
  • python學習之日誌輸出格式logging.basicConfig函數的使用
    python的logging.basicConfig函數 ,使用時粘貼到用例前,就可以打log了。logging模塊是python內置的標準模塊,主要用於輸出運行日誌,可以設置輸出日誌的等級,日誌保存路徑,日誌文件回滾等日誌等級:(從低到高)debug:調試代碼用的,信息比較詳細info:輸出正確的信息,按照正常的代碼運行
  • python乾貨分享:使用logging記錄日誌信息
    Python中自帶的logging模塊提供了日誌功能,它將logger的level分為5個級別,可以通過Logger.setLevel(lvl)來設置,其中DEBUG為最低級別,CRITICAL為最高級別. 默認的級別為WARNING。
  • python中的模塊詳解
    概念python中的模塊是什麼?簡而言之,在python中,一個文件(以「.py」為後綴名的文件)就叫做一個模塊,每一個模塊在python裡都被看做是一個獨立的文件。模塊可以被項目中的其他模塊、一些腳本甚至是交互式的解析器所使用,它可以被其他程序引用,從而使用該模塊裡的函數等功能,使用Python中的標準庫也是採用這種方法。分類在Python中模塊分為以下幾種:系統內置模塊,例如:sys、time、json模塊等等;自定義模塊,自定義模塊是自己寫的模塊,對某段邏輯或某些函數進行封裝後供其他函數調用。
  • 【python】os 模塊使用筆記
    複製文件的函數居然在os模塊中不存在!原因是複製文件並非由作業系統提供的系統調用。理論上講,我們通過上一節的讀寫文件可以完成文件複製,只不過要多寫很多代碼。幸運的是shutil模塊提供了copyfile()的函數,你還可以在shutil模塊中找到很多實用函數,它們可以看做是os模塊的補充。
  • Python與SEO應用第二期
    一、講義說明本期培訓主要是面向想通過python來提高SEO工作效率的SEOer或者是對python爬蟲感興趣的目標人群。培訓的主要內容是學習如何通過python來開發各種SEO工具,以及python爬蟲的開發。
  • 淺談 Python 中的模塊
    模塊分類Python 中的模塊共分為三類,即內置模塊、第三方模塊、以及自定義模塊。random:用於生成隨機數time: 主要包含各種提供日期、時間功能的類和函數datetime:對 time 模塊的一個高級封裝logging:日誌處理re:用於實現正則匹配json:用於字符串和數據類型間進行轉換json1.2 第三方模塊
  • Python3 pickle模塊的使用詳解
    pickle模塊特點1、只能在python中使用,只支持python的基本數據類型。2、可以處理複雜的序列化語法。
  • netcdf4-python 模塊詳解
    python中提供了多種方式來處理netcdf文件,這裡主要講一下常用的 netcdf4-python 模塊。
  • 萬字長文詳解Python正則表達式及re模塊
    本文帶來的是偷學Python第三十一天:Python正則表達式語法及re模塊的使用,其他內容將在近期更新完畢,本文主要將涉及以下內容exp) 零寬度負回顧後發斷言,來斷言此位置的前面不能匹配表達式exp,Python中提供的re模塊使Python擁有全部正則表達式的功能!
  • python之OS模塊39個常用函數詳解
    作者:小伍哥 來源:AI入門學習os,語義作業系統,所以該模塊就是作業系統相關的功能了,用於處理文件和目錄這些我們日常手動需要做的操作,比如新建文件夾、獲取文件列表、刪除某個文件、獲取文件大小、重命名文件、獲取文件修改時間等,該模塊就包含了大量的作業系統操作函數,精選常用的進行解析,希望對大家有所幫助。
  • 史上最全的 python 基礎知識匯總篇,沒有比這再全面的了,建議收藏
    爬蟲(六十三)socket編程(五十四)我們自己值多少錢爬蟲(六十一)網絡編程(五十二)定投的心態,就像還房貸爬蟲(六十)re模塊爬蟲(五十九)正則表達式語法(五十)定投的好處爬蟲(五十八)正則表達式(四十九)定投,做一個聰明的『懶人』爬蟲(五十七)通用標準庫 logging
  • python的模塊和序列
    前言概要本章節主要講述python中的模塊和序列的概念以及如何使用模塊和序列化方面的知識。模塊的概念在python中有個關鍵詞是import,代表的是導入、加載的意思。通常import加載的模塊分為四個通用類別:使用python語言編寫的代碼(後綴名為py的文件)已被編譯為共享庫或DLL的C或C++的擴展使用C編寫並連接到python解釋器的內置模塊
  • Python之os模塊
    Python部落(python.freelycode.com)組織翻譯,禁止轉載,歡迎轉發。
  • Python程式設計師進階之路:從新手到高手的100個模塊
    ,真實反映了 python 程式設計師在成長過程中的一些困惑。英漢小詞典pythoneer - 指所有用python語言開發程序的人pythonista - 意為資深的、追求質量和品味的python開發者本文所列舉的這100個模塊,是在工作和學習中用過的或者正在學習的,算是學習總結。希望對處在迷茫中的程式設計師有所幫助。
  • 第39天: Python itertools 模塊
    而 itertools 作為 Python 的內置模塊,就為我們提供了一套非常有用的用於操作可迭代對象的函數。常用功能 count 功能詳解count(start=0,step=1) 函數有兩個參數,其中 step 是默認參數,可選的,默認值為 1。該函數返回一個新的迭代器,從 start 開始,返回以 step 為步長的均勻間隔的值。