Python 参数中函数的日志记录开销

Rob*_*rtG 6 python logging

我正在使用 python 日志记录模块(python 3.4.3)。假设我的日志记录级别设置为 INFO,并且我想使用一个函数作为我的日志记录消息的参数。

现在我期望当日志级别降低(例如警告)时,参数函数不会被执行。

这是真的?

示例(控制台):

>>> import math
>>> import logging
>>> logging.basicConfig(level=logging.INFO)
>>> logging.debug('Factorial of 100000=',math.factorial(100000))
>>> */empty output but slightly delayed, small CPU peak/*
>>> logging.debug('Factorial of 10=',math.factorial(10))
>>> */empty output but instant, no noticeable CPU usage/*
Run Code Online (Sandbox Code Playgroud)

该函数可能没有执行,但仍然存在明显的延迟。有人可以向我解释一下可能的原因吗?

bak*_*kal 3

调用前的函数参数评估

好吧,您看到您传递给的参数需要在调用之前logging.debug('Factorial of 100000=', math.factorial(100000))进行评估,并且评估需要时间logging.debug()math.factorial(100000)

即使函数最终在调用中不执行任何操作也没关系,参数仍然会被求值

从概念上讲,你可以将其视为

value = math.factorial(100000)           # This gets evaluated
logging.debug('Factorial is %d', value)  # Even if this is a "no op" call, 
                                         # the arg evaluation still takes place
Run Code Online (Sandbox Code Playgroud)

解决方法

import math
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()

if logger.getEffectiveLevel() <= logging.DEBUG:    # Or use == if you want DEBUG only
    logger.debug('Factorial is %d', math.factorial(100000))
Run Code Online (Sandbox Code Playgroud)

使用Python 3的logger.getEffectiveLevel()

鉴于级别的排序为

CRITICAL    50
ERROR       40
WARNING     30
INFO        20
DEBUG       10
NOTSET      0
Run Code Online (Sandbox Code Playgroud)

你可以看到我们的 if 块(with <= logging.DEBUG)只会在(so和)DEBUG之上运行DEBUGNOTSET