我试图在使用两个记录器对象之前和之后使用打印功能,这两个记录器对象会将输出流式传输到控制台。事情是我得到了一个非常混乱的输出,它的输出顺序不正确。
我尝试将print()更改为logger_object.info(),并且按预期工作。
带有意外输出的完整代码:
import logging
# Create logger objects and set level
loggerA = logging.getLogger()
loggerA.setLevel(logging.DEBUG)
loggerB = logging.getLogger()
loggerB.setLevel(logging.DEBUG)
# Set log output format
log_format = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s', datefmt='%m/%d/%Y - %I:%M:%S %p')
# Create a console stream handler
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(log_format)
# Add handlers to the loggers
loggerA.addHandler(stream_handler)
loggerB.addHandler(stream_handler)
def main():
for i in range(10):
print('Starting loop number {}'.format(i))
loggerA.info("loop number {}".format(i))
loggerB.info("loop number {}".format(i))
print('Finished loop number {}'.format(i))
if __name__ == '__main__':
main()
添加loggerC对象以用loggerC.info()替换print():
...
loggerC = logging.getLogger()
loggerC.setLevel(logging.DEBUG)
...
def main():
for i in range(10):
loggerC('Starting loop number {}'.format(i))
loggerA.info("loop number {}".format(i))
loggerB.info("loop number {}".format(i))
loggerC('Finished loop number {}'.format(i))
...
使用print()意外输出的第一种情况是:
04/06/2019 - 10:10:34 AM - INFO - loggerA - loop number 1
Starting loop number 1
04/06/2019 - 10:10:34 AM - INFO - loggerB - loop number 1
04/06/2019 - 10:10:34 AM - INFO - loggerA - loop number 2
04/06/2019 - 10:10:34 AM - INFO - loggerB - loop number 2
Finished loop number 1
Starting loop number 2
Finished loop number 2
Starting loop number 3
Finished loop number 3
04/06/2019 - 10:10:34 AM - INFO - loggerA - loop number 3
04/06/2019 - 10:10:34 AM - INFO - loggerB - loop number 3
第二种情况是使用loggerC.info()而不是print(),这是预期的输出:
04/06/2019 - 10:12:21 AM - INFO - loggerC - Starting loop number 1
04/06/2019 - 10:12:21 AM - INFO - loggerA - loop number 1
04/06/2019 - 10:12:21 AM - INFO - loggerB - loop number 1
04/06/2019 - 10:12:21 AM - INFO - loggerC - Finished loop number 1
04/06/2019 - 10:12:21 AM - INFO - loggerC - Starting loop number 2
04/06/2019 - 10:12:21 AM - INFO - loggerA - loop number 2
04/06/2019 - 10:12:21 AM - INFO - loggerB - loop number 2
04/06/2019 - 10:12:21 AM - INFO - loggerC - Finished loop number 2
04/06/2019 - 10:12:21 AM - INFO - loggerC - Starting loop number 3
04/06/2019 - 10:12:21 AM - INFO - loggerA - loop number 3
04/06/2019 - 10:12:21 AM - INFO - loggerB - loop number 3
04/06/2019 - 10:12:21 AM - INFO - loggerC - Finished loop number 3
您发出的问题可能是标准流的问题。默认情况下print
使用std::out
和logger.info
使用std::err
。这两个流都绑定到您的终端,但是它们可能具有不同的flush
刷新或触发器。
这就是为什么您的输出混合在一起,函数写入不同的流,并且将它们以不同的方式刷新到终端的原因,从而导致明显的不一致结果。
更改您的第一个代码以强制logger.info
使用相同的流而不是print
解决问题:
import sys
stream_handler = logging.StreamHandler(sys.stdout)
现在,它返回正确的输出:
-- Starting loop number 0
04/06/2019 - 07:41:34 AM - INFO - root - loop number 0
04/06/2019 - 07:41:34 AM - INFO - root - loop number 0
-- Finished loop number 0
-- Starting loop number 1
04/06/2019 - 07:41:34 AM - INFO - root - loop number 1
04/06/2019 - 07:41:34 AM - INFO - root - loop number 1
-- Finished loop number 1
-- Starting loop number 2
04/06/2019 - 07:41:34 AM - INFO - root - loop number 2
04/06/2019 - 07:41:34 AM - INFO - root - loop number 2
-- Finished loop number 2
-- Starting loop number 3
04/06/2019 - 07:41:34 AM - INFO - root - loop number 3
04/06/2019 - 07:41:34 AM - INFO - root - loop number 3
-- Finished loop number 3
因为无论print
并且logger.info
无论何时在被刷新到终端的正确顺序供给相同的流,结果是正确的。
def main():
for i in range(10):
print('-- Starting loop number {}'.format(i))
# Force std::out stream (fed by print) to be flushed to the terminal
# before logger feeds std::err and also flushes
sys.stdout.flush()
loggerA.info("loop number {}".format(i))
loggerB.info("loop number {}".format(i))
print('-- Finished loop number {}'.format(i))
sys.stdout.flush()
第二个版本也产生了预期的结果。
还请记住,logger
从定义上讲不是线程安全的,但print
不是。如果要使用线程制作模块,则仅用于logger
跟踪执行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句