将 Python 日志记录与 AWS Lambda 结合使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37703609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using python Logging with AWS Lambda
提问by p.magalhaes
As the AWS documentation suggests:
正如 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')
Now I made:
现在我做了:
import logging
logging.basicConfig(level = logging.INFO)
logging.info("Hello World!")
The first snippet of code prints in the Cloud Watch
console, but the second one no.
第一段代码打印在Cloud Watch
控制台中,但第二段没有。
I didn't see any difference as the two snippets are using the root logger.
我没有看到任何区别,因为这两个片段使用的是根记录器。
回答by Brett Beatty
Copied straight from the top answer in the question @StevenBohrer's answer links to (this did the trick for me, replacing the last line with my own config):
直接从问题@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)
回答by Pit
The reason that logging does not seem to work is because the AWS Lambda Python runtime pre-configures a logging handlerthat, depending on the version of the runtime selected, might modify the format of the message logged, and might also add some metadata to the record if available. What is notpreconfigured though is the log-level. This means that no matter the type of log-message you try to send, it will not actually print.
日志记录似乎不起作用的原因是因为 AWS Lambda Python 运行时预先配置了一个日志记录处理程序,根据所选运行时的版本,该处理程序可能会修改记录的消息的格式,并且还可能将一些元数据添加到如果可用,记录。什么是不,虽然预配置是日志级别。这意味着无论您尝试发送哪种类型的日志消息,它实际上都不会打印。
As AWS documents themselves, to correctly use the logging
library in the AWS Lambda context, you only need to set the log-level for the root-logger:
作为AWS 文档本身,要logging
在 AWS Lambda 上下文中正确使用库,您只需为 root-logger 设置日志级别:
import logging
logging.getLogger().setLevel(logging.INFO)
If you want your Python-script to be both executable on AWS Lambda, but also with your local Python interpreter, you can check whether a handler is configured or not, and fall back to basicConfig
(which creates the default stderr-handler) otherwise:
如果您希望 Python 脚本既可以在 AWS Lambda 上执行,也可以使用本地 Python 解释器,您可以检查是否配置了处理程序,否则返回到basicConfig
(创建默认的 stderr 处理程序):
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)
回答by Steven Bohrer
I had a similar problem, and I suspect that the lambda container is calling logging.basicConfig to add handlers BEFORE the lambda code is imported. This seems like bad form...
我遇到了类似的问题,我怀疑 lambda 容器正在调用 logging.basicConfig 以在导入 lambda 代码之前添加处理程序。这似乎是一种糟糕的形式......
Workaround was to see if root logger handlers were configured and if so, remove them, add my formatter and desired log level (using basicConfig), and restore the handlers.
解决方法是查看是否配置了根记录器处理程序,如果是,则删除它们,添加我的格式化程序和所需的日志级别(使用 basicConfig),然后恢复处理程序。
See this article Python logging before you run logging.basicConfig?
回答by HEADLESS_0NE
Probably not referencing the same logger, actually.
In the first snippet, log the return of: logging.Logger.manager.loggerDict
实际上,可能没有引用同一个记录器。在第一个片段中,记录返回:logging.Logger.manager.loggerDict
It will return a dict
of the loggers already initialized.
它将返回一个dict
已经初始化的记录器。
Also, from the logging
documentation, an important note on logging.basicConfig
:
此外,从logging
文档中,有一个重要的注意事项logging.basicConfig
:
Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the root logger. The functions debug(), info(), warning(), error() and critical() will call basicConfig() automatically if no handlers are defined for the root logger.
This function does nothing if the root logger already has handlers configured for it.
通过创建带有默认格式化程序的 StreamHandler 并将其添加到根记录器,为日志记录系统进行基本配置。如果没有为根记录器定义处理程序,函数 debug()、info()、warning()、error() 和 critical() 将自动调用 basicConfig()。
如果根记录器已经为其配置了处理程序,则此函数不执行任何操作。
Source: https://docs.python.org/2/library/logging.html#logging.basicConfig
来源:https: //docs.python.org/2/library/logging.html#logging.basicConfig
回答by Kinman
I've struggled with this exact problem. The solution that works both locally and on AWS CloudWatch is to setup your logging like this:
我一直在努力解决这个确切的问题。适用于本地和 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!")
回答by Edward Z. Yang
Essentially, the AWS logging monkey patch needs to be handled in a very particular way, where:
从本质上讲,AWS 日志猴子补丁需要以一种非常特殊的方式进行处理,其中:
- The log level is set from the TOP level of the script (e.g., at import time)
- The log statements you are interested in are invoked from within the lambda function
- 日志级别从脚本的 TOP 级别设置(例如,在导入时)
- 您感兴趣的日志语句是从 lambda 函数中调用的
Since it's generally considered good form not to run arbitrary code in Python module import, you usually should be able to restructure your code so that the heavy lifting occurs only inside the lambda function.
由于在 Python 模块导入中不运行任意代码通常被认为是一种很好的形式,因此您通常应该能够重构代码,以便仅在 lambda 函数内部进行繁重的工作。