I have the problem, that when logging with slf4j (and io.symphonia:lambda-logging) in Java, for every new line in the logging message CloudWatch outputs a new log message. This also happens for exceptions using the LOGGER.error(String msg, Throwable t)
)
And since the messages output by CloudWatch are unsorted and multiple messages can come in from different Lambdas (or other Services, etc.) the logs are becoming unreadable.
One solution to this is to setup the logging pattern in the logging configuration as follows:
<?xml version="1.0" encoding="UTF-8"?>
<configuration packages="com.amazonaws.services.lambda.runtime.log4j2">
<appender name="Lambda" class="io.symphonia.lambda.logging.DefaultConsoleAppender">
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss} %-5level - %logger{0}:%line: %replace(%msg){'\n','
'} %replace(%exception){'\n','
'} %nopexception %n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="Lambda" />
</root>
</configuration>
See the <pattern>
tag: The magic is in the %replace(%msg){'\n','
'}
and the %replace(%exception){'\n','
'} %nopexception
. Both calls are replacing the new line (\n) with a carriage return (
) for the log message (%msg) and a passed in exception (%exception). The reason why the second argument is in Unicode Hex Character Code and the first isn't is described in the conversation on GitHub linked below.
I put this into a loggerconfig.xml and setup the logger to use it in the class that is the entry point for the lambda like this:
private static final Logger LOGGER;
static {
// must be set before the very first call to LoggerFactory.getLogger()
System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "loggerconfig.xml");
LOGGER = LoggerFactory.getLogger(ClassThatShallLog.class);
}
I came to this solution through this conversation on GitHub.