Monday, June 6, 2016

Using log4j2 with Play application

Play default logging engine is Logback. It may be combined with the another logging framework or replaced at all starting from Play 2.5.
This post complements the Play manual, which explains how to customize the Logback configuration for Scala, but does not refers Java.

How to combine Logback with log4j2

The jars in a Play application dependencies may use log4j2 as a logging engine. In such case log4j2 configuration should be provided in addition to Logback configuration.
In order to configure log4j2 two things are demanded:
1. A configuration file.
2. The system property log4j.configurationFile assigned with the configuration file name.
You can read all the details in log4j2 manual.

Setting log4j2 configuration for Play in run-time

To define log4j2 configuration in run-time:
1. Put log4j2 configuration file, for example log4j2.xml, into conf directory. Now both logback.xml and log4j2.xml are in conf directory and each is used by the relevant logging framework.
2. Set the system property log4j.configurationFile via JVM argument upon running the application. For example, in development mode:
activator -Dlog4j.configurationFile=conf/log4j2.xml 

Programmatic setting of Play log4j2 configuration

In this method the system property log4j.configurationFile is set with the help of an application configuration. I prefer this way, since it is less error-prone.
Reminder: default application configuration is defined with the file conf/application.conf, but it may be replaced by another one (see this post).

To define log4j2 configuration programmatically:
1. Put log4j2 configuration file, for example log4j2.xml, into conf directory.
2.Add property log4j.configurationFile into application configuration file and assign to it the value of a log configuration file with a relative path:
3. Create a class StartUpHandler, which is responsible for initializing of the system property log4j.configurationFile on the application startup:
 public class StartUpHandler {  
      private static final String LOG4J2_CONFIG_PROPERTY = "log4j.configurationFile";  
      public StartUpHandler(final Configuration configuration) {  
           System.setProperty(LOG4J2_CONFIG_PROPERTY, configuration.getString(LOG4J2_CONFIG_PROPERTY));
StartUpHandler reads a value of the property log4j.configurationFile from application.conf and assigns it to the system property log4j.configurationFile.
4. Create a module class OnStartupModule and register StartUpHandler to be injected:
 package modules;  
 public class OnStartupModule extends AbstractModule {  
      protected void configure() {  
5. Add the module into application.conf:
play.modules.enabled += "modules.OnStartupModule"

How to replace Logback with log4j2 for Java

Staring from Play 2.5 it is possible to replace the default Logback with another logging framework.
The following steps should be done:
1. Disable PlayLogback sbt plugin in build.sbt:
lazy val root = (project in file("."))
2. Add slf4 and log4j dependencies in build.sbt (use appropriate log4j2 version):
val log4jVersion = "2.4.1"
libraryDependencies ++= Seq(
  "org.apache.logging.log4j" % "log4j-slf4j-impl" % log4jVersion ,
  "org.apache.logging.log4j" % "log4j-api" % log4jVersion ,
  "org.apache.logging.log4j" % "log4j-core" % log4jVersion 
3. Define log4j2 configuration same to above steps, done for combining of log4j2 with Logback.


The custom logging framework does not work in development mode. There is an open issue.
While running with activator the following error appears upon an application startup:
No play.logger.configurator found: logging must be configured entirely by the application.
Log4j uses the default configuration and it is impossible to change it.

The good news - in the deployment mode this works well.

No comments :

About the author

My Photo
I trust only simple code and believe that code should be handsome. This is not a matter of technology, but professional approach, consolidated after years of software development. I enjoy to cause things working and feel very happy, when I manage to solve a problem.
Back to Top