我是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中,我该怎么办?
答案 0 :(得分:3)
这是因为您的logger_3
默认情况下还propagates将事件记录到其父记录器(根记录器)。
如果您使用basicConfig()
,则根记录器默认会附加StreamHandler
,这会导致您的消息也会在控制台上结束。
要防止出现这种情况,您可以设置logger_3.propagate = False
,也可以只将处理程序直接附加到根记录程序(这是最常用的设置)并使用logging levels和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()
将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
,以防止记录到它们的消息冒泡到根记录器。