Using Log4J with JBoss AS 7 and WildFly

User Rating: 2 / 5

Star ActiveStar ActiveStar InactiveStar InactiveStar Inactive
 

Using log4j with JBoss AS 7 has had a troubled history and I'd like to offer a comprehensive guide with this article so that you can save a few headaches. Let's start with the newest version of the application server and later we will see how to use log4j with jBoss AS 7.

WildFly Log4j configuration

Using Log4j with Wildfly is quite easy as you have already a module named "org.apache.log4j" for that purpose:

<module-alias xmlns="urn:jboss:module:1.1" name="org.apache.log4j" target-name="org.jboss.log4j.logmanager"/>

Please notice that the actual log4j libraries are packed in the log4j-jboss-logmanager-1.1.0.Final.jar that can be found under JBOSS_HOME\modules\system\layers\base\org\jboss\log4j\logmanager\main folder.

So, in order to start logging with WildFly make sure:

Step #1: Include Log4j dependency in your META-INF/MANIFEST.MF or in jboss-deployment-structure.xml

Manifest-Version: 1.0
Dependencies: org.apache.log4j


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 (Take care WEB-INF/classes not WEB-INF !)
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="log4j.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 !

@WebServlet("/LoggerServlet")
public class LoggerServlet extends HttpServlet {
    private static org.apache.log4j.Logger logger =
            org.apache.log4j.Logger.getLogger(LoggerServlet.class);
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException,
            IOException {
        logger.warn("Hello from 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>

Using Log4j with JBoss AS 7.1.1

Using log4j for releases under the 7.1.2 is a bit more troublesome as there are some conflicts which arise between log4j and the default logging implementation of the application server.So you have to follow these steps:
Step #1: Include log4j libraries and log4j configuration file in your application classpath

Step #2: As org.apache.log4j will conflict with your libraries, you have to exclude the module from your deployment:
 
I added a WEB-INF/jboss-deployment-structure.xml file with the following content:

<?xml version="1.0" encoding="UTF-8"?> 
<jboss-deployment-structure>
   <deployment>
     <exclusions>
       <module name="org.apache.log4j" />
     </exclusions>
   </deployment>
 </jboss-deployment-structure> 

Please notice that for server releases above the 7.1.1 (such as the 7.2.0) this bug has been fixed and you can use the same approach which has been discussed in "Using Log4j with WildFly" at the beginning of this article.

Follow us on Twitter