延迟记录器消息字符串评估

延迟记录器消息字符串评估

本文介绍了延迟记录器消息字符串评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

导入日志logging.basicConfig(level=logging.INFO)logger = logging.getLogger("log")而真:logger.debug('愚蠢的日志消息" + ' '.join([str(i) for i in range(20)]) )# 做一点事

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

有什么解决办法吗?

在 C++ 中,我们有 log4cxx 包提供如下宏:
LOG4CXX_DEBUG(logger, message)
这有效地评估为

如果(log4cxx::debugEnabled(记录器)){log4cxx.log(记录器,log4cxx::LOG4CXX_DEBUG,消息)}

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

解决方案

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

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

... 而不是这个:

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

日志模块足够智能,不会生成完整的日志消息,除非消息确实被记录在某处.

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

类lazyjoin:def __init__(self, s, items):self.s = sself.items = 物品def __str__(self):返回 self.s.join(self.items)

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

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

这是一个演示,展示了这项工作.

>>>导入日志>>>logging.basicConfig(level=logging.INFO)>>>logger = logging.getLogger("log")>>>类 DoNotStr:... def __str__(self):... raise AssertionError("代码不应该调用这个")...>>>logger.info('消息 %s', DoNotStr())回溯(最近一次调用最后一次):...断言错误:代码不应该调用这个>>>logger.debug('消息 %s', DoNotStr())>>>

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

I'm using standard python logging module in my python application:

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

The issue is that although debug level is not enable, that stupid log message is evaluated on each loop iteration, which harms performance badly.

Is there any solution for this?

In C++ we have log4cxx package that provides macros like this:
LOG4CXX_DEBUG(logger, messasage)
That effectively evaluates to

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

But since there are no macros in Python (AFAIK), if there a efficient way to do logging?

解决方案

The logging module already has partial support for what you want to do. Do this:

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

... instead of this:

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

The logging module is smart enough to not produce the complete log message unless the message actually gets logged somewhere.

To apply this feature to your specific request, you could create a lazyjoin class.

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

Use it like this (note the use of a generator expression, adding to the laziness):

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

Here is a demo that shows this works.

>>> 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())
>>>

In the demo, The logger.info() call hit the assertion error, while logger.debug() did not get that far.

这篇关于延迟记录器消息字符串评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 17:00