优化Python日志代码



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

我们确实利用了日志记录(用于调试),使用标准导入库。

当我们在生产环境中分析东西时,似乎我们的日志记录活动带来了相当多的开销。所有的字符串格式化和循环加起来。我很想删除它,但是我们不能——我们确实需要保留它用于测试,并且有时需要在生产环境中进行调试。

我想知道是否有人有有效的策略来根据需要最小化日志记录,所以这段代码可以在我们的生产环境中执行时"优化掉",而根本不运行。

例如,在mod_perl下,编译器会"优化掉"在False constants

下运行的语句在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下模仿这种行为的有效方法?

使用__debug__。当Python使用-O命令行标志运行时,此标志被设置为False, Python将在编译时进一步优化我们的调试代码。几个月前我写了一篇关于它的博文。

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

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

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

请参阅Logging HOWTO的优化部分

我建议使用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()中的所有内容都被优化掉了。

最新更新