如何为单个记录器使用多种格式

时间:2019-11-06 23:36:43

标签: python logging

我有一个模块,可以将数据输出到控制台和日志文件。我希望控制台输出具有简单的'%(message)s'格式,但是我想在日志文件中添加时间戳'%(asctime)s - %(message)s'。如何设置处理程序以向控制台发送与向日志文件发送格式不同的格式?我尝试过的方法导致将两者消息发送到控制台。

以下是不起作用的一个示例:

    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)s - %(message)s')
    console.setFormatter(formatter)
    root.addHandler(console)
    if sysout:
        handler = logging.StreamHandler(sys.stdout)
        handler.setLevel(logging.INFO)
        formatter = logging.Formatter('%(message)s')
        handler.setFormatter(formatter)
        root.addHandler(handler)

部分解决方案:

在我的setup_logging函数中,我使用以下代码:

    logging.basicConfig(filename=abs_log_file, level=logging.DEBUG,
                        format='%(asctime)s - %(message)s')
    root = logging.getLogger()
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    formatter = logging.Formatter('%(message)s')
    console.setFormatter(formatter)
    root.addHandler(console)

...并且在调用setup_logging的模块中,我具有以下内容:

# inhibits timestamps from printing to console logging.getLogger('').handlers[1].formatter._fmt = '%(message)s'

这可以按需工作,但是出现警告“访问类的受保护成员_fmt”。什么是合规解决方案?

1 个答案:

答案 0 :(得分:1)

您有两个处理程序:

  1. 名为handler的处理程序。 handler的输出流为sys.stdouthandler仅打印消息,没有时间戳。
  2. 您有一个名为console的处理程序。 console打印时间戳记和消息。您未指定输出流。

请注意,在编写console = logging.StreamHandler()时,您没有将任何内容传递给构造函数,默认情况下,StreamHandler的目标是sys.stderr,两个处理程序都不会打印到文件。一个通过stdout打印到控制台,另一个通过stderr打印到控制台。我猜想您在stderr提要中看到控制台上的时间戳。


I recommend something like the following:

import logging
import sys

sysout = True
logger = logging.getLogger('simple_example')
logger.setLevel(logging.INFO)
file_handler = logging.FileHandler("mylog.log", delay=True)
# If delay is true, then file opening
# is deferred until the first call to emit().
#
# there's no need to open the file until
# records are read to be written
file_handler.setLevel(logging.INFO)
logger.addHandler(file_handler)
frmt_time_and_msg = logging.Formatter('%(asctime)s - %(message)s')
file_handler.setFormatter(frmt_time_and_msg)


if sysout:
    stdout_handler = logging.StreamHandler(sys.stdout)
    stdout_handler.setLevel(logging.INFO)
    msg_only = logging.Formatter('%(message)s')
    stdout_handler.setFormatter(msg_only)
    logger.addHandler(stdout_handler)


logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

sys.stdout上看到的输出。并非没有时间戳:

info message
warn message
error message
critical message

mylog.log的内容:

2019-11-06 17:24:55,502 - info message
2019-11-06 17:24:55,508 - warn message
2019-11-06 17:24:55,508 - error message
2019-11-06 17:24:55,508 - critical message