Routing java.util.logging messages to Log4J
From Shrubbery
Contents |
[edit] Overview
Here's a little Handler I made that routes java.util.logging messsages to Log4J. These are all available here:
This very nicely solves the Facelets 'loadImplicit' error issue as well as giving you the flexibility to enable more detailed logging for the JSF reference implementation.
[edit] The java.util.logging Handler Class
JuliToLog4jHandler.java
package org.yajul.log;
import org.apache.log4j.Priority;
import org.apache.log4j.Logger;
import java.text.MessageFormat;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
/**
* A JULI (java.util.logging) handler that redirects java.util.logging messages to Log4J
* http://wiki.apache.org/myfaces/Trinidad_and_Common_Logging
* <br>
* User: josh
* Date: Jun 4, 2008
* Time: 3:31:21 PM
*/
public class JuliToLog4jHandler extends Handler {
public void publish(LogRecord record) {
org.apache.log4j.Logger log4j = getTargetLogger(record.getLoggerName());
Priority priority = toLog4j(record.getLevel());
log4j.log(priority, toLog4jMessage(record), record.getThrown());
}
static Logger getTargetLogger(String loggerName) {
return Logger.getLogger(loggerName);
}
public static Logger getTargetLogger(Class clazz) {
return getTargetLogger(clazz.getName());
}
private String toLog4jMessage(LogRecord record) {
String message = record.getMessage();
// Format message
try {
Object parameters[] = record.getParameters();
if (parameters != null && parameters.length != 0) {
// Check for the first few parameters ?
if (message.indexOf("{0}") >= 0 ||
message.indexOf("{1}") >= 0 ||
message.indexOf("{2}") >= 0 ||
message.indexOf("{3}") >= 0) {
message = MessageFormat.format(message, parameters);
}
}
}
catch (Exception ex) {
// ignore Exception
}
return message;
}
private org.apache.log4j.Level toLog4j(Level level) {//converts levels
if (Level.SEVERE == level) {
return org.apache.log4j.Level.ERROR;
} else if (Level.WARNING == level) {
return org.apache.log4j.Level.WARN;
} else if (Level.INFO == level) {
return org.apache.log4j.Level.INFO;
} else if (Level.OFF == level) {
return org.apache.log4j.Level.OFF;
}
return org.apache.log4j.Level.OFF;
}
@Override
public void flush() {
// nothing to do
}
@Override
public void close() {
// nothing to do
}
}
[edit] JMX MBean Wrapper
Lifecycle.java
/**
* Standard JMX MBean lifecycle methods.
* <br>User: Joshua Davis
* Date: Aug 29, 2007
* Time: 5:58:12 AM
*/
public interface Lifecycle {
/**
* Called when an MBean is started
*
* @throws Exception if something went wrong.
*/
void start() throws Exception;
/**
* Called when an MBean is stopped
*/
void stop();
}
JuliToLog4jServiceMBean.java
package org.yajul.log;
import org.yajul.jmx.Lifecycle;
/**
* JMX Interface for the Juli->Log4J MBean.
* <br>
* User: josh
* Date: Jun 5, 2008
* Time: 8:44:16 AM
*/
public interface JuliToLog4JServiceMBean extends Lifecycle {
/**
* @return The logging level of the java.util.logging->Log4J 'Handler' as a string
*/
String getHandlerLevel();
/**
* Sets the logging level of the java.util.logging->Log4J 'Handler' to the specified value.
* @param level the logging level for the adapter, e.g. "INFO"
*/
void setHandlerLevel(String level);
}
JuliToLog4jService.java
package org.yajul.log;
import java.util.logging.Logger;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.List;
import java.util.ArrayList;
/**
* JMX MBean that plugs in the JULI->Log4j handler on start and unplugs it on stop.
* Here is an example of a JBoss JMX MBean declaration:
* <!-- Redirect java.util.logging to Log4J. -->
* <mbean code="org.yajul.log.JuliToLog4JService"
* name="org.yajul:service=JuliToLog4J">
* <attribute name="HandlerLevel">DEBUG</attribute>
* <depends>jboss.system:type=Log4jService,service=Logging</depends>
* </mbean>
* Note that because of a small glitch in the JMX specification, the attribute name
* is 'HandlerLevel', and not 'handlerLevel' as you might expect.
* See http://madplanet.com/jboss-docu-wiki/Wiki.jsp?page=40.JMX.MBean
* <br>
* User: josh
* Date: Jun 4, 2008
* Time: 3:41:44 PM
*/
public class JuliToLog4JService implements JuliToLog4JServiceMBean {
private Handler activeHandler;
private List<Handler> oldHandlers = new ArrayList<Handler>();
private Level handlerLevel = Level.ALL;
private Level rootLevel = Level.INFO;
public void start() throws Exception {
try {
JuliToLog4jHandler.getTargetLogger(JuliToLog4JService.class).info(
"start(): Redirecting java.util.logging to Log4J...");
Logger rootLogger = LogManager.getLogManager().getLogger("");
// remove old handlers
for (Handler handler : rootLogger.getHandlers()) {
oldHandlers.add(handler);
rootLogger.removeHandler(handler);
}
// add our own
activeHandler = new JuliToLog4jHandler();
activeHandler.setLevel(handlerLevel);
rootLogger.addHandler(activeHandler);
rootLogger.setLevel(rootLevel);
// done, let's check it right away!!!
Logger.getLogger(JuliToLog4JService.class.getName()).info("started: sending JDK log messages to Log4J");
} catch (Exception exc) {
JuliToLog4jHandler.getTargetLogger(JuliToLog4JService.class).error("start() failed", exc);
}
}
public void stop() {
Logger rootLogger = LogManager.getLogManager().getLogger("");
rootLogger.removeHandler(activeHandler);
// Put all the old handlers back.
for (Handler oldHandler : oldHandlers) {
rootLogger.addHandler(oldHandler);
}
Logger.getLogger(JuliToLog4jHandler.class.getName()).info("stopped");
}
public String getHandlerLevel() {
return handlerLevel.getName();
}
public void setHandlerLevel(String level) {
final String parseThis = level.toUpperCase();
if ("DEBUG".equalsIgnoreCase(parseThis))
handlerLevel = Level.FINE;
else
handlerLevel = Level.parse(parseThis);
}
}
[edit] Adding it to JBoss AS
Once you have the classes in the classpath, just add the following to conf/jboss-service.xml right after the Log4JService declaration:
<!-- Redirect java.util.logging to Log4J. -->
<mbean code="org.yajul.log.JuliToLog4JService"
name="org.yajul:service=JuliToLog4J">
<attribute name="HandlerLevel">DEBUG</attribute>
<depends>jboss.system:type=Log4jService,service=Logging</depends>
</mbean>
[edit] See Also
- http://wiki.apache.org/myfaces/Trinidad_and_Common_Logging
- http://madplanet.com/jboss-docu-wiki/Wiki.jsp?page=40.JMX.MBean
Categories: Java | YAJUL

