python 记录到多个目的地

python logging to multiple destination

我是 Python 的新手。我现在需要使用日志记录,这是我做的实验:

我有 2 个文件:

logtest_1.py, logtest_2.py

logtest_1.py:

    import logging
    from logtest_2 import loglib

    format = '%(asctime)s: %(levelname)s: %(message)s'
    logging.basicConfig(format=format,level=logging.DEBUG)
    logger = logging.getLogger(__name__)
    logger.info('Before calling loglib...')
    loglib()
    logger.info('Loglib done.')

logtest_2.py: 导入日志 从 logging.handlers 导入 TimedRotatingFileHandler 导入时间

def loglib():
    logger_2 = logging.getLogger(__name__)

    logger_3 = logging.getLogger('TimeRotateLogger')
    logger_3.setLevel(logging.DEBUG)
    handler = TimedRotatingFileHandler('timerotate.log',
                                        when='s',
                                        interval=2,
                                        backupCount=10)
    logger_3.addHandler(handler)

    logger_2.info('This is a log from logtest_2.')

    time.sleep(1)
    for i in range(5):
        logger_3.info('Rotation test...')
        time.sleep(2)

我尝试使用 logger_3 将信息写入那些时间轮换文件。实际上,这是有效的。但是,它也会打印到屏幕上:

2015-02-16 15:26:34,010: INFO: Before calling loglib...
2015-02-16 15:26:34,011: INFO: This is a log from logtest_2.
2015-02-16 15:26:35,019: INFO: Rotation test...
2015-02-16 15:26:37,029: INFO: Rotation test...
2015-02-16 15:26:39,039: INFO: Rotation test...
2015-02-16 15:26:41,049: INFO: Rotation test...
2015-02-16 15:26:43,059: INFO: Rotation test...
2015-02-16 15:26:45,070: INFO: Loglib done.

我只想 logger_3 登录这些文件。如何防止它打印到屏幕上?

另外,为什么会这样?我已经将处理程序提供给 logger_3 写入文件。

如果我真的想在logtest_1.py中保留logging.basicConfig(format=format,level=logging.DEBUG),我该怎么办?

参见Logger.propagate。在您的子模块记录器上将其设置为 False 以防止记录到它们的消息也冒泡到您的根记录器。

发生这种情况是因为您的 logger_3 默认情况下还 propagates 将事件记录到其父记录器,即根记录器。

如果您使用 basicConfig(),默认情况下根记录器将附加一个 StreamHandler,这会导致您的消息也最终出现在控制台上。

为了防止这种情况,您可以设置 logger_3.propagate = False,或者只将处理程序直接附加到您的根记录器(这是最常用的设置)并使用 logging levels and filters 来控制输出的位置.


仅将处理程序附加到根记录器的示例如下所示:

import logging
from logging.handlers import TimedRotatingFileHandler


format = '%(asctime)s: %(levelname)s: %(message)s'
logging.basicConfig(format=format, level=logging.INFO)
logger = logging.getLogger(__name__)

handler = TimedRotatingFileHandler('timerotate.log',
                                   when='s',
                                   interval=2,
                                   backupCount=10)
handler.setLevel(logging.DEBUG)
logging.root.addHandler(handler)

logger.info('This will end up on console and in timerotate.log')
logger.debug('This will only end up in timerotate.log')

basicInfo() 将级别为 INFOStreamHandler 附加到记录到 stdout 的根记录器 - 但仅限级别为 INFO or higher 的消息。

然后您附加第二个级别为 DEBUG 的处理程序,因此它会将级别为 DEBUG 或更高级别的每条消息记录到 timerotate.log。这是一个非常简单的示例,它使用不同的日志级别来确定输出的最终位置 - 使用这种方法,您不能将特定语句 only 发送到控制台,而另一个 到一个文件。

如果您需要更细粒度的控制,例如,您可以将 extra keyword argument when logging, and add a filter 中的一些数据传递给您的任何处理程序,以仅发出符合特定条件的消息。

但是,如果您只是希望能够直接从您的代码中控制特定消息应该发送到一个文件,并且只发送到该文件,那么简单地将 logger_3.propagate 设置为 [= 可能是最简单的方法25=],并使用您已经描述的设置。