WildFly 9 comes with a lot of in-build logger, like Console, File, Size, Syslog. But if you want to use specialized loggers or other data stores (database, HDFS) you need to build a custom log handler which handles all of these things.
In our case we wanted to use Apache Flume as log collector and Hadoop/HDSF as storage for our logs.
To use Log4j as log handler for WildFly you have to do the following steps:
So let’s do this step by step. You can download the code from GitHub.
All custom handlers which you want to use in WildFly have to extend the abstract class java.util.logging.Handler. It is a bridge from java.util.logging to Log4j so the name of the handler is JulToLog4jHandler.
The handler includes the following steps:
The initialization is done in the constructor.
public JulToLog4jHandler() {
ConfigurationSource source;
try {
source = new ConfigurationSource(this.getClass()
.getClassLoader().getResourceAsStream("log4j.xml"));
Configurator.initialize(null, source);
} catch (IOException e) {
e.printStackTrace();
}
}
Since java.util.logging and Log4j have different level, a conversion is necessary.
private org.apache.logging.log4j.Level convertLeveltoLog4j(Level level) {
if (level.equals(Level.SEVERE)) {
return org.apache.logging.log4j.Level.ERROR;
} else if (level.equals(Level.WARNING)) {
return org.apache.logging.log4j.Level.WARN;
} else if (level.equals(Level.INFO)) {
return org.apache.logging.log4j.Level.INFO;
} else if (level.equals(Level.FINE)) {
return org.apache.logging.log4j.Level.DEBUG;
} else if (level.equals(Level.FINEST)) {
return org.apache.logging.log4j.Level.TRACE;
} else if (level.equals(Level.OFF)) {
return org.apache.logging.log4j.Level.OFF;
}
return org.apache.logging.log4j.Level.OFF;
}
Method that publish the log records to the appropriate Log4j logger.
@Override
public void publish(LogRecord record) {
if (record.getLevel().equals(Level.OFF)) return;
Logger log4j = getTargetLogger(record.getLoggerName());
org.apache.logging.log4j.Level level = convertLeveltoLog4j(record.getLevel());
log4j.log(level, toLog4jMessage(record), record.getThrown());
}
Create a jar file with maven by executing mvn clean package.
You can download the modules.zip and extract it into modules/system/layers/base under WildFly home directory or do the following steps manually.
The following steps are all done under WILDFLY_HOME/modules/system/layers/base. We assume that MODULES_BASE points to WILDFLY_HOME/modules/system/layers/base.
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="de.bdegmbh.logging">
<resources>
<resource-root path="jul2log4j-0.0.1.jar"/>
<resource-root path="."/>
</resources>
<dependencies>
<module name="org.apache.logging.log4j"/>
<module name="org.apache.flume"/>
<module name="org.slf4j"/>
</dependencies>
</module>
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.apache.logging.log4j">
<resources>
<resource-root path="log4j-api-2.3.jar"/>
<resource-root path="log4j-core-2.3.jar"/>
<resource-root path="log4j-1.2-api-2.3.jar"/>
<resource-root path="log4j-slf4j-impl-2.3.jar "/>
<resource-root path="log4j-flume-ng-2.3.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="org.apache.flume"/>
</dependencies>
</module>
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.apache.flume">
<resources>
<resource-root path="flume-ng-core-1.6.0.jar"/>
<resource-root path="flume-ng-sdk-1.6.0.jar"/>
<resource-root path="flume-ng-log4jappender-1.6.0.jar"/>
<resource-root path="flume-ng-configuration-1.6.0.jar"/>
</resources>
<dependencies>
<module name="org.slf4j"/>
</dependencies>
</module>
The last step is to define a new custom handler in WildFly configuration via web interface or in appropriate xml file and assign it as handler for your classes.
<subsystem xmlns="urn:jboss:domain:logging:3.0">
<console-handler name="CONSOLE">
<level name="INFO"/>
<formatter>
<named-formatter name="COLOR-PATTERN"/>
</formatter>
</console-handler>
<custom-handler name="LOG4J" class="de.bdegmbh.logging.jul2log4j.JulToLog4jHandler" module="de.bdegmbh.logging"/>
.
.
.
</subsystem>
That's all. If you have any questions or suggestions, do not hesitate to contact us.
comments powered by Disqus