I am currently working on event/activity logging system, which I'm implementing as an aspect using method interceptors. At the moment, the system/framework assumes that each method is one activity but I want to extend this so that an activity can span multiple method invocations. In order to do this, the first approach that come to mind is by providing some context to all the related method calls. However, I only know a way to do this if all method invocations are within the context of a single thread (like Log4J's MDC/NDC). Is there any way to provide context for multiple threads (probably without the code being aware of multithreading)?
3 Answers
Don't think about "logging". It goes to something even more fundamental: if you want the actions done by multiple thread being treated in the same context, what is you propagating to let each thread aware which context they are in?
If you can answer this, then this context is what you need to put in MDC/NDC for logging (probably not the whole context, but some key information in that context).
If your application doesn't carry such information around, there is no way anyone can determine that for you.
Edit:
I may give u some idea on how you may perform the setup. Whether it is appropriate to use AOP to further enhance it, that's your further study :)
// Assume I have a ContextManager which Context is stored in thread local:
abstract class ContextAwaredJob implements Runnable {
public ContextAwaredJob() {
this.context = ContextManager.getCurrentContext();
}
public void run() {
ContextManager.setCurrentContext(this.context);
doRun();
}
protected abstract void doRun();
}
You new "job" is going to extend this parent class, and context will be automatically setup if you are running this by another thread. (The design of course can be refined a lot but it give u a basic idea on what is happening)
2 Comments
Class ThreadLocal? This sems like it actually might be a valid and resonable use for TLS - adding a cotext to code that already exists.
2 Comments
I stumbled upon InheritableThreadLocal, which I think could work for my code. This is assuming that all related threads are spawned from some parent/root thread (which I think is a safe assumption).