Log4j2 configuration in a separate file

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

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.