如何在Python中临时更改日志消息格式?
在Python中,最简单的方法是什么,可以临时改变日志信息的格式(通过日志模块)?
我们的目标是有一个标准的消息格式,同时能够临时添加一些关于正在读取的文件的信息(比如文件名);当不再读取文件时,消息格式应该恢复到默认状态。生成这些消息的程序并不知道正在读取哪个文件,所以如果它的消息能自动包含相关的文件名就好了(比如错误信息会变成:“错误 在读取文件 ***: …”而不是“错误: …”)。
5 个回答
6
我不太推荐这样做;不过你可以假设第一个根处理程序有问题,然后直接修改它。
import logging
ROOT_LOGGER = logging.getLogger()
ROOT_LOGGER.handlers[0].setFormatter(logging.Formatter(
'%(asctime)s:%(levelname)s:%(name)s:%(message)s\n'
))
如果你在一个有管理日志的系统中,这样做可能会给自己带来麻烦;最好还是能准确找到你想修改的处理程序,然后去修改它。
不过如果它能正常工作,谁会在乎它有多糟糕呢?
9
有几种方法可以做到这一点。除了已经记录的方式(比如在记录日志时使用extra
参数、LoggerAdapter
和Filter
),还有一种方法是指定一个自定义的格式化类,你可以让这个类知道正在处理哪个文件。例如:
class FileProcessingFormatter(logging.Formatter):
def __init__(self, fmt, datefmt=None, current_file=None):
super(FileProcessingFormatter, self).__init__(fmt, datefmt)
self.orig_fmt = fmt
self.current_file = current_file
def format(self, record):
if self.current_file is None:
self._fmt = self.orig_fmt.replace('__FILE_PLACEHOLDER__', '')
else:
self._fmt = self.orig_fmt.replace('__FILE_PLACEHOLDER__',
' while processing %r' % self.current_file)
return super(FileProcessingFormatter, self).format(record)
实例化格式化器 ...
f = FileProcessingFormatter('%(levelname)s__FILE_PLACEHOLDER__ %(message)s')
for h in relevant_handlers:
h.setFormatter(f)
处理文件 ...
f.current_file = fn
process_file(fn)
f.current_file = None
这非常简单——比如说,如果文件处理是由不同的线程同时进行的,这种方法就不适用了。
更新:虽然可以通过logging.getLogger().handlers
访问根记录器的处理器,但这只是一个实现细节,可能会改变。由于你的需求并不那么基础,你可以考虑使用dictConfig()
来配置你的日志记录(在logutils项目中可以找到适用于旧版本Python的相关内容)。
23
这里有一个简单的解决方案,可以从 Vinay Sajip 的 教程 中推导出来;它基本上是通过 setFormatter()
来更新日志格式化器:
import logging
logger = logging.getLogger() # Logger
logger_handler = logging.StreamHandler() # Handler for the logger
logger.addHandler(logger_handler)
# First, generic formatter:
logger_handler.setFormatter(logging.Formatter('%(message)s'))
logger.error('error message') # Test
# New formatter for the handler:
logger_handler.setFormatter(logging.Formatter('PROCESSING FILE xxx - %(message)s'))
logger.error('error message') # Test
这样做可以正确生成:
error message
PROCESSING FILE xxx - error message
(其中 xxx
可以动态设置为正在处理的文件,这正是问题中所要求的)。