python登录到多个目的地

时间:2015-02-16 23:47:43

标签: python logging

我是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提供了写入文件的处理程序。

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

2 个答案:

答案 0 :(得分:3)

这是因为您的logger_3默认情况下还propagates将事件记录到其父记录器(根记录器)。

如果您使用basicConfig(),则根记录器默认会附加StreamHandler,这会导致您的消息也会在控制台上结束。

要防止出现这种情况,您可以设置logger_3.propagate = False,也可以只将处理程序直接附加到根记录程序(这是最常用的设置)并使用logging levelsfilters来控制输出的位置。


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

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()StreamHandler级别INFO附加到记录到stdout的根记录程序 - 但仅包含级别为INFO or higher的邮件。

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

如果您需要更精细的控制,例如,您可以在日志记录时传递extra keyword argument中的一些数据,并将add a filter传递给任何处理程序,以仅发出符合特定条件的邮件。

但是,如果您只是希望能够直接从代码中控制某个特定消息应该转到文件,而只是该文件,那么将logger_3.propagate设置为“{1}}可能最简单False,并使用您已描述的设置。

答案 1 :(得分:1)

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