Python使用structlog记录日志出现内存泄漏的配置问题咨询
structlog多线程场景内存泄漏解决方案
核心原因及对应配置修正
1. 线程本地存储(TLS)上下文缓存未回收
structlog默认会为每个线程维护独立的上下文缓存,若业务频繁创建销毁线程、或重复传入大体积字典作为额外日志参数,旧线程的缓存数据不会被主动回收,会产生持续内存增长。
可通过以下配置修复:
import structlog structlog.configure( # 核心配置1:使用无持久缓存的字典作为上下文存储类 context_class=structlog.threadlocal.wrap_dict(dict), # 核心配置2:关闭logger实例缓存,避免动态创建的logger实例残留 cache_logger_on_first_use=False, processors=[ # 其他你的业务所需的处理器,比如上下文合并、格式化等 structlog.contextvars.merge_contextvars, structlog.processors.JSONRenderer() ] )
2. 低级别日志提前过滤未开启
你当前调用的是debug级别的日志,若全局日志级别高于debug,默认逻辑会先序列化所有传入的额外参数(包括observation大字典)后再执行级别过滤,序列化产生的临时对象会残留未释放。
可在处理器列表最开头新增级别过滤逻辑,参数未序列化前直接丢弃不满足级别的日志:
structlog.configure( processors=[ # 放在处理器列表第一位,提前过滤低级别日志 structlog.stdlib.filter_by_level, # 其余原有处理器保持不变 ] )
临时代码优化方案
如果不改动全局配置,也可以直接调整调用代码,避免大字典被绑定到上下文存储:
# 将observation转为字符串直接写入日志内容,不通过额外参数传递 logger.debug("RANGEB obs {}/{},observation={}".format(i + 1, obs_cnt, str(observation)))
效果验证
调整后重复运行压测,统计1000次以上日志调用的内存占用,确认内存不会持续线性增长即修复完成。
内容的提问来源于stack exchange,提问作者Manuel Yguel
相关产品推荐
相关产品推荐

