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