基本介紹
- 語言環(huán)境:python3.9
- 文章大意:簡要的寫一下關于python中l(wèi)ogging模塊的理解
- 官方文檔鏈接:
概念介紹
logging中有四個主要概念logger(記錄器)笛园、handler(處理器)颇玷、filter(過濾器)和formatter(格式器)
前三者的關系不是等價的丰涉,而是logger可以包含filter企垦,handler也可以包含filter
- 先思考一下,假如我們現(xiàn)在想做一個日志功能需要怎么做呢涯保?
- 代碼報錯的時候诉濒,我們要打印一條日志消息,那么需要一個類去拿到這條消息(記錄器)
- 日志消息有很多種夕春,可能是重大報錯了未荒,也可能只是執(zhí)行成功的一條確認消息
- 那我們就應該分級別,如DEBUG及志,INFO片排,WARNING,ERROR等
- 然后經(jīng)過一系列過濾之后(過濾器)速侈,這條消息是不是得拿去處理率寡?
- 處理什么呢?比如我們可以把它寫到文件里倚搬,也可以寫到控制臺上
- 最后一個問題冶共,我們決定寫到文件里了,可是怎么寫呢每界?
- 我們就需要定義一個輸出的規(guī)范(格式器)比默,比如第一列表示時間,第二列表示嚴不嚴重
- 這么一想盆犁,是不是logging沒有想象中那么難了命咐?接下來看一下常見的配置
- 不用去看懂每一句,先看清楚結(jié)構(gòu)
- LOGGING這個字典里一共有4個key
- version代表架構(gòu)版本谐岁,不用理解太深醋奠,反正目前都是1
- formatter應該很好理解,給處理器(handler)用的伊佃,讓處理器可以根據(jù)這個格式進行輸出
- 先看記錄器(logger)窜司,先想一想為什么要用my_project_name命名呢?只定義這兩個記錄器夠嗎航揉?我們可是有成百上前的項目文件的塞祈,為什么就用一兩個記錄器就可以了?
- 比如某一個文件為
my_project_name.my_package.my_file.py
帅涂,代表在項目下的包里的一個文件议薪,我們在這個文件使用記錄器的時候,一般代碼為logger = logging.getLogger(__name__)
媳友,以這個文件名為一個記錄器 - 但是我們沒有配置這個名字的記錄器(如果一個文件配置一個記錄器斯议,很累的對不對?)醇锚,它就會默認找上級哼御,比如找
my_project_name.my_package
,或者my_project_name
,當?shù)絤y_project_name的時候就找到了恋昼,如下面的代碼里可以看到 - 經(jīng)過level和可能會有的過濾器后看靠,他就要發(fā)送給handler了,下面可以看到是發(fā)給兩個液肌,分別為console和file挟炬,然后接下來會發(fā)生什么
- console的處理器猜一猜都覺得是輸出到控制臺,那file呢矩屁?
- 可以看到有個filename的key辟宗,我們終于找到日志要輸出到哪了爵赵,就是在項目根目錄下的一個名為
my_project_name.log
的文件吝秕,然后用formatter去格式化那個輸出的格式 - 至此,流程就串通起來了空幻,一條日志記錄就誕生了
LOGGING = {
'version': 1,
'formatters': {
'default': {
'format': '%(levelname)s %(asctime)s %(module)s %(message)s'
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'default',
},
'file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'default',
'filename': BASE_DIR / 'my_project_name.log',
'backupCount': 5,
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'formatter': 'default',
},
},
'loggers': {
'django': {
'handlers': ['console', 'file'],
'level': 'ERROR',
},
'my_project_name': {
'handlers': ['console', 'file'],
'level': 'DEBUG',
},
}
}