优化Python日志代码

时间:2013-05-16 18:38:35

标签: python logging pyramid

我在Pyramid框架上编写了一个Python应用程序。

我们真的利用标准导入库来登录(用于调试)。

当我们对生产进行分析时,我们的日志活动似乎有相当多的开销。所有的字符串格式和循环加起来。我想删除它,但我们不能 - 我们确实需要将其保留用于测试,有时需要在生产环境中进行调试。

我想知道是否有人根据需要有最小化日志记录的有效策略,因此这些代码可以在我们的生产环境执行期间“优化掉”而不会运行。

例如,在mod_perl下,编译器将“优化”在False常量下运行的语句

在psuedocode中...(我很久没有碰过perl了!)

use constant DEBUG => False ;
if ( DEBUG ) {
      log.debug("stuff here " + string );
}

use constant DEBUG => False ;
DEBUG && log.debug("stuff here " + string );

在这些情况下,调用log.debug甚至字符串插值都不会发生。

有人可以推荐一种在Python下模仿这种行为的有效方法吗?

3 个答案:

答案 0 :(得分:7)

当您可以使用log.debug('stuff here %s', string)时,请勿使用连接;记录模块推迟插值,直到记录时实际格式化字符串。如果已禁用DEBUG日志级别,则不会进行插值。

您还可以测试日志记录级别,以避免收集昂贵的日志记录信息,除非需要:

if logger.isEnabledFor(logging.DEBUG):
    logger.debug('Message with %s, %s', expensive_func1(),
                                        expensive_func2())

请参阅optimization section of the Logging HOWTO

答案 1 :(得分:6)

使用__debug__。当Python使用False命令行标志运行时,此标志设置为-O,Python将在编译时优化调试代码。 I wrote a blog post on it几个月前。

答案 2 :(得分:0)

我建议将assert用于此目的,因为它在优化模式下很好地进行了优化。

在这种情况下,无需手动检查是否启用了日志记录级别。这在执行可用于日志记录的昂贵格式化操作时非常有用(例如使用pprint模块)。

一个例子:

而不是

logging.debug('my message %s', pprint.pformat(mycomplexdata))

你会写

assert(logging.debug('my message %s', pprint.pformat(mycomplexdata)) or True)

(部分or True确保断言不会失败。)

在这种情况下甚至可以使用.format而不会因使用-O而造成性能损失。

assert(logging.debug('my message {}'.format(pprint.pformat(mycomplexdata))) or True)

使用-O运行python时,assert()中的所有内容都被优化了。