Python logging通过dictConfig配置日志时如何使用GMT/UTC时间
问题原因
你在dictConfig的formatter配置中直接写converter参数不生效,核心原因是Python原生的dictConfig在初始化logging.Formatter实例时,默认仅识别format、datefmt、style、validate几个内置参数,你传入的converter字段会被直接忽略,因此日志始终使用默认的本地时间。
传入字符串形式的'time.gmtime'/'gmtime'同样无效:dictConfig仅会对class字段传入的类路径做自动导入解析,普通配置字段不会自动转换为对应模块的函数/对象。
可用解决方案
方案1:自定义UTC格式化器子类(最推荐,无侵入)
直接继承logging.Formatter覆盖时间转换属性,在配置中通过class字段指定使用该子类即可,完全兼容dictConfig的原生加载逻辑,不会破坏毫秒格式:
import time import logging from logging.config import dictConfig # 定义UTC时区的格式化器子类 class UTCFormatter(logging.Formatter): converter = time.gmtime DEFAULT_CONFIG = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'class': '__main__.UTCFormatter', # 如果子类放在其他模块,替换为对应导入路径即可 'format': '%(levelname)s : %(name)s : %(asctime)s.%(msecs)03d : %(message)s', 'datefmt': '%Y-%m-%d %H.%M.%S', } }, 'handlers' : { 'default': { 'level': 'NOTSET', 'class': 'logging.StreamHandler', 'formatter': 'standard', } }, 'loggers': { 'TEST': { 'handlers' : ['default'], 'level': 'INFO', 'propagate': False, }, }, 'root': { 'level': 'INFO', 'handlers': ['default'] }, 'incremental': False } if __name__ == '__main__': dictConfig(DEFAULT_CONFIG) logger = logging.getLogger('TEST') logger.info('info message') logger.warning('warning message') logger.error('error message')
运行后输出的时间即为UTC时间,毫秒部分正常保留3位格式。
方案2:加载配置后批量修改格式化器属性
如果不想自定义子类,也可以在调用dictConfig加载完配置后,遍历所有处理器上的格式化器,手动修改converter属性:
if __name__ == '__main__': dictConfig(DEFAULT_CONFIG) # 统一设置所有已注册处理器的格式化器使用UTC时间 for handler in logging.root.handlers: if handler.formatter: handler.formatter.converter = time.gmtime # 如有自定义非root logger,额外遍历对应logger的handlers做相同设置即可 logger = logging.getLogger('TEST') logger.info('info message')
关于fileConfig的说明
fileConfig的配置解析灵活度比dictConfig更低,不支持直接传入自定义构造参数,要实现UTC时间输出,要么使用上述自定义Formatter子类,要么加载完配置后手动修改formatter的converter属性即可。
内容的提问来源于stack exchange,提问作者NichD
相关产品推荐
相关产品推荐

