Python標準庫 - logging
編寫代碼時, 常要跟蹤下其運行過程, 記錄日誌是常用的方式. 較簡單的就是print命令打印到終端, 或通過open函數寫入文件. 但隨著代碼量的增加, 該方式不可控的弊端, 也凸顯出來, 這也正是logging模塊出現的背景.
對於logging模塊, 簡單來說直接import進來, 就可以用了.
In [1]: import logging
In [2]: logging.warning('Watch out!')
WARNING:root:Watch out!
In [3]: logging.info('I told you so')
In [4]:
In [4]:
第二個語句沒有輸出呢, 這需了解下日誌等級的概念. logging模塊默認的日誌等級是WARNING, 大於該等級的日誌才會輸出, 細節如下.
Level | When it’s used |
DEBUG | Detailed information, typically of interest only when diagnosing problems. |
INFO | Confirmation that things are working as expected. |
WARNING | An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR | Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL | A serious error, indicating that the program itself may be unable to continue running. |
借助basicConfig方法, 可對日誌記錄做些配置.
In [1]: import logging
In [2]: logging.basicConfig(filename='/tmp/example.log',level=logging.DEBUG)
In [3]: logging.debug('This message should go to the log file')
In [4]: logging.info('So should this')
In [5]: logging.warning('And this, too')
$ cat /tmp/example.log
DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too
在腳本中, 可按照下面的方式使用logging模塊.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# myapp.py
import logging
import mylib
def main():
logging.basicConfig(filename='myapp.log', format='%(asctime)s - %(name)s - %(levelname)s - %(pathname)s - %(message)s', level=logging.INFO)
logging.info('Started')
mylib.do_something()
logging.info('Finished')
if __name__ == '__main__':
main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# mylib.py
import logging
def do_something():
logging.info('Doing something')
$ python myapp.py
$ cat myapp.log
2018-01-19 17:00:14,821 - root - INFO - myapp.py - Started
2018-01-19 17:00:14,821 - root - INFO - /home/zz/stage/mylib.py - Doing something
2018-01-19 17:00:14,821 - root - INFO - myapp.py - Finished
簡單了解了logging模塊的使用, 接著看下其中幾個重要的概念.
1. Logger 日誌記錄器, 暴露給應用程序直接使用的接口, 幾個方法用於設置記錄器.
Logger.setLevel() - 指定日誌記錄器處理的日誌最低級別.
Logger.addHandler(), Logger.removeHandler() - 為日誌記錄器添加, 或移除處理器.
2. Handler 處理器, 將記錄器獲取的日誌, 傳送到其定義的目的地, 也有幾個方法設置處理器.
setLevel() - 指定處理器處理的日誌最低級別.
setFormatter() - 為處理器選擇一個格式化器.
3. Formatter 格式化器, 指定日誌的輸出格式.
最開始說了logging模塊的簡單用法, 以及了解了上面的概念後, 看下開發較大應用時, 如何使用logging呢.
這主要介紹兩種方式, 其一是, 將logging模塊的配置直接寫在應用代碼中, 如下所示.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# simple_logging_module.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.warn('warn message')
logger.error('error message')
logger.critical('critical message')
$ python simple_logging_module.py
2018-01-19 21:41:58,180 - simple_example - DEBUG - debug message
2018-01-19 21:41:58,180 - simple_example - INFO - info message
2018-01-19 21:41:58,180 - simple_example - WARNING - warn message
2018-01-19 21:41:58,180 - simple_example - ERROR - error message
2018-01-19 21:41:58,180 - simple_example - CRITICAL - critical message
其二, 配置信息寫入文件中, 借助fileConfig方法加載該文件, 如下所示.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# simple_logging_config.py
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.warn('warn message')
logger.error('error message')
logger.critical('critical message')
# 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=
$ python simple_logging_config.py
2018-01-19 21:53:46,216 - simpleExample - DEBUG - debug message
2018-01-19 21:53:46,216 - simpleExample - INFO - info message
2018-01-19 21:53:46,216 - simpleExample - WARNING - warn message
2018-01-19 21:53:46,216 - simpleExample - ERROR - error message
2018-01-19 21:53:46,216 - simpleExample - CRITICAL - critical message
最後簡單說下, 如何總結一個模塊, 可圍繞下面三點進行說明.
1. 該模塊解決的問題, 其它方法是如何做的.
2. 模塊的使用, 以及核心概念(或定義).
3. 核心API的梳理.
若感興趣可關註訂閱號”數據庫最佳實踐”(DBBestPractice).
Python標準庫 - logging