Python logging模塊使用配置文件記錄日誌
推薦用法
在項目中推薦使用按照時間的滾動日誌記錄方式,並使用配置文件進行日誌記錄配置。這樣有很多好處:不會讓日誌文件無限變大,很容易實現保留最近N天日誌的功能,需要修改日誌記錄規則直接改配置文件就好。按照時間滾動的日誌需要使用TimedRotationHandler,其定義如下所示:
所謂按時間滾動意思是系統會在時間滿足一定條件時給舊的日誌文件存檔,並僅保留一定時間內的日誌,最終存檔的日誌文件名稱類似:xx.log.2016-06-01。
class logging.handlers.TimedRotatingFileHandler(filename, when=‘h‘, interval=1, backupCount=0, encoding=None, delay=False, utc=False)
參數 | 名稱 | 解釋 |
---|---|---|
filename | 文件名 | 在時間滾動模式中,它實際上代表文件名的前綴 |
when | 時間 | 按照哪種時間單位滾動(可選s-按秒,m-按分鐘,h-按小時,d-按天,w0-w6-按指定的星期幾,midnight-在午夜) |
interval | 間隔 | 比如when設置為s,interval設置為1意思是每1秒 |
backupCount | 備份數量 | 保存幾份日誌,系統會自動刪除超出此數目的日誌文件 |
encoding | 編碼 | 默認是UTF-8編碼 |
delay | 延遲寫入 | 如果設置為True那麽只有調用了emit()後才會寫入文件。 |
utc | 標準時間 | 設置為False(默認)使用本地時間,否則使用標準時間 |
配置文件
下面簡單介紹一下配置文件中的要素。
設置按時間滾動
可以在log.conf文件中用下面的樣式設置按時間滾動的handler。使用class指定handler,使用level指定使用此handler處理的日誌級別,使用formatter指定此handler的日誌格式,使用args傳遞參數,參數應該按上述定義的順序寫。
[handler_timedrt]
class=handlers.TimedRotatingFileHandler
level=INFO
formatter=form02
args=(‘myapp.log‘, ‘s‘, 1 , 10 )
設置HTTP
題外話:可以設置向HTTP服務器發送數據,通常在一個分布式的環境中,我們會選擇實現一個HTTP接口用來接收來自各個網絡組件的日誌。
[handler_http]
class=handlers.HTTPHandler
level=NOTSET
formatter=form02
args=(‘localhost:9022‘, ‘/log‘, ‘GET‘)
使用示例
可以使用下面的代碼從配置文件中載入日誌配置並進行日誌記錄。
import logging
import logging.config
logging.config.fileConfig("logger.conf")
logger = logging.getLogger("example01")
logger.debug(‘This is debug message‘)
logger.info(‘This is info message‘)
logger.warning(‘This is warning message‘)
在工程中的實踐
下面我們來看看如何在實際的工程中按照推薦的用法使用logging模塊。在工程中,我推薦使用下面這種結構:
--lib
|--class1.py
|--class2.py
--config.py
--main.py
--logger.conf
工程中我們使用一個名字為config.py的Python模塊用來保存全局的配置,由於logging在工程中每個源代碼文件都可能用到,因此我們把logging模塊在config.py中生成一個實例,這樣其它模塊只需要引用這個實例就可以了。
import logging
import logging.config
from pymongo import MongoClient
config = { "key1":"value1" }
logging.config.fileConfig("logger.conf")
logger = logging.getLogger("cse")
在其它模塊中,我們使用這樣的語句引用logger對象:
from config import logger
需要記錄日誌的時候,只需要使用logger.error,logger.debug類似的語句就好了。
完整的logger.conf
下面是一個完整的logger.conf文件示例,它默認為會將日誌存儲在當前目錄的log目錄下,會將ERROR及以上級別的日誌通過POST請求發送到http://localhost:8087/api/v1.0/log。請根據需要自行修改。
#logger.conf
###############################################
[loggers]
keys=root,cse
[logger_root]
level=DEBUG
handlers=stream
[logger_cse]
handlers=stream,timedrt,http
qualname=cse
propagate=0
###############################################
[handlers]
keys=stream,timedrt,http
[handler_stream]
class=StreamHandler
level=NOTSET
formatter=form01
args=(sys.stderr,)
[handler_filert]
class=handlers.RotatingFileHandler
level=INFO
formatter=form02
args=(‘log/cse.log‘, ‘a‘, 10*1024*1024, 5)
[handler_timedrt]
class=handlers.TimedRotatingFileHandler
level=DEBUG
formatter=form01
args=(‘log/cse.log‘, ‘d‘, 1 , 10 )
[handler_http]
class=handlers.HTTPHandler
level=ERROR
formatter=form01
args=(‘localhost:8087‘, ‘/api/v1.0/log‘, ‘POST‘)
###############################################
[formatters]
keys=form01,form02
[formatter_form01]
format=[%(asctime)s][%(filename)s][line:%(lineno)d][%(levelname)s] %(message)s
datefmt=%a, %d %b %Y %H:%M:%S
[formatter_form02]
format=%(name)-12s: %(levelname)-8s %(message)s
datefmt=
字段說明:
[loggers]
# 定義logger模塊,root是父類,必需存在的,其它的是自定義。
# logging.getLogger(NAME)便相當於向logging模塊註冊了一種日誌打印
# name 中用 . 表示 log 的繼承關系
[handlers]
# 定義handler
[formatters]# 定義格式化輸出 [logger_root]
# 實現上面定義的logger模塊,必需是[logger_xxxx]這樣的形式
# [logger_xxxx] logger_模塊名稱
# level 級別,級別有DEBUG、INFO、WARNING、ERROR、CRITICAL
# handlers 處理類,可以有多個,用逗號分開
# qualname logger名稱,應用程序通過 logging.getLogger獲取。對於不能獲取的名稱,則記錄到root模塊。
# propagate 是否繼承父類的log信息,0:否 1:是
[handler_infohandler]# [handler_xxxx]# class handler類名# level 日誌級別# formatter,上面定義的formatter# args handler初始化函數參數
[formatter_form01]
# 日誌格式
#--------------------------------------------------
# %(asctime)s 年-月-日 時-分-秒,毫秒 2013-04-26 20:10:43,745
# %(filename)s 文件名,不含目錄
# %(pathname)s 目錄名,完整路徑
# %(funcName)s 函數名
# %(levelname)s 級別名
# %(lineno)d 行號
# %(module)s 模塊名
# %(message)s 消息體
# %(name)s 日誌模塊名
# %(process)d 進程id
# %(processName)s 進程名
# %(thread)d 線程id
# %(threadName)s 線程名
Python logging模塊使用配置文件記錄日誌