I am using a lambda function and writing it in Java. I was looking up logging for Lambda functions when I read the docs and they support log4j - http://docs.aws.amazon.com/lambda/latest/dg/java-logging.html#java-wt-logging-using-log4j.
I was wondering if we could use logging using the Slf4j annotation as well since Slf4j is only a binding annotation. Has anybody tried using Slf4j before with lambda?
Yes, you can. Just add the following dependencies to your project
<dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j</artifactId> <version>1.0.0</version> </dependency>
and create correct log4j.properties in /src/main/resources/ of your project, e.g.
log = . log4j.rootLogger = DEBUG, LAMBDA #Define the LAMBDA appender log4j.appender.LAMBDA=com.amazonaws.services.lambda.runtime.log4j.LambdaAppender log4j.appender.LAMBDA.layout=org.apache.log4j.PatternLayout log4j.appender.LAMBDA.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} <%X{AWSRequestId}> %-5p %c{1}:%m%n
Just include following dependency:
<dependency> <groupId>io.symphonia</groupId> <artifactId>lambda-logging</artifactId> <version>1.0.0</version> </dependency>
Background information available at: https://blog.symphonia.io/a-love-letter-to-lambda-logging-974b0eb49273
The jlib AWS Lambda Logback Appender allows you to use SLF4J with Logback from your AWS Lambda functions.
Simply add these dependencies:
Gradle (build.gradle)
dependencies { implementation 'org.slf4j:slf4j-api:1.8.0-beta2' runtimeOnly 'org.jlib:jlib-awslambda-logback:1.0.0' }
Maven (pom.xml)
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.8.0-beta2</version> </dependency> <dependency> <groupId>org.jlib/groupId> <artifactId>jlib-awslambda-logback/artifactId> <version>1.0.0</version> <scope>runtime</scope> </dependency>
Then use the AwsLambdaAppender in your logging configuration:
Example XML configuration (src/main/resources/logback.xml)
<configuration> <appender name="awslambda" class="org.jlib.cloud.aws.lambda.logback.AwsLambdaAppender"> <encoder type="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] <%-36X{AWSRequestId:-request-id-not-set-by-lambda-runtime}> %-5level %logger{10} - %msg%n</pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="awslambda" /> </root> </configuration>
Unlike other solutions, this Logback Appender correctly handles multi-line log messages, especially stack traces, and produces only a single CloudWatch Logs event per message.
The library also allows you to include the AWSRequestId, provided by the AWS Lambda runtime, in every single log message for better tracing.
While log4j2 requires additional handling in the build when you create an uber-jar, this solution works out of the box.
Disclaimer: I'm the developer of jlib