如何配置Loguru避免低级别日志语句的执行?
我需要在开发与生产环境使用不同日志级别,程序初期设置了日志最低级别,代码如下:
import sys from loguru import logger as log log.remove() #移除旧处理器,否则新旧处理器会同时生效 log.add(sys.stdout, level="INFO") log.debug(f"Spark.Dataframe.count(): {df.count()}") #此行为关注点 log.info("info message") log.warning("warning message") log.error("error message")
当日志仅为字符串时资源消耗低,但所有日志语句都会执行,仅符合级别要求的才会输出。其中log.debug(df.count())中的df.count()是Spark DataFrame行数统计,在生产环境处理大数据集时属于昂贵操作,我不希望每次运行都执行该语句。
请问如何配置Loguru,让指定日志语句仅在日志级别符合设置时才执行?是否必须通过全代码添加if条件判断来控制?Loguru是否支持通过级别设置避免日志消息内容的执行,同时保持日志代码的简洁性?设置INFO级别后,我期望避免log.debug(昂贵操作)的执行时间,而非执行后再被过滤。
解决方案
不需要全量添加if条件判断,Loguru提供了简洁的惰性求值方式来解决这个问题:
1. 使用Lambda表达式实现惰性求值
将昂贵操作包裹在lambda表达式中传递给日志方法,Loguru会仅在当前日志级别满足该语句的级别要求时,才执行lambda内的代码。修改后的代码如下:
log.debug(lambda: f"Spark.Dataframe.count(): {df.count()}")
当日志级别设置为INFO时,这条debug级别的日志不会被触发,lambda表达式不会被调用,df.count()也就不会执行,完全避免了昂贵操作的资源消耗。
2. 手动级别判断(可选)
如果偏好更直观的条件判断方式,也可以直接检查当前日志的最低级别,但这种方式代码量稍多,且需要访问Loguru内部属性,不如lambda方式优雅:
if log.level("DEBUG").no() <= log._core.min_level: log.debug(f"Spark.Dataframe.count(): {df.count()}")
总结
Loguru支持通过惰性求值机制避免低级别日志中昂贵操作的执行,使用lambda表达式就能保持代码简洁,无需全量添加if判断,完美实现“级别不满足时不执行日志内容”的需求。
内容的提问来源于stack exchange,提问作者Cristian C. Bittel

