<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>lstierneyltd &#187; log4j</title>
	<atom:link href="http://lstierneyltd.com/blog/tag/log4j/feed/" rel="self" type="application/rss+xml" />
	<link>http://lstierneyltd.com/blog</link>
	<description>Yet another development blog</description>
	<lastBuildDate>Wed, 13 Jul 2011 12:55:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Log4j Nested Diagnostic Contexts (NDC)</title>
		<link>http://lstierneyltd.com/blog/development/log4j-nested-diagnostic-contexts-ndc/</link>
		<comments>http://lstierneyltd.com/blog/development/log4j-nested-diagnostic-contexts-ndc/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 18:31:57 +0000</pubDate>
		<dc:creator>lawrence</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[How to's]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[log4j]]></category>
		<category><![CDATA[logging]]></category>

		<guid isPermaLink="false">http://lstierneyltd.com/blog/?p=118</guid>
		<description><![CDATA[Introduction and Problem Log4j is a brilliant set of libraries which provides good &#8220;out of the box&#8221; logging capabilities. Sometimes however, in multi-threaded environments (for example web apps), it can be hard to decipher the interleaved messages from the various clients e.g. Client A logs something Client B logs something Client A logs something Client [...]]]></description>
			<content:encoded><![CDATA[<h4>Introduction and Problem</h4>
<p>Log4j is a brilliant set of libraries which provides good &#8220;out of the box&#8221; logging capabilities.</p>
<p>Sometimes however, in multi-threaded environments (for example web apps), it can be hard to decipher the interleaved messages from the various clients<br />
<code><span id="more-118"></span></code><br />
e.g.</p>
<p>Client A logs something<br />
Client B logs something<br />
Client A logs something<br />
Client C logs something<br />
Client A logs something<br />
Client A logs something<br />
Client B logs something<br />
Client A logs something</p>
<p>Getting hard to read already!</p>
<h4>Solution</h4>
<p>Luckily for us Log4j has a built in solution to this common problem: Nested Diagnostic Contexts.</p>
<p>To quote the API doc &#8220;A Nested Diagnostic Context, or NDC in short, is an instrument to distinguish interleaved log output from different sources. Log output is typically interleaved when a server handles multiple clients near-simultaneously. </p>
<p>Interleaved log output can still be meaningful if each log entry from different contexts had a distinctive stamp. This is where NDCs come into play&#8230;.&#8221; </p>
<p><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/NDC.html">http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/NDC.html</a></p>
<p>The simple example below applies NDC to a Message Driven Bean (MDB):</p>
<h4>Sample Java Code</h4>
<pre>
package test.controller;

import javax.jms.Message;
import javax.jms.MessageListener;

import org.apache.log4j.Logger;
import org.apache.log4j.NDC;

public class Log4jDiagnosticContextSetter implements MessageListener {

    private static final Logger LOG = Logger.getLogger(Log4jDiagnosticContextSetter.class);

    private MessageListener messageListener;

    public void onMessage(Message message) {
        boolean loggingContextIsSet = addLoggingContextData(message);

        try {
            messageListener.onMessage(message); // the bean does its stuff
        }
        finally {
            if (loggingContextIsSet){
                removeLoggingContextData();
            }
        }
    }

    private boolean addLoggingContextData(Message message) {
        if (!LOG.isInfoEnabled())
            return false;

        try {
            NDC.push(getUniqueRef());
        }
        catch (Exception e) {
            LOG.error("Error pushing identifier onto Log4J NDC stack.", e);

            return false;
        }

        return true;
    }

    private void removeLoggingContextData() {
        try {
            while (NDC.getDepth() != 0) {
                NDC.pop();
            }
        }
        catch (Exception e) {
            LOG.error("Error popping message ID off of Log4J NDC stack.", e);
    }

    private String getUniqueRef() {
        // some way to get a unique reference
    }
}
</pre>
<h4>Sample Log Output</h4>
<p>You can see here in the example log output the result of the NDC push code above (in this case &#8220;98765432&#8243; is the unique identifier)</p>
<pre>
[02/06/2010 12:49:34:883 BST] [MessageListenerThreadPool : 0] DEBUG AuditServiceListener [98765432] - Processing message
[02/06/2010 12:49:34:883 BST] [MessageListenerThreadPool : 0] DEBUG ServiceMsgProcessor  [98765432] - Starting processing of XML request. Request=(<someMessage></someMessage>)
[02/06/2010 12:49:34:883 BST] [MessageListenerThreadPool : 0] DEBUG RequestUnmarshaller  [98765432] - Unmarshalling XML request payload to object.
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lstierneyltd.com/blog/development/log4j-nested-diagnostic-contexts-ndc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

