Using Log4J 1.x with WildFly and JBoss EAP

This article discusses how to use the Log4j 1.x with WildFly / JBoss EAP applications. We will show the basic configuration steps and we will deploy a sample application on WildFly.

Log4j 1.x has reached EOL

Please note that log4j 1.x is no longer supported by the Apache Software Foundation. While it may still function in your application, it is recommended to migrate to log4j 2 to ensure compatibility with future updates and to receive ongoing support and security patches.
Check this article to learn how to configure Log4j2 with WildFly: How to use Log4j2 in your WildFly applications

WildFly Log4j 1.x configuration

Using Log4j with Wildfly is quite easy.

Step #1: Include Log4j dependency in your pom.xml file so that you are able to build your classes:

<dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
</dependency>

Step #2: Include a log4j configuration file (log4j.xml /log4j.properties) in your application’s classpath, so for example WEB-INF/classes for web applications. If you are using Maven to organize your project, you can place it into the resources folder.
Example:

<log4j:configuration debug="true"
                     xmlns:log4j='http://jakarta.apache.org/log4j/'>
    
    <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
        <param name="append" value="false" />
        <param name="file" value="${jboss.server.log.dir}/application.log" />

        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n" />
        </layout>
    </appender>

    <root>
        <level value="DEBUG" />
        <appender-ref ref="fileAppender" />
    </root>

</log4j:configuration>

Step #3: Make sure you have not altered the defaults for the System property named org.jboss.as.logging.per-deployment (default true). You can always revert the change by setting -Dorg.jboss.as.logging.per-deployment=true

Now you can log with log4j !

package com.mastertheboss.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;

@WebServlet(name = "hello", urlPatterns = { "/hello" })
public class HelloWorldServlet extends HttpServlet {


	static Logger logger = Logger.getLogger(HelloWorldServlet.class);
	public HelloWorldServlet() {
		super();

	}
	
	protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter writer = response.getWriter();
		writer.println("<h1>Hello World Servlet on WildFly</h1>");
		logger.debug("Hello World Servlet on WildFly");
		writer.close();
    }
 
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

Here is our your project source should look like:

src
└── main
    ├── java
    │   └── com
    │       └── mastertheboss
    │           └── servlet
    │               └── HelloWorldServlet.java
    ├── resources
    │   └── log4j.xml
    └── webapp
        ├── index.jsp
        └── WEB-INF
            └── beans.xml

Test the example Servlet and verify that logs are being written into the ${jboss.server.log.dir}/application.log folder.

Source code available on Github: https://github.com/fmarchioni/mastertheboss/tree/master/log/log4j

Configuring WildFly to use Mapped Diagnostic Context (MDC)

Mapped Diagnostic Context (MDC) allows debugging useful information which is not available in the default logging formatters. A typical example of it could be dumping the IP Address of a remote client on each logging line. In order to do that, you can use the following pattern in your server configuration:

<formatter name="PATTERN">
      <pattern-formatter pattern="%X{IP} %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
</formatter>
<formatter name="COLOR-PATTERN">
      <pattern-formatter pattern="%X{IP} %K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
</formatter>

Now you need to fill the IP attribute through the diagnostic context. This has to be done by the MDC implementation of your logging framework: for example, if you are using log4j, you will do something like that:

org.apache.log4j.MDC.put("IP", request.getRemoteAddr());
logger.info("This shows the Log4j MDC concept printing the remote IP Address");

Advanced Log4j configuration

I’ve often been asked if it’s possible to automatically compress rotating logs used by the application server. I’ve found out that this can be done by using Apache Extras for Apache log4j which is a jar file full of additional functionality for log4j 1.2.x. You can download it from here: http://logging.apache.org/log4j/extras/
Once downloaded, comes the installation part which is quite easy since we already know where to place the file (JBOSS_HOME\modules\system\layers\base\org\jboss\log4j\logmanager\main):

14/10/2013  13:41           448.797 apache-log4j-extras-1.2.17.jar
28/02/2014  19:05           482.869 log4j-jboss-logmanager-1.1.0.Final.jar
28/02/2014  19:05             1.638 module.xml

You have to update the module.xml to include log4j extras in your modules resources root:

<module xmlns="urn:jboss:module:1.1" name="org.jboss.log4j.logmanager">
    <resources>
        <resource-root path="log4j-jboss-logmanager-1.1.0.Final.jar"/>
        <resource-root path="apache-log4j-extras-1.2.17.jar"/>
    </resources>

    <dependencies>
        <module name="javax.api"/>
        <module name="javax.mail.api" optional="true"/>
        <module name="javax.jms.api" optional="true"/>
        <module name="org.dom4j" optional="true"/>
        <module name="org.jboss.logmanager"/>
        <module name="org.jboss.modules"/>
    </dependencies>
</module>

And here is a sample log4j.xml file which contains a RollingFileAppender policy which rotates the file daily and creates a zipped file name of older logs named myserver.%d{yyyy-MM-dd-HH-mm}.log.zip:

<log4j:configuration debug="true"
    xmlns:log4j='http://jakarta.apache.org/log4j/'>


    <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
        <param name="append" value="false" />
        <param name="file" value="log4j.log" />
        <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">

            <param name="FileNamePattern" value="myserver.%d{yyyy-MM-dd-HH-mm}.log.zip" />
        </rollingPolicy>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n" />
        </layout>
    </appender>

    <root>
        <level value="DEBUG" />
        <appender-ref ref="fileAppender" />
    </root>

</log4j:configuration>