我一直在尝试了解python中的日志记录。我有一个 init 模块,另外两个模块和一个主模块。由于某些原因,当我运行模块时,日志详细信息会跳过代码流,并在其他输出之前首先打印
有人可以告诉我为什么会这样吗
这是在__init__.py
from dir1.mod1 import FirstClass
from dir1.mod2 import SecondClass
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
f_handler=logging.FileHandler('python_logs.log')
f_handler.setLevel(logging.DEBUG)
c_handler = logging.StreamHandler()
c_handler.setLevel(logging.ERROR)
f_formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
c_formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
f_handler.setFormatter(f_formatter)
c_handler.setFormatter(c_formatter)
logger.addHandler(f_handler)
logger.addHandler(c_handler)
这是在其他两个模块中(写在resp类的__init__()
内
self.logger = logging.getLogger(__name__)
在模块之一内部定义的addn()函数的代码段
def addn(self):
z=self.x +self.y
print('sum is '+z)
self.logger.error('incrementing number!')
self.logger.info('Still incrementing number!!')
return z
我运行的主要模块具有以下功能:
from dir1.mod1 import FirstClass
from dir1.mod2 import SecondClass
number = FirstClass(2,2)
print('addition results')
number.addn()
我期望输出如下
添加结果
总和为3
dir1.mod1
-错误-递增数字!
但是我得到的是
dir1.mod1
-错误-递增数字!
dir1.mod1
-错误-递增数字!
附加结果:
总和为3
为什么首先打印的日志消息跳出代码流?还有谁能告诉我为什么日志消息要打印两次?
答案 0 :(得分:4)
U可以尝试禁用记录器的传播属性。
传播:如果此属性的值为true,则除了附加到此记录器的任何处理程序外,记录到该记录器的事件还将传递到更高级别(祖先)记录器的处理程序中。邮件直接传递给祖先记录器的处理程序-既不考虑所讨论祖先记录器的级别也没有过滤器。
这是一个初始化记录器的示例,该记录器使用具有不同调试级别的文件和标准输出:
def init_logger_singleton():
global logger
logger = logging.getLogger(name='loggerName')
logger.propagate = False
logger.setLevel(10)
formatter = logging.Formatter(
'\t%(message)s'
)
filehandler = logging.StreamHandler()
filehandler.setLevel(40)
filehandler.setFormatter(formatter)
logger.addHandler(filehandler)
我使用数字来定义日志级别,但是10 = DEBUG和40 = ERRO。有关更多信息,请访问this link.
答案 1 :(得分:3)
默认情况下,当您将打印语句发送到stdout时,Python StreamHandler将默认登录到stderr。这是两个不同的管道,不能保证它们之间的顺序。
通过将所有输出发送到同一管道来确保正确订购。例如,您可以在打印语句中添加file=sys.stderr
参数。
答案 2 :(得分:0)
您还可以将参数 sys.stdout
添加到您的流处理程序,因此 print
和记录器事件都将传递到一个通道。
stream_handler = logging.StreamHandler(sys.stdout)