Python-日誌收集處理
目錄:
一、logging四大元件:
- 記錄器(Logger): 提供應用程式程式碼直接使用的介面
- 處理器(Handler): 將日誌記錄(由記錄器建立)傳送適當的目的地,即決定日誌在不同端輸出-->控制檯、日誌檔案
- 篩選器(Filter):提供了更細粒度的功能,用於確定要輸出的日誌記錄
- 格式器(Formatter):程式在最終輸出日誌記錄的內容格式
-
日誌器Logger
-
1建立日誌器,若沒有指定日誌器名稱,則預設root
-
logger = logging.getLogger()
print(logger)
輸出結果:#<RootLogger root (WARNING)>
1.2 當有多個具有相同名稱的日誌器,呼叫任一日誌器時將返回對同一記錄物件的引用
注:這種情況下的handler是相互疊加的,由於logging每次輸出日誌記錄數量 = handler數量,如有多個handler,實際結果也會列印多條日誌記錄
import logging logger = logging.getLogger() print(logger) #<RootLogger root (WARNING)> logger1 = logging.getLogger() print(logger1) #<<RootLogger root (WARNING)> #設定兩個處理器handler console_handler = logging.StreamHandler() console_handler1 = logging.StreamHandler() #給兩個相同名稱的logger新增上處理器 logger.addHandler(console_handler) logger1.addHandler(console_handler1) #設定一下格式 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_handler.setFormatter(formatter) console_handler1.setFormatter(formatter) #輸出日誌記錄 logger1.warning("=============this is a warning=================")
輸出結果:
<RootLogger root (WARNING)>
<RootLogger root (WARNING)> #兩個日誌器名稱相同,則對應的有幾個handler就輸出幾條日誌記錄
2021-08-11 21:08:15,855 - root - WARNING - =============this is a warning=================
2021-08-11 21:08:15,855 - root - WARNING - =============this is a warning=================
1.3. 通常建議使用__name__來命名日誌器,或者自定義名稱
import logging
logger = logging.getLogger(__name__)
print(logger) #<Logger __main__ (WARNING)>
logger1 = logging.getLogger("DIY")
print(logger1) #<Logger DIY (WARNING)>
#設定兩個處理器handler
console_handler = logging.StreamHandler()
console_handler1 = logging.StreamHandler()
#給兩個相同名稱的logger新增上處理器
logger.addHandler(console_handler)
logger1.addHandler(console_handler1)
#設定一下格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
console_handler1.setFormatter(formatter)
#輸出日誌記錄
logger1.warning("=============this is a warning=================")
輸出結果:
2021-08-11 21:43:45,628 - DIY - WARNING - =============this is a warning=================
2. 處理器Handler
處理器負責將日誌訊息傳送到不同目標,例如:控制檯,日誌檔案,電子郵件等目標
logging模組提供很多個型別的處理器,其中NullHandler、StreamHandler、FileHandler類在核心日誌包中定義,直接用,其它處理器在logging.handler中(還有另一個子模組logging.config,用於配置功能)
- SteamHandler: 日誌記錄傳送到控制檯,stream:預設為None,日誌輸出到sys.stder;指定stream的話,日誌則輸出到指定stream
logging.StreamHandler(stream=None)
- FileHandler: 日誌記錄傳送到磁碟檔案中
logging.FileHandler(filename='log.txt',mode='a',encoding=None,delay=False)
引數:
filename: 只填寫檔名,則預設新增檔案到當前工作目錄;填寫工作路徑+檔名稱,則新增到對應工作目錄
mode: 預設a模式,可自定義
encoding: 預設為None,可自定義
delay: 預設為False, 如果為True時,將檔案開啟延遲到第一次呼叫時進行emit()
- NullHandler: 不做任何事情的處理器,防止sys.stderr在沒有日誌記錄配置的情況下將庫的記錄事件輸出
logging.NullHandler()
- WatchedFileHandler : 該處理器在linux / unix 下使用,它監視檔案以檢視自上一次發出以來是否已更改。(如果檔案的裝置或索引節點已更改,則認為改檔案已更改),如果檔案已更改,則關閉舊檔案流,並開啟該檔案以獲取新的流,不適合在window下使用
import logging.handlers
logging.handlers.WatchedFileHandler(filename='log.txt',mode='a',encoding='UTF-8',delay=False)
- RotatingFileHandler:日誌記錄到檔案中,當檔案到達指定大小時,開啟一個新的檔案接著記錄,並重命名並增加其後綴為(例如:原檔名.1,原檔名.2)
引數:
maxBytes: 日誌檔案大小,單位為位元組
backupcCount: 備份檔案數量
logging.handlers.RotatingFileHandler(filename='log.txt',mode='a',maxBytes=200,backupCount=1)
輸出:
- TimeRotatingFileHandler: 日誌記錄到檔案中,支援按時間間隔來更新日誌
引數 :
when: 不同值對應不同時間型別,以字串填入,不區分大小寫
3.過濾器Filter
Filters可以由級別使用,輸出感興趣的日誌,過濾不感興趣的日誌
4.格式器Formatter
引數:
fmt: 日誌格式引數,預設為None,如果不特別指定fmt,則使用'%(message)s'格式
datafmt: 時間格式引數,預設為None,如果不特別指定datafmt,則使用formatTime()文件中描述的格式
style: 風格引數,預設為'%',也支援'$','{' 格式
logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt=None,style='%')
二、Logging的工作流程:
- 一個Logger可以包含多個Handler
- 每個Handler可以設定自己的Filter和Formatter
三、設定日誌級別
使用setLevel()方法設定日誌級別,注意:若沒有設定日誌級別,日誌器的日誌級別預設為WARNING
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
四、輸出日誌記錄
logging模組提供5個日誌級別的輸出方法
兩種方法呼叫,分別是logging直接呼叫,或者日誌器呼叫,我們常用的都是建立日誌器物件來呼叫
#logger1為日誌器
logger1.warning("=============this is a warning=================")
logger1.info("=================this is a info===================")
logger1.error("=================this is a error==================")
logger1.debug("=================this is a debug==================")
五、日誌記錄配置
logging模組提供一個配置方法,以字典為容器,設定日誌器,處理器,格式器等引數,使用logging.conf.dictConfig(配置字典)方法生成對應的元器件
import logging.handlers
import logging.config
config = {
'version': 1, # 必填項,值只能為1
'disable_existing_loggers': True, # 選填,預設為True,將以向後相容的方式啟用舊行為,此行為是禁用任何現有的非根日誌記錄器,除非它們或它們的祖先在日誌配置中顯式命名。如果指定為False,則在進行此呼叫時存在的記錄器將保持啟用狀態
'incremental': False, # 選填,預設為False,作用,為True時,logging完全忽略任何formatters和filters,僅處理handlers的level
'formatters': # 格式器配置專用key,在這裡配置formatter,可配置複數formatter
{
'myformatter1': {
'class': 'logging.Formatter', # 必填,格式器對應的類
'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s', # fmt格式
'datefmt': '%Y-%m-%d %H:%M:%S' # 日期時間格式
}
},
'handlers': # 處理器配置專用key,在這裡配置handler,可配置複數handler
{
'console_handler': {
'class': 'logging.StreamHandler', # 必填,處理器對應的類
'level': logging.DEBUG, # 選填,處理器的日誌級別,可填字串'info',或者logging.INFO
'formatter': 'myformatter1', # 選填,這裡要填寫formatters字典中的鍵
},
'file_handler': {
'class': 'logging.handlers.RotatingFileHandler', # 必填,處理器對應的類
'level': logging.INFO, # 選填,處理器的日誌級別,可填字串'info',或者logging.INFO
'formatter': 'myformatter1', # 選填,這裡要填寫formatters字典中的鍵
'filename': './mylog.log', # filehandler特有引數,檔名
'maxBytes': 1024*1024, # 檔案大小
'backupCount': 3, # 備份數量
'encoding': 'UTF-8', # 編碼格式
}
},
'loggers': # 記錄器配置專用key,在這裡配置logger,可配置複數logger
{
'logger1': {
'handlers': ['console_handler', 'file_handler'], # 列表形式,元素填handlers字典中的handler
'level': logging.DEBUG, # 選填,記錄器的日誌級別,不填則預設Warning級別
'propagate': False, # 選填,為False時,禁止將日誌訊息傳遞給父級記錄器
}
},
'root': # 根記錄器專用key
{
'handlers': ['console_handler', 'file_handler'], # 列表形式,元素填handlers字典中的handler
'level': logging.DEBUG, # 選填,記錄器的日誌級別,不填則預設Warning級別
}
}
# 根據配置字典,配置對應元器件
logging.config.dictConfig(config)
if __name__ == '__main__':
logger = logging.getLogger('logger1') # 獲取配置中的logger物件
# 輸出logger日誌記錄
logger.debug("====================【debug】====================")
logger.info("====================【info】====================")
logger.warning("====================【warning】====================")
logger.error("====================【error】====================")
logger.critical("====================【critical】====================")
六、其它實用的方法
logging.basicConfig(**kwargs): 該方法可設定多項引數,來建立StreamHandler或者FileHandler,並新增到根記錄器中,從程式碼上看,更方便更簡潔
三十六般武藝,七十二般變化,修練出個人品牌併發出光芒