views:

51

answers:

3

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications.

[App A] -> [App B] -> [App C]

We set a global id in the message header so we can trace each message lifecycle through the system.

I would like to be able to prepend any log message in the system with the message global id.

Has anyone else done this? Is there any way to associate this variable to the Thread so I can access it in future methods? I'd rather not pass the variable around in methods of the system.

+1  A: 
Thread t = Thread.currentThread();
t.setName("Your ID Here");
James Camfield
+2  A: 

I think ThreadLocal may be what you want here, though some may find this approach an abuse of ThreadLocal's purpose, or good design. Something like:

public class MyIDManager {
  public static final ThreadLocal<Long> myID = new ThreadLocal<Long>();
}

...
// set ID at some point
MyIDManager.myID.set(theNewID);

...
// read it later
long currentID = MyIDManager.get();

The magic here is that myID's value is actually specific to a Thread, and will be different when accessed from different threads.

You can then do what you like with the ID, including logging it.

Sean Owen
Log4j uses thread-local variables to implement its `NDC` and `MDC` classes, which is what I'd use for this problem with log4j. If you had to roll your own, a `ThreadLocal` is a good fit.
erickson
I ended up using NDC, thank you.
Mark Sailes
A: 

Another answer, which I believe the first post is alluding to, is to simply ask your logging framework to include the thread name in the log statement. For example, log4j lets you add the thread name with 't' in its PatternLayout: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html I've seen this in other frameworks too.

Sean Owen
we do this, but obviously there can be many different threads used throughout the system.
Mark Sailes