[英]Custom Python logging formatter works with fileConfig but not with dictConfig?
我已經花了幾個小時試圖弄清楚為什么這兩個日志配置,據我所知應該是 100% 相同的,不會導致相同的行為:
LOGGING_CONFIG = {
'version': 1,
'disable_existing_loggers': False,
'root': {
'handlers': ['console'],
'level': 'INFO',
},
'gunicorn.access': {
'level': 'INFO',
'handlers': ['access_console'],
'propagate': False,
'qualname': 'gunicorn.access',
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stderr',
'formatter': 'syslog',
},
'access_console': {
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',
'formatter': 'docker_access',
},
},
'formatters': {
'syslog': {
'()': 'citi.logging.DockerFormatter',
'fmt': 'SYSLOG %(asctime)s [%(levelname)s] %(name)s: %(message)s',
},
'docker_access': {
'()': 'citi.logging.DockerFormatter',
'fmt': 'GUNICORN_ACCESS %(asctime)s %(message)s',
},
},
}
[loggers]
keys=root,gunicorn.access
[handlers]
keys=console,access_console
[formatters]
keys=syslog,docker_access
[logger_root]
level=INFO
handlers=console
[logger_gunicorn.access]
level=INFO
handlers=access_console
propagate=0
qualname=gunicorn.access
[handler_console]
class=StreamHandler
formatter=syslog
args=(sys.stderr, )
[handler_access_console]
class=StreamHandler
formatter=docker_access
args=(sys.stdout, )
[formatter_syslog]
class=citi.logging.DockerFormatter
format=SYSLOG %(asctime)s [%(levelname)s] %(name)s: %(message)s
[formatter_docker_access]
class=citi.logging.DockerFormatter
format=GUNICORN_ACCESS %(asctime)s %(message)s
當我使用logging.config.fileConfig
並將包含第二個代碼塊的文件傳遞給它時,它工作正常。 gunicorn.access
記錄器將其格式化程序更改為具有指定format
字符串的自定義DockerFormatter
類(它是logging.Formatter
的簡單子類)。 訪問日志如下所示:
GUNICORN_ACCESS 2021-07-16 18:59:56,454 172.18.0.1 - - "GET /citi/server-status HTTP/1.0" 200 11 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36" 11766
但是當我使用logging.config.dictConfig
並將它傳遞給頂部的 dict 時,除了自定義格式化程序之外的所有內容都可以工作。 格式化程序似乎仍然設置為 Gunicorn 提供的原始默認值(也許??)。 輸出是:
172.18.0.1 - - "GET /citi/server-status HTTP/1.0" 200 11 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36" 7549
通過使用logging_tree
包,我可以知道gunicorn.access
的格式化程序在使用dictConfig
時是某種默認dictConfig
。 它應該是這樣的:
o<--"gunicorn"
| Level NOTSET so inherits level INFO
| |
| o "gunicorn.access"
| | Level INFO
| | Propagate OFF
| | Handler Stream <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
| | Formatter <citi.logging.DockerFormatter object at 0x7f68240e7d90>
但它看起來像這樣:
o<--"gunicorn"
| Level NOTSET so inherits level INFO
| |
| o "gunicorn.access"
| | Level INFO
| | Propagate OFF
| | Handler Stream <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
| | Formatter fmt='%(message)s' datefmt=None
在DockerFormatter
類的調用方式方面,我可以檢測到的唯一區別是fileConfig
表單使用位置參數調用它,而dictConfig
使用(正確的)關鍵字參數調用它。
似乎正在發生的是格式化程序正在正確構造,但沒有正確分配。 我不知道為什么。
最令人氣憤的是,我實際上已經大大簡化了我的日志配置。 在我的完整配置中,我設置了一個基於structlog
的自定義格式化程序,其配置方式與syslog
和docker_access
與DockerFormatter
配置方式DockerFormatter
,但它確實有效。 我很沮喪。 >_<
當然,我在離開辦公室前的最后一次努力(遲到了幾個小時......)確實有效。 事實證明,我對 Gunicorn 的默認設置保持原樣是正確的,因為我完全錯過了 dictConfig 字典中絕對必要的'loggers'
子詞。
它應該是這樣的:
LOGGING_CONFIG = {
'version': 1,
'disable_existing_loggers': False,
'root': {
'handlers': ['console'],
'level': 'INFO',
},
'loggers' {
'gunicorn.access': {
'level': 'INFO',
'handlers': ['access_console'],
'propagate': False,
'qualname': 'gunicorn.access',
},
}
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.