Changing default logging system in Glassfish 2.1 with Log4J
A lot of people are not satisfied by the default Java Logging (JUL) in Glassfish. Also, myself I encountered some problems on clustered environments where we should have one single log and not one log for each instance. Trying to change the logging system in Glassfish it looks to be almost impossible , but I found a very interesting project java.util.logging to log4j Bridge and the sky become more clear for Glassfish logging. Jul to Log4J Bridge are part of log4J project and is very useful when you want to overwrite java.util.logging OR log4J classes.
To change the default logging system of Glassfish we should have apache-jul-log4j-bridge binary’s.
First we should compile apache-jul-log4j-bridge because we can found it only in source form and not binary’s.
$ cd /usr/src
$ svn checkout http://svn.apache.org/repos/asf/logging/sandbox/jul-to-log4j-bridge apache-jul-log4j-bridge
$ cd apache-jul-log4j-bridge
$ mvn assembly:assembly
If you don’t have maven (mvn) installed just look on my old tutorial about log4j and dbappender
Now just get apache-jul-log4j-bridge-version.jar, log4j-version.jar and apache-log4j-component-1.0-version.jar from the target folder and copy it on the glassfish lib folder.
Second you should create a log4j.properties file in the root of the glassfish folder (/opt/SUNWappersver or /opt/glassfish or depends where did you install it) with the following content
log4j.properties
1 2 3 4 5 6 | #Logging to console log4j.appender.DB=org.apache.log4j.ConsoleAppender log4j.appender.DB.layout=org.apache.log4j.PatternLayout log4j.appender.DB.layout.ConversionPattern=%d [%t] %-5p %c - %m%n log4j.rootLogger=INFO, DB |
Off course you can use any Log4J appender, but you just need to add it on lib folder from the glassfish root.
Third you need to modify processLauncher.xml from lib/ folder and replace com.sun.enterprise.server.logging.ServerLogManager with org.apache.logging.julbridge.JULBridgeLogManager
Four, just restart your glassfish server and watch the console.
Bugs
At this moment Apache jul Log4J Bridge have a little bug and it’s possible to crash (at this moment I use revision 819660). I already filed a bug report on log4j bugzilla site and is possible to be corrected son.
If you get the following error in your glassfish log:
1 2 3 4 5 6 7 8 9 10 11 | java.lang.NullPointerException at org.apache.log4j.CategoryKey.<init>(CategoryKey.java:32) at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:266) at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:247) at org.apache.logging.julbridge.JULLog4jEventConverter.convert(JULLog4jEventConverter.java:121) at org.apache.logging.julbridge.JULBridgeHandler.publish(JULBridgeHandler.java:49) at java.util.logging.Logger.log(Logger.java:458) at java.util.logging.Logger.doLog(Logger.java:480) at java.util.logging.Logger.log(Logger.java:503) |
apply the following patch on the apache jul log4j bridge:
jul2log4j.diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | diff -NBru new/apache-jul-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java apache-jul-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java --- new/apache-jul-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java 2009-09-28 16:28:15.000000000 +0300 +++ apache-jul-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULBridgeHandler.java 2009-09-28 16:18:49.000000000 +0300 @@ -27,6 +27,7 @@ * */ class JULBridgeHandler extends Handler { + private static final String UNKNOWN_LOGGER_NAME = "unknown.jul.logger"; private final LoggerRepository repository; private final JULLog4jEventConverter converter; @@ -48,7 +49,12 @@ public void publish(LogRecord record) { LoggingEvent event = converter.convert(record); - Category localLogger = repository.getLogger(record.getLoggerName()); + String loggerName = record.getLoggerName(); + if (loggerName == null) { + loggerName = UNKNOWN_LOGGER_NAME; + } + + Category localLogger = repository.getLogger(loggerName); if (event.getLevel().isGreaterOrEqual(localLogger.getEffectiveLevel())) { localLogger.callAppenders(event); } diff -NBru new/apache-jul-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jEventConverter.java apache-jul-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jEventConverter.java --- new/apache-jul-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jEventConverter.java 2009-09-28 16:28:15.000000000 +0300 +++ apache-jul-log4j-bridge/src/main/java/org/apache/logging/julbridge/JULLog4jEventConverter.java 2009-09-28 16:11:59.000000000 +0300 @@ -27,6 +27,7 @@ * @author psmith */ public class JULLog4jEventConverter { +private static final String UNKNOWN_LOGGER_NAME = "unknown.jul.logger"; /** * A default implementation of a converter that converts: @@ -118,6 +119,9 @@ */ public LoggingEvent convert(LogRecord record) { String loggerName = record.getLoggerName(); + if (loggerName == null) { + loggerName = UNKNOWN_LOGGER_NAME; + } Logger logger = repository.getLogger(loggerName); String sourceClassName = record.getSourceClassName(); String sourceMethodName = record.getSourceMethodName(); |
To patch the bridge sources just run
$cd /usr/src
$patch -Ep1 < /pathTo/jul2log4j.diff
and recompile.
The patch is just adding return validation of getLoggerName function ().
getLoggerName() function from java.util.logging.LogRecord it can return Null as
specified in JDK documentation, and in the bridge sources getLoggerName() return is not checked.
Good Luck!























Leave your response!