Using MDC in JBoss AS 6 applications

Version 3

    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:

     

    1. Writes a log entry without the MDC being populated
    2. Populates the MDC with two fields
    3. Writes another log entry
    4. Spawn and run a thread which writes another log entry
    5. Remove the fields from the MDC
    6. 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 :

    https://community.jboss.org/thread/161799