Did you ever deploy a jar to production and then need to change the log4j2 configuration for some package? Changing the jar on-the-fly or a new deployment was like stuck between a rock and a hard place. Then I found the following easy solution.
Log4j2 integration
As described in the Spring Boot tutorial it is a simple change in the pom.xml to add log4j2 support to the project:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
There are a bunch of logging frameworks available but why should I choose log4j2? A good answer ist found on stackoverflow. My favorites are the following properties of log4j2:
This means: no more additional if like
if (logger.isDebugEnabled()) { logger.debug("Logging in user " + user.getName() + " with birthday " + user.getBirthdayCalendar()); }
and lightning fast logging.
A log4j2 configuration to start with
I confess: normally I copy-and-paste a log file from an older project when I start a new one. But this time I give you (and me) a template to use in new projects. The format is the good old XML style because everybody knows it (inspired by logging.apache.org):
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" name="MyApp" packages=""> <Appenders> <RollingFile name="FILE" fileName="logs/app.log" filePattern="logs/app-%d{yyyy-MM-dd}.log.zip" ignoreExceptions="false"> <PatternLayout> <Pattern>%d [%-6p] %C{1}.%M(%F:%L) - %m%n</Pattern> </PatternLayout> <TimeBasedTriggeringPolicy interval="30" modulate="true" /> </RollingFile> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%m%n"/> </Console> <Async name="Async"> <AppenderRef ref="FILE"/> </Async> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Async"/> </Root> </Loggers> </Configuration>
</Configuration>
Use an external log4j2.xml
Log4j2 (and all other logging frameworks I know) try to find the configuration on the classpath. If you want to use an external configuration file you have to extend the classpath. This sounds like a bad idea for security reason. Think about adding an additional jar von the classpath with some classes that overrides production classes…
Here is the trick to use an external log configuration file without changing the classpath: call the jar with the parameter-Dlog4j.configurationFile=./log4j2.xml
When you want to use async loggers, don’t forget to add the parameter-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector