AWS Lambda连续调用2次时Python代码日志重复问题排查
解决AWS Docker化Python Lambda日志重复问题
问题根源
你遇到的日志重复问题,核心是Python logging模块的单例特性结合Lambda执行环境复用机制导致的:
- Python的
logging.getLogger('my_name')会返回同一个单例实例,不会每次调用都新建 - Lambda在冷启动后会复用执行环境,连续调用时会复用之前的环境
- 你的
make_logger()函数如果每次调用都给同一个logger实例添加新的日志处理器(Handler),就会导致每条日志被多个处理器重复输出,出现业务日志重复、系统日志正常的现象 - 重试场景下重复次数增加,是因为每次重试都在同一个环境中给logger添加了新的处理器,累积的处理器越多,日志重复次数就越多
解决方案
方案1:避免重复添加日志处理器
修改make_logger()函数,添加判断逻辑,仅在logger没有处理器时才进行配置:
def make_logger(): logger = logging.getLogger('my_name') # 关键:检查是否已有处理器,避免重复添加 if not logger.handlers: # 替换成你原本的logger配置代码 formatter = logging.Formatter('{"message": "%(message)s"}') stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) logger.addHandler(stream_handler) logger.setLevel(logging.INFO) # 禁止向父级logger传递日志,避免额外重复 logger.propagate = False return logger
方案2:全局初始化logger
利用Lambda执行环境的初始化特性,把logger的配置放在handler函数之外,冷启动时仅执行一次,热复用环境不会重复执行:
# 全局区域:冷启动时执行一次,后续复用环境不会重复运行 logger = logging.getLogger('my_name') # 配置logger formatter = logging.Formatter('{"message": "%(message)s"}') stream_handler = logging.StreamHandler() stream_handler.setFormatter(formatter) logger.addHandler(stream_handler) logger.setLevel(logging.INFO) logger.propagate = False def handler(event, context): logger.info("starting to do something") message = json.loads(event['Records'][0]['body']) # 业务逻辑代码 logger_adapter = logging.LoggerAdapter(logger, message) logger_adapter.info("another log message with context data in it")
补充说明
你提到的"连续调用2次重复,3次及以上正常",大概率是因为第三次调用时Lambda销毁了之前的复用环境,重新冷启动了新环境,此时logger只有一个处理器,日志正常输出。但这是环境回收的随机行为,不能依赖,必须通过代码修复。
内容的提问来源于stack exchange,提问作者senaps
相关产品推荐
相关产品推荐

