python - 惰性记录器消息字符串评估

标签 python logging

我在我的 python 应用程序中使用标准的 python 日志记录模块:

import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("log")
while True:
  logger.debug('Stupid log message " + ' '.join([str(i) for i in range(20)]) )
  # Do something

问题在于,虽然调试级别未启用,但在每次循环迭代时都会评估该愚蠢的日志消息,这会严重损害性能。

有什么解决办法吗?

在 C++ 中,我们有 log4cxx 包,它提供如下宏:
LOG4CXX_DEBUG(记录器,消息)
这有效地评估为

if (log4cxx::debugEnabled(logger)) {
    log4cxx.log(logger,log4cxx::LOG4CXX_DEBUG, message)
}

但是由于 Python (AFAIK) 中没有宏,是否有一种有效的方法来进行日志记录?

最佳答案

日志记录模块已经部分支持您想要执行的操作。这样做:

log.debug("Some message: a=%s b=%s", a, b)

... 而不是这个:

log.debug("Some message: a=%s b=%s" % (a, b))

日志记录模块足够聪明,不会产生完整的日志消息,除非该消息实际记录在某处。

要将此功能应用于您的特定请求,您可以创建一个lazyjoin 类。

class lazyjoin:
    def __init__(self, s, items):
        self.s = s
        self.items = items
    def __str__(self):
        return self.s.join(self.items)

像这样使用它(注意使用生成器表达式,增加了懒惰):

logger.info('Stupid log message %s', lazyjoin(' ', (str(i) for i in range(20))))

这是一个演示此工作的演示。

>>> import logging
>>> logging.basicConfig(level=logging.INFO)
>>> logger = logging.getLogger("log")
>>> class DoNotStr:
...     def __str__(self):
...         raise AssertionError("the code should not have called this")
... 
>>> logger.info('Message %s', DoNotStr())
Traceback (most recent call last):
...
AssertionError: the code should not have called this
>>> logger.debug('Message %s', DoNotStr())
>>>

在演示中,logger.info() 调用遇到了断言错误,而 logger.debug() 没有达到那么远。

关于python - 惰性记录器消息字符串评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4148790/

相关文章:

python - Postgresql 中的 RRULE 解析

Python模式匹配问题

Python:为什么迭代时序列的 __len__() 被忽略?

python - 如果值位于另一个数据帧中,如何从一个数据帧获取行

java - RollingFileAppender 如何与 log4j2 一起工作?

linux - Snort日志文件输出格式

python - Pandas 将小时和分钟列合并为时间

linux - 如何集中 rsyslogs 并用作 logstash 的输入?

c# - Log4Net 不记录(可能未初始化)

logging - 如何在TensorFlow摘要中添加任意值?