AWS Cloudwatch 从一次日志调用中记录多次

AWS Cloudwatch Logs Multiple Times from single log call

我在另一个使用 Python 内置日志库的日志库之上编写了一个包装日志库。下面是一个片段。

import logging


class Foo(Bar):
    def __init__(self):
        self.logger.propagate = False
        ...

    def info(self, msg, *args, **kwargs):
        ...
        super().info(msg, *args, **kwargs)
    
class Bar:
    def __init__(self):
        self.logger = logging.getLogger("logger name")

    def info(self, msg, *args, **kwargs):
        ...
        self.logger.info(msg, *args, **kwargs)

### In handler.py ###
def lambda_handler(event, context):
    foo = Foo()
    foo.info("my msg")

然而,当我在 AWS Lambda 中使用 Foo 时,我最终得到了多个日志,如下所示:

我知道最后的 [INFO] 日志来自 AWS,但为什么我的日志仍然被输出 2 次?我按照其他问题的建议设置了propagate = False,但似乎没有效果。

导致我的错误的原因有点像一场完美风暴。首先,众所周知,AWS Lambda 实例将继续 运行,即使在处理请求后也是如此。这会导致一些已创建对象的持久化,特别是 logger.

我后来发现这个 question 它告诉我每次调用 logging.getLogger(...) 时,我都在向 添加一个 处理程序 记录器。然后,这些 处理程序 中的每一个都将继续创建一个日志行,从而产生多个日志行。

我不确定处理这个问题的正确方法,因为解决方案要求我每次都清除所有 处理程序 并创建我自己的处理程序,我不赞成这样做因为我不了解 loggerhandler.

的内部工作原理

最后,我做了以下操作以确保我只有一个 handler:

class Foo(Bar):
    def __init__(self):
        self.logger.propagate = False
        self.logger.handlers = self.logger.handlers[:1] # add this line
        ...

    def info(self, msg, *args, **kwargs):
        ...
        super().info(msg, *args, **kwargs)