JBoss logging, like Apache log4j can make use of an MDC (Mapped Diagnostic Context) for logging information specific to a thread and its children.
The JavaDoc for Log4J's MDC can be found here, JBoss logging MDC behaves in exactly the same way: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html
To use the MDC in your code you have to import org.jboss.logging.MDC, then use the static methods "put" and "remove" to populate entries in the MDC. The example code below shows a simple servlet which performs the following actions when browsed to:
- Writes a log entry without the MDC being populated
- Populates the MDC with two fields
- Writes another log entry
- Spawn and run a thread which writes another log entry
- Remove the fields from the MDC
- Write another log entry
h3. TestServlet.java - set the MDC entries and spawn a child thread
{code}package com.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.logging.MDC;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.resource.work.JBossWorkManagerMBean;
import javax.management.MBeanServer;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.resource.spi.work.WorkManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TestServlet extends HttpServlet {
private static final Log log = LogFactory.getLog(TestServlet.class);
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
protected void doAction(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//1 first log without any MDC entries
log.info("Log without MDC");
//2 now add the MDC entries
MDC.put("entry1", "some stuff");
MDC.put("entry2", "some other stuff");
//3 print a log line now the MDC has been populated
log.info("Log with MDC");
//4 use the work manager to spawn a child thread
try {
//get the work manager
MBeanServer server = MBeanServerLocator.locateJBoss();
ObjectName objectName = new ObjectName("jboss.jca:service=WorkManager");
JBossWorkManagerMBean jwm = (JBossWorkManagerMBean)
MBeanServerInvocationHandler.newProxyInstance(server, objectName, JBossWorkManagerMBean.class, false);
WorkManager wm = jwm.getInstance();
//start the thread
wm.doWork(new WorkImpl());
}
catch (Exception e) {
log.error("Exception caught", e);
}
//5 remove the entries from the MDC
MDC.remove("entry1");
MDC.remove("entry2");
//6 write another log line
log.info("Another log without MDC");
}
}{code}
h3. WorkImpl.java - write another log entry
{code}package com.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.resource.spi.work.Work;
import java.io.Serializable;
public class WorkImpl implements Work, Serializable {
private static final Log log = LogFactory.getLog(WorkImpl.class);
@Override
public void release() {
}
@Override
public void run() {
log.info("Child thread with MDC");
}
}{code}
*Note: If the MDC entries are removed before the thread does its work then they will not be displayed in the child thread's log entries*
In order to display the MDC entries in the log you will have to configure an appender in the jboss-logging.xml with a pattern layout which will display the MDC entries in its output.
The sample below is taken from the default jboss-logging.xml, the important bit of configuration is the pattern-formatter, note in the example below the "%X{entry1}" and "%X{entry2}" elements in the pattern, which correspond to the MDC elements in the TestServlet.java code above.
{code:xml}<periodic-rotating-file-handler
file-name="${jboss.server.log.dir}/server.log"
name="FILE"
autoflush="true"
append="true"
suffix=".yyyy-MM-dd">
<error-manager>
<only-once/>
</error-manager>
<formatter>
<pattern-formatter pattern="%d %-5p [%c] (%t) [%X{entry1}, %X{entry2}] %s%E%n"/>
</formatter>
</periodic-rotating-file-handler>{code:xml}
When browsing to the servlet the following log entries are output:
{noformat}2011-02-15 16:55:01,048 INFO [com.test.TestServlet] (http-127.0.0.1-8080-2) [, ] Log without MDC
2011-02-15 16:55:01,049 INFO [com.test.TestServlet] (http-127.0.0.1-8080-2) [some stuff, some other stuff] Log with MDC
2011-02-15 16:55:01,050 INFO [com.test.WorkImpl] (pool-1-thread-16) [some stuff, some other stuff] Child thread with MDC
2011-02-15 16:55:01,050 INFO [com.test.TestServlet] (http-127.0.0.1-8080-2) [, ] Another log without MDC{noformat}
Known Issue :
https://issues.jboss.org/browse/JBLOGGING-54
Discussion :
Comments