打印日志是很多程序的重要需求揩抡,良好的日志輸出可以幫我們更方便的檢測程序運(yùn)行狀態(tài)藻懒。Python標(biāo)準(zhǔn)庫提供了logging模塊簇爆,讓我們也可以方便的在Python中打印日志癞松。
日志介紹
完整的使用方法可以參考標(biāo)準(zhǔn)庫文檔。這里做一下簡單介紹入蛆。
日志級別
日志級別有如下幾種响蓉。當(dāng)獲取根Logger的時候,默認(rèn)級別為NOTSET哨毁,這樣會顯示所有輸出枫甲。當(dāng)獲取非根Logger的時候,根Logger的默認(rèn)級別是WARNING,非根Logger會繼承這個級別想幻,只有WARNING以上的日志才會輸出粱栖。
級別 | 數(shù)值 |
---|---|
CRITICAL | 50 |
ERROR | 40 |
WARNING | 30 |
INFO | 20 |
DEBUG | 10 |
NOTSET | 0 |
日志對象
日志對象通過模塊的getLogger(name)
函數(shù)獲得,可以向該函數(shù)傳遞一個名稱脏毯。如果不傳遞名字的話闹究,就會獲取根Logger。
日志對象常用方法如下抄沮。
方法名 | 作用 |
---|---|
setLevel(lvl) | 設(shè)置日志級別 |
isEnabledFor(lvl) | 檢查某級別的日志是否啟用 |
getEffectiveLevel() | 獲取實際的日志級別 |
debug/warning/info/error(msg, *args, **kwargs) |
輸出對應(yīng)級別的日志 |
log(lvl, msg, *args, **kwargs) |
輸出指定級別的日志 |
addFilter(filt)/removeFilter(filt) | 添加或刪除指定的過濾器 |
addHandler(hdlr)/removeHandler(hdlr) | 添加或刪除指定的處理器 |
Handler對象
日志對象用于輸出日志跋核,而Handler對象用于指定日志向哪里輸出(文件、終端等等)叛买。Handler列表可以參考Handler類型砂代。
常用的Handler有以下幾種:
- StreamHandler, 用于向標(biāo)準(zhǔn)輸入輸出流等輸出日志率挣。
- FileHandler刻伊,用于向文件輸出日志。
- NullHandler椒功,什么也不輸出捶箱。
- RotatingFileHandler,向文件輸出日志动漾,如果文件到達(dá)指定大小丁屎,創(chuàng)建新文件并繼續(xù)輸出日志。
還有好多種Handler旱眯,可以向HTTP服務(wù)器發(fā)送日志晨川、向系統(tǒng)日志管理器寫入日志、向指定電子郵箱發(fā)送日志等Handler删豺。這里就不介紹了共虑。如果有相關(guān)需求請參考相應(yīng)文檔。
Formatter對象
Formatter對象用于格式化日志輸出呀页。格式化字符串使用傳統(tǒng)的%
形式來格式化日志妈拌,可以參考官方文檔了解更多信息。
過濾器對象
過濾器對象用于過濾日志的輸出蓬蝶。
LogRecord對象
LogRecord對象基本上和我們沒多大關(guān)系尘分,簡單地說,我們輸出的每一條日志丸氛,就是一個LogRecord對象音诫。它有日志系統(tǒng)自動創(chuàng)建和使用。如果我們留心一下日志模塊的方法雪位,會發(fā)現(xiàn)有很多地方都要接受LogRecord參數(shù)。LogRecord有很多屬性信息,對日志打印有幫助雹洗,可以參考16.6.6. LogRecord Objects下面的屬性和格式化符的對照表香罐。例如%(asctime)s
會生成人類可讀的時間戳,%(lineno)d
返回當(dāng)前行號等等时肿。
模塊級別函數(shù)
日志模塊還包含了一些模塊級別的函數(shù)庇茫。簡單不完整列舉如下:
函數(shù)名 | 作用 |
---|---|
getLogger(name=None) | 獲取對應(yīng)名稱的Logger,如果不指定名稱會返回根Logger |
debug/info等函數(shù) | 在根Logger上打印對應(yīng)級別的日志信息 |
disable(lvl) | 禁用某級別的日志打印 |
basicConfig(關(guān)鍵字參數(shù)) | 這個函數(shù)可以快速設(shè)置日志的級別螃成、格式旦签、Handler、Formatter等 |
使用日志
前面都是紙面上的介紹寸宏,下面來真正使用日志模塊來打印日志宁炫。下面的代碼所用知識,前面都已介紹過氮凝。運(yùn)行代碼之后羔巢,可以驗證日志同時在終端輸出和文件中輸出。
import logging
# 創(chuàng)建Logger
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# 創(chuàng)建Handler
# 終端Handler
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.DEBUG)
# 文件Handler
fileHandler = logging.FileHandler('log.log', mode='w', encoding='UTF-8')
fileHandler.setLevel(logging.NOTSET)
# Formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
consoleHandler.setFormatter(formatter)
fileHandler.setFormatter(formatter)
# 添加到Logger中
logger.addHandler(consoleHandler)
logger.addHandler(fileHandler)
# 打印日志
logger.debug('debug 信息')
logger.info('info 信息')
logger.warning('warn 信息')
logger.error('error 信息')
logger.critical('critical 信息')
logger.debug('%s 是自定義信息' % '這些東西')
運(yùn)行結(jié)果罩阵。
2017-04-04 21:45:16,742 - root - DEBUG - debug 信息
2017-04-04 21:45:16,742 - root - INFO - info 信息
2017-04-04 21:45:16,742 - root - WARNING - warn 信息
2017-04-04 21:45:16,742 - root - ERROR - error 信息
2017-04-04 21:45:16,742 - root - CRITICAL - critical 信息
2017-04-04 21:45:16,742 - root - DEBUG - 這些東西 是自定義信息
外部配置
前面都是在代碼中配置日志的輸出竿秆,我們還可以將配置寫到配置文件中,然后傳遞給日志模塊稿壁。舊式程序會使用conf
格式配置文件幽钢,不過這種配置文件比較傳統(tǒng),所以就不介紹了傅是。
自Python 3.2起匪燕,引入了一種新的基于鍵值對的配置方式。這種新方式的優(yōu)點是配置文件非常靈活落午,我們可以使用XML谎懦、YAML、JSON等格式存儲配置溃斋,也可以從網(wǎng)絡(luò)上接收序列化的Python對象當(dāng)做配置對象界拦。總之梗劫,想怎么來就怎么來享甸。我們下面就介紹這種新方式。
具體的鍵值對需要參考官方文檔梳侨。例如下面就是Python官方給出的一個YAML格式的配置文件蛉威。
version: 1
formatters:
simple:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stdout
loggers:
main:
level: DEBUG
handlers: [console]
propagate: no
root:
level: DEBUG
handlers: [console]
然后引入logging.config
模塊,并將配置文件傳遞給logging.config
模塊的dictConfig
方法走哺。這樣就做好了日志打印的準(zhǔn)備工作了蚯嫌。
import logging.config
logging.config.dictConfig('config.yaml')
logger = logging.getLogger('fuck')