Python學習-logging

Python的logging模塊提供了通用的日誌系統,可以方便第三方模塊或者是應用使用。這個模塊提供不同的日誌級別,並可以採用不同的方式記錄日誌。

logging的日誌可以分爲debug(),info(),warning(),error()和critical 五個級別


最簡單用法

#!/usr/local/bin/python
# -*- coding:utf-8 -*-
import logging


logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')


WARNING:root:warn message
ERROR:root:error message
CRITICAL:root:critical message

默認情況下,logging模塊將日誌打印到屏幕上(stdout),日誌級別爲WARNING(即只有日誌級別高於WARNING的日誌信息纔會輸出)日誌格式如:

WARNING   : root:       warn message
日誌級別 logger實例名  日誌消息內容

日誌級別

級別應用
DEBUG
詳細信息,典型地調試問題時會感興趣
INFO
證明事情按預期工作
WARNING
表明發生了一些意外,或者不久的將來會發生問題(如‘磁盤滿了’)。軟件還是在正常工作
ERROR
由於更嚴重的問題,軟件已不能執行一些功能了
CRITICAL
嚴重錯誤,表明軟件已不能繼續運行了


把日誌寫到文件裏,簡單配置

#!/usr/local/bin/python
# -*- coding:utf-8 -*-
import logging

logging.basicConfig(filename='logger.log', level=logging.INFO)

logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')


INFO:root:info message
WARNING:root:warn message
ERROR:root:error message
CRITICAL:root:critical message

標準輸出(屏幕)未顯示任何信息,發現當前工作目錄下生成了logger.log

其中下面這句level=loggin.INFO意思是,把日誌紀錄級別設置爲INFO,也就是說,只有比日誌是INFO或比INFO級別更高的日誌纔會被紀錄到文件裏,在這個例子, 第一條日誌是不會被紀錄的,如果希望紀錄debug的日誌,那把日誌級別改成DEBUG就行了

如果想同時把log打印在屏幕和文件日誌裏,就需要了解一點複雜的知識了

幾個重要的概念

Logger記錄器,暴露了應用程序代碼能直接使用的接口
Handler處理器,將(記錄器產生的)日誌記錄發送至合適的目的地
Filter過濾器,提供了更好的粒度控制,它可以決定輸出哪些日誌記錄
Formatter格式化器,指明瞭最終輸出中日誌記錄的佈局


Logger 記錄器

Logger是一個樹形層級結構,在使用接口debug,info,warn,error,critical之前必須創建Logger實例,即創建一個記錄器,如果沒有顯式的進行創建,則默認創建一個root logger,並應用默認的日誌級別(WARN),處理器Handler(StreamHandler,即將日誌信息打印輸出在標準輸出上),和格式化器Formatter(默認的格式即爲第一個簡單使用程序中輸出的格式)。

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

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

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

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

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


Handler 處理器

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

# 創建方法
sh = logging.StreamHandler(stream=None)
fh = logging.FileHandler(filename, mode='a', encoding=None, delay=False)

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

·ch.setLevel(logging.WARN) # 指定日誌級別,低於WARN級別的日誌將被忽略

·ch.setFormatter(formatter_name) # 設置一個格式化器formatter

·ch.addFilter(filter_name) # 增加一個過濾器,可以增加多個

·ch.removeFilter(filter_name) # 刪除一個過濾器

NullHandler類位於核心logging包,不做任何的格式化或者輸出。
本質上它是個“什麼都不做”的handler,由庫開發者使用


Formatter 格式化器

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

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

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


Filter 過濾器

暫且略過


basicConfig關鍵字參數

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


配置示例

顯式配置

# -*- encoding:utf-8 -*-
import logging

# create logger
logger_name = "le"
logger = logging.getLogger(logger_name)
logger.setLevel(logging.DEBUG)

# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# create file handler and set level to warning
log_path = "./log.log"
fh = logging.FileHandler(log_path)
fh.setLevel(logging.WARN)

# create formatter
fmt = "%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s"
datefmt = "%a %d %b %Y %H:%M:%S"
formatter = logging.Formatter(fmt, datefmt)

# add handler and formatter to logger
ch.setFormatter(formatter)
fh.setFormatter(formatter)
logger.addHandler(ch)
logger.addHandler(fh)

# print log info
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')


源自作者,好吃的野菜&alex大王

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章