Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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. 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;

    }

}
like image 766
Joseph McCarthy Avatar asked Aug 02 '18 10:08

Joseph McCarthy


1 Answers

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

<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

<?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

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

like image 175
Joseph McCarthy Avatar answered Sep 29 '22 17:09

Joseph McCarthy