如何获取当前的日志格式化程序?

cic*_*lus 5 python logging

我正在使用 python 标准库中的日志记录模块,并希望获取当前的Formatter. 原因是我正在使用multiprocessing模块,并且对于每个进程,我想为它的记录器分配另一个文件处理程序以记录到它自己的日志文件中。当我按以下方式执行此操作时

logger = logging.getLogger('subprocess')
log_path = 'log.txt'
with open(log_path, 'a') as outfile:
        handler = logging.StreamHandler(outfile)
        logger.addHandler(handler)
Run Code Online (Sandbox Code Playgroud)

中的消息log.txt根本没有格式,但我希望该消息的格式与我的典型日志记录格式相同。我的典型日志记录设置如下所示

    logging.basicConfig(
        format='%(asctime)s | %(levelname)s | %(name)s - %(process)d | %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
        level=os.environ.get('LOGLEVEL', 'INFO').upper(),
    )
    logger = logging.getLogger(__name__)
Run Code Online (Sandbox Code Playgroud)

由于看起来该Formatter对象与该对象相关联Handler,因此我尝试从Logger具有正确格式的主对象获取处理程序。所以我打电话

logger.handlers
Run Code Online (Sandbox Code Playgroud)

但我得到了一个空清单[]

所以我的问题是,我在哪里可以获得Formatter与我的主记录器具有相同格式的对象?

根据记录,我在 macOS 上使用 python 3.8,但代码将部署到 Linux(但仍然是 python 3.8)。

小智 3

cpython上的源代码来看logging.basicConfig,包含格式化字符串的格式化程序对象最终会添加到传递给根记录器的处理程序中(请参阅:此处)。因此,您可以通过执行以下操作从根记录器对象获取处理程序(以及格式化程序)

logging.root.handlers[0].formatter
Run Code Online (Sandbox Code Playgroud)

特别是,要实现问题中的子进程日志记录处理程序,您可以这样做

        handler = logging.StreamHandler(outfile)
        handler.setFormatter(logging.root.handlers[0].formatter)
        handler.setLevel(logging.root.level)
        logger.addHandler(handler)
Run Code Online (Sandbox Code Playgroud)

这会将您的处理程序设置为与常用记录器对象相同的日志记录格式(以及级别!)。