使用带有AWS Lambda的python日志记录

p.m*_*aes 38 python logging amazon-web-services aws-lambda

正如AWS文档所示:

import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def my_logging_handler(event, context):
    logger.info('got event{}'.format(event))
    logger.error('something went wrong')
Run Code Online (Sandbox Code Playgroud)

现在我做了:

import logging
logging.basicConfig(level = logging.INFO)
logging.info("Hello World!")
Run Code Online (Sandbox Code Playgroud)

第一段代码在Cloud Watch控制台中打印,但第二段没有.

我没有看到任何差异,因为两个片段正在使用根记录器.

Bre*_*tty 40

直接从问题的顶部答案复制@StevenBohrer的答案链接(这对我来说很有用,用我自己的配置替换最后一行):

root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

  • 从 python 3.8 开始,有一个新参数“force”,它的作用与上面描述的完全一样:“logging.basicConfig(level =logging.INFO,force=True)”。https://docs.python.org/3/library/logging.html#logging.basicConfig (27认同)
  • 谢谢,这很棒。我把它放在我的导入语句之后,然后我的整个 lambda/模块可以访问我自己的个人记录器 :) 在 basicConfig 之后添加这一行:logger = logging.getLogger() (3认同)

小智 16

我遇到了类似的问题,我怀疑lambda容器在导入lambda代码之前调用logging.basicConfig来添加处理程序.这似乎是糟糕的形式......

解决方法是查看是否已配置root logger处理程序,如果已配置,请删除它们,添加格式化程序和所需的日志级别(使用basicConfig),然后还原处理程序.

在运行logging.basicConfig之前,请参阅此文章Python日志记录?


Kin*_*man 16

我一直在努力解决这个确切的问题。适用于本地和 AWS CloudWatch 的解决方案是设置您的日志记录,如下所示:

import logging

# Initialize you log configuration using the base class
logging.basicConfig(level = logging.INFO)

# Retrieve the logger instance
logger = logging.getLogger()

# Log your output to the retrieved logger instance
logger.info("Python for the win!")

Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用。必须使用OP发布的第一个块代码。 (4认同)
  • 本地日志记录按预期工作。除非出现错误,否则无法在 cloudwatch 上看到日志。 (2认同)

Vij*_*ian 11

这取决于aws lambda python version

如果python版本3.8及以上

import os
import logging

default_log_args = {
    "level": logging.DEBUG if os.environ.get("DEBUG", False) else logging.INFO,
    "format": "%(asctime)s [%(levelname)s] %(name)s - %(message)s",
    "datefmt": "%d-%b-%y %H:%M",
    "force": True,
}


logging.basicConfig(**default_log_args)
log = logging.getLogger("Run-Lambda")

log.info("I m here too)

Run Code Online (Sandbox Code Playgroud)

如果python版本3.7及以下

import os
import logging

root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)

default_log_args = {
    "level": logging.DEBUG if os.environ.get("DEBUG", False) else logging.INFO,
    "format": "%(asctime)s [%(levelname)s] %(name)s - %(message)s",
    "datefmt": "%d-%b-%y %H:%M"
}

logging.basicConfig(**default_log_args)
log = logging.getLogger("Run-Lambda")

log.info("Iam here")

Run Code Online (Sandbox Code Playgroud)

  • @weberc2 日志的数量非常昂贵,可能会导致意外的 PII 泄漏,默认情况下,人们不希望在 python 中杀死任何记录器(编码器的选择)。 (2认同)

Pit*_*Pit 7

日志似乎无法正常运行的原因是,AWS Lambda Python运行时预先配置了日志处理程序该日志处理程序可能会根据所选择的运行时版本来修改所记录消息的格式,并且还会向其中添加一些元数据。记录(如果有)。什么是,虽然预配置是日志级别。这意味着无论您尝试发送的日志消息的类型如何,它实际上都不会打印。

AWS文档本身时,要logging在AWS Lambda上下文中正确使用该库,您只需为root-logger设置日志级别:

import logging
logging.getLogger().setLevel(logging.INFO)
Run Code Online (Sandbox Code Playgroud)

如果您希望Python脚本既可以在AWS Lambda上执行,又可以在本地Python解释器上执行,则可以检查是否配置了处理程序,然后退回到basicConfig(创建默认的stderr-handler):

if len(logging.getLogger().handlers) > 0:
    # The Lambda environment pre-configures a handler logging to stderr. If a handler is already configured,
    # `.basicConfig` does not execute. Thus we set the level directly.
    logging.getLogger().setLevel(logging.INFO)
else:
    logging.basicConfig(level=logging.INFO)
Run Code Online (Sandbox Code Playgroud)

  • 使用“logging.getLogger().hasHandlers()”而不是“len(logging.getLogger().handlers) > 0”可能会更好。 (7认同)
  • 对于 python < 3.2,“iflogging.getLogger().handlers:”怎么样?读起来与 3.2+ 版本类似,并且更惯用。 (4认同)
  • 你说得对。我应该添加“for Python 3.2+”:) (3认同)
  • @ebk 这是一个非常好的观点,但是 `hasHandlers` 仅从 Python 3.2 开始可用。由于 [AWS 仍然支持 Python 2.7 运行时](https://aws.amazon.com/blogs/compute/continued-support-for-python-2-7-on-aws-lambda/),因此使用 `len(. ..handlers)`是目前最便携的解决方案。 (2认同)

HEA*_*0NE 5

实际上,可能没有引用同一个记录器。在第一个片段中,记录以下返回:logging.Logger.manager.loggerDict

它将返回dict已初始化的记录器。

另外,从logging文档中,有一个重要说明logging.basicConfig

通过使用默认格式化程序创建 StreamHandler 并将其添加到根记录器,对日志记录系统进行基本配置。如果没有为根记录器定义处理程序,则函数 debug()、info()、warning()、error() 和 critical() 将自动调用 basicConfig()。

如果根记录器已为其配置了处理程序,则此函数不会执行任何操作。

来源:https://docs.python.org/2/library/logging.html#logging.basicConfig