【Tornado】解决日志文件和控制台日志格式不一致的问题

tech2025-11-04  7

问题

通过以下参数来配置tornado的日志输出格式(参数可参考:tornado/log.py)

LOGGING = { 'options': { 'logging': 'info', # 日志级别 (debug|info|warning|error|none) 'log_to_stderr': None, # Default None, type bool 'log_file_prefix': './aone.log', # 日志文件前缀 'log_rotate_mode': 'time', # 日志切换模式 (time|size) 'log_file_max_size': 1024 * 1024 * 1024, # 日志最大大小 'log_file_num_backups': 10, # 日志最大备份数 'log_rotate_when': 'D', # 指定按时间切换的类型 ('S', 'M', 'H', 'D', 'W0'-'W6') 'log_rotate_interval': 1, # 按时间切换间隔 }, 'formatter': { 'fmt': '%(asctime)s %(levelname)s %(filename)s %(funcName)s:%(lineno)d : %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S' } }

然后通过参数化读取设置,输出控制台和文件日志:日志文件里的格式与预期配置的不一样

# 日志文件 [E 200904 13:42:56 cms_service:91] 扫描发生了异常:Expecting value: line 3 column 1 (char 2) # 控制台 2020-09-04 13:42:56 ERROR cms_service.py scan_cms:91 : 扫描发生了异常:Expecting value: line 3 column 1 (char 2)

解决前代码

def main(): """Aone for service""" for key, value in SETTINGS.LOGGING['options'].items(): tornado.options.options.__setattr__(key, value) # 读取配置参数 formatter = tornado.log.LogFormatter(**SETTINGS.LOGGING['formatter']) [i.setFormatter(formatter) for i in logging.getLogger().handlers] # 解析命令行 tornado.options.define('port', default=8888, help='run on the given port', type=int) tornado.options.parse_command_line() # 创建服务并监听端口 http_server = tornado.httpserver.HTTPServer(Application()) http_server.listen(tornado.options.options.port) try: tornado.ioloop.IOLoop.instance().start() except Exception as e: print(e, 'Exception tornado.ioloop.IOLoop.instance().start()')

排查

发现tornado.options.options配置的参数,真正使用是在tornado.options.parse_command_line()方法的调用,且最终调用tornado.log.enable_pretty_logging()来为程序添加对应的日志方案,即:实例化TimedRotatingFileHandler等相关对象,并添加到logger中,这里有个问题是,上诉的代码,在读取配置参数后,然后解析命令行,这个顺序导致:为logger添加的formatter,并未添加到TimedRotatingFileHandler,因为此时它还没有被添加到logger的handlers中。因此需要调整下代码顺序

修改后

def main(): """Aone for service""" for key, value in SETTINGS.LOGGING['options'].items(): tornado.options.options.__setattr__(key, value) # 解析命令行 tornado.options.define('port', default=8888, help='run on the given port', type=int) tornado.options.parse_command_line() # 读取配置参数 formatter = tornado.log.LogFormatter(**SETTINGS.LOGGING['formatter']) [i.setFormatter(formatter) for i in logging.getLogger().handlers] # 创建服务并监听端口 http_server = tornado.httpserver.HTTPServer(Application()) http_server.listen(tornado.options.options.port) try: tornado.ioloop.IOLoop.instance().start() except Exception as e: print(e, 'Exception tornado.ioloop.IOLoop.instance().start()')

问题解决

最新回复(0)