简体   繁体   English

是否可以在运行时更改 AWS Lambda 的日志级别?

[英]Is it possible to change the log level of an AWS Lambda at runtime?

I'm running a lamba on AWS, and using slf4j for logging我在 AWS 上运行 Lamba,并使用 slf4j 进行日志记录

Part of the project requirements is that the log level can be set at runtime, using an environment variable, but I'm not sure if that's possible项目要求的一部分是可以在运行时设置日志级别,使用环境变量,但我不确定这是否可能

I'm using the following code, but changing the environment variable "LOG_LEVEL" in the UI to "DEBUG" has no effect to what is added to the CloudWatch logs.我正在使用以下代码,但将 UI 中的环境变量“LOG_LEVEL”更改为“DEBUG”对添加到 CloudWatch 日志的内容没有影响。 Is this possible?这可能吗?

import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyLambdaHandler implements RequestHandler<Integer, String> {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyLambdaHandler.class);

    static {
        org.apache.log4j.Logger rootLogger = LogManager.getRootLogger();
        String logLevel = (System.getenv("LOG_LEVEL") != null) ? System.getenv("LOG_LEVEL") : "INFO";
        rootLogger.setLevel(Level.toLevel(logLevel));
    }

    public String myHandler(int myCount, Context context) {

        LOGGER.debug("Entering myHandler lambda handler";
        LOGGER.info("Handling myCount {}", myCount);
        int returnValue = myCount * 2;
        LOGGER.debug("MyHandler return value {}", returnValue);
        return returnValue;

    }

}

Yes it's possible!是的,这是可能的! You need to take care of two things:你需要注意两件事:

  • One, update your lambda environment variable一、更新你的lambda环境变量
  • Two, ensure that log4j will pick up the update二、确保log4j会拾取更新

For the first problem, all you need to do is pass a lambda environment variable with name JAVA_TOOL_OPTIONS and value "-DLOG_LEVEL=DEBUG" .对于第一个问题,您需要做的就是传递一个名为JAVA_TOOL_OPTIONS且值为"-DLOG_LEVEL=DEBUG"的 lambda 环境变量。

For the second point, you can add this to your Java project src/main/resources/log4j.properties with content something like对于第二点,您可以将其添加到您的 Java 项目src/main/resources/log4j.properties ,内容类似于

log4j.rootCategory=${LOG_LEVEL}, LAMBDA
LOG_LEVEL_PATTERN=%5p
LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] boot%X{context} ${LOG_LEVEL_PATTERN} [%t] - %c{1}: %m%n
log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender
log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout
log4j.appender.LAMBDA.layout.conversionPattern=${LOG_PATTERN}

And that's it!就是这样!

If everything goes well you should soon see in your logs a line reading something like如果一切顺利,您应该很快就会在日志中看到一行内容,例如

Picked up JAVA_TOOL_OPTIONS: -DLOG_LEVEL=DEBUG

and hopefully start seeing some debug statements.并希望开始看到一些调试语句。

Notice how LOG_LEVEL is embedded in the value of the lambda variable as opposed to being the variable name.请注意LOG_LEVEL如何嵌入到 lambda 变量的值中,而不是作为变量名称。 This is a useful indirect way to feed JVM arguments down a lambda which you can then use as system properties.这是一种将 JVM 参数提供给 lambda 的有用的间接方法,然后您可以将其用作系统属性。 Kudos to https://zenidas.wordpress.com/recipes/system-properties-for-a-java-lambda-function/感谢https://zenidas.wordpress.com/recipes/system-properties-for-a-java-lambda-function/

I was able to resolve this by using the amazon version of log4j2, and making a change to the log4j2.xml configuration file Add these dependencies to maven我能够通过使用 log4j2 的亚马逊版本解决这个问题,并对 log4j2.xml 配置文件进行更改将这些依赖项添加到 maven

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-log4j2</artifactId>
    <version>1.1.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.11.2</version>
</dependency>

use the environment variable in the level of the logger in the configuration在配置中使用logger级别的环境变量

<?xml version="1.0" encoding="UTF-8"?>
<Configuration
    packages="com.amazonaws.services.lambda.runtime.log4j2">
    <Appenders>
        <Lambda name="Lambda">
            <PatternLayout>
                <pattern>%d{yyyy-MM-dd HH:mm:ss} %X{AWSRequestId} %-5p %c{1}:%L - %m%n</pattern>
            </PatternLayout>
        </Lambda>
    </Appenders>
    <Loggers>
        <Root level="${env:LOG_LEVEL}">
            <AppenderRef ref="Lambda" />
        </Root>
    </Loggers>
</Configuration>

finally, use the log4j2 logger in the lambda itself最后,在 lambda 本身中使用 log4j2 记录器

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class MyLambdaHandler implements RequestHandler<Void, Void> {

    private static final Logger LOGGER = LogManager.getLogger(MyLambdaHandler .class);

    public Void handleRequest(Void myVoid, Context context) {

        LOGGER.error("Log info enabled: {}", LOGGER.isInfoEnabled());
        LOGGER.info("Info messge");
        LOGGER.error("Log error enabled: {}",  LOGGER.isErrorEnabled());
        LOGGER.error("Error Message");
        LOGGER.error("Log trace enabled: {}",  LOGGER.isTraceEnabled());
        LOGGER.trace("trace message");
        LOGGER.error("Log warning enabled: {}",  LOGGER.isWarnEnabled());
        LOGGER.warn("warn message");
        LOGGER.error("Log debug enabled: {}",  LOGGER.isDebugEnabled());
        LOGGER.debug("debug message");
        return null;

    }

}    

then set the LOG_LEVEL environment variable to the appropriate level to see the the relevant entries in the logs然后将 LOG_LEVEL 环境变量设置为适当的级别以查看日志中的相关条目

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM