python 日志模块向控制台输出额外信息

python logging module outputs extra information to the console

我想使用日志记录将信息(当前是相同的信息)记录到控制台和文件中。

但是,我看到控制台上打印了额外的不需要的信息。

我想将以下输出同时输出到控制台和文件:

INFO - thisuser executed the pipeline at 2019-04-17 13:44:50,626
default log message
other default log message
INFO - pipeline execution completed at 2019-04-17 13:44:50,627
INFO - total time elapsed: 100.4 minutes

我在文件中得到了预期的输出,但控制台输出如下:

INFO:start_log:thisuser
INFO - thisuser executed the pipeline at 2019-04-17 13:44:50,626
INFO:root:default log message
default log message
INFO:root:other default log message
other default log message
INFO:end_log:-
INFO - pipeline execution completed at 2019-04-17 13:44:50,627
INFO:duration_log:100.4
INFO - total time elapsed: 100.4 minutes

我想删除打印到控制台的额外信息(上面的奇数行)。任何帮助将不胜感激!

下面是我的代码 运行:

import logging
import getpass

class DispatchingFormatter:

    def __init__(self, formatters, default_formatter):
        self._formatters = formatters
        self._default_formatter = default_formatter

    def format(self, record):
        formatter = self._formatters.get(record.name, self._default_formatter)
        return formatter.format(record)

logging.basicConfig(level=logging.INFO)

formatter = DispatchingFormatter({
        'start_log': logging.Formatter('%(levelname)s - %(message)s executed the pipeline at %(asctime)s'),
        'end_log': logging.Formatter('%(levelname)s - pipeline execution completed at %(asctime)s'),
        'duration_log': logging.Formatter('%(levelname)s - total time elapsed: %(message)s minutes')
    },
    logging.Formatter('%(message)s'),
)


c_handler = logging.StreamHandler()
c_handler.setFormatter(formatter)
f_handler = logging.FileHandler('log.txt')
f_handler.setFormatter(formatter)

logging.getLogger().addHandler(c_handler)
logging.getLogger().addHandler(f_handler)

logging.getLogger('start_log').info(f'{getpass.getuser()}')

logging.info('default log message')
logging.info('other default log message')

logging.getLogger('end_log').info('-')
time_elapsed = 100.4
logging.getLogger('duration_log').info(f'{time_elapsed}')

管道将打印约 100 行信息(分析结果),我不想在任何日志记录级别前添加这些信息,因此我尝试使用多个格式化程序来实现。

我知道这是一个有点 hacky 的解决方案..如果有人有一般的改进建议,这也将不胜感激!

经过四处搜索 (Replace default handler of Python logger) and reading up more on the documentation (https://docs.python.org/3.7/library/logging.html#),我找到了一个可行的解决方案。

我正在向记录器的默认处理程序添加两个处理程序(一个打印到控制台,另一个打印到具有指定格式的文件),显然记录器的默认处理程序将那些我不想要的行打印到控制台.

一个解决方案(也许是一个 hacky 的解决方案)是首先通过执行以下操作清空处理程序:

logging.basicConfig(level=logging.INFO, filemode='w')

# Added two lines below to first empty out (remove original handler) handlers
root_logger = logging.getLogger()
root_logger.handlers = []

然后继续创建我想要的格式化程序对象并添加两个我想要的处理程序(与问题中的代码相同):

formatter = DispatchingFormatter({
    'start_log': logging.Formatter('%(levelname)s - %(message)s executed the pipeline at %(asctime)s', datefmt='%Y-%m-%d %H:%M:%S'),
    'end_log': logging.Formatter('%(levelname)s - pipeline execution completed at %(asctime)s', datefmt='%Y-%m-%d %H:%M:%S'),
    'duration_log': logging.Formatter('%(levelname)s - total time elapsed: %(message)s minutes')
},
logging.Formatter('%(message)s'),
)


c_handler = logging.StreamHandler()
c_handler.setFormatter(formatter)
f_handler = logging.FileHandler('log.txt', 'w+')
f_handler.setFormatter(formatter)

logging.getLogger().addHandler(c_handler)
logging.getLogger().addHandler(f_handler)

正如 logging.basicConfig 的文档所述:

Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the root logger.

所以已经附加了一个流处理程序。您可以通过调用删除它:

logging.getLogger().handlers.clear()

在添加其他处理程序之前。

或者您可以使用 logging.getLogger().setLevel(logging.INFO) 而不是 basicConfig。在这种情况下,您不必清除处理程序,因为它们默认附加 none。