Hi
I also suggest the approach with using MDC and custom filter.
You probably want the outputs from each thread in separate files. If so, you
have two possibilities:
1. Implementing a own RepositorySelector which holds different repositories for
each thread / thread sub group.
2. Creating and configuring the special appender at run time each time such a
thread starts. Remove it after thread ends.
Approach 1): At Thread start you put the threadID to MDC (is threadlocale)
before you make the first call (implicit or explicit) to LogManager. A
subsequent call to log4j (i.e. by requesting a particular Appender or a Logger)
will end up in your repository selector which can check the MDC value and
return a repository specific to this thread. The target of the found appender
can then be configured at runtime (i.e. supplying the file name with thread
id). This approach does not work in all cases if you have static Loggers in
your working classes, since these were instantiated at first class loading.
Similar problem with static helper functions. The logger has to be fetched at
each entry of such a function.
Approach 2): You not only have to create the special appender but also to
attach it to loggers. The problem arisis that there may be configured loggers
other than root which may have the additivity flag set to false. If you attach
the new appender only to root logger, this other configured loggers would never
output to the new appender. So you have to loop over all loggers and attach the
new appender to all loggers which have the additivity flag set to false.
Otherwise you would loose one main benefit of log4j (finetuning log outputs per
class). But you definitely loose the possibility of reconfiguring during
runtime (configureAndWatch).
Heri
-Original Message-
From: Maarten Bosteels [mailto:[EMAIL PROTECTED]
Sent: Wednesday, October 31, 2007 11:03 PM
To: Log4J Users List
Subject: Re: appenders with thread id affinity
I think what you want can easily be done with a cobination of
the MDC and a
custom filter:
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/A
ppenderSkeleton.html#addFilter(org.apache.log4j.spi.Filter)
1) When your unit of work starts, you put some key/value in the MDC
2) the custom filter denies all request where the specific
key/value is not
set
3) when unit of work is done, you remove key from MDC
You don't even have to add appender + filter at runtime, you can do it
initialization.
HTH
Maarten
On 10/31/07, William Damian Faris [EMAIL PROTECTED] wrote:
I was wondering if there is a way to do the following that
may or may not
be
possible.
I have a bunch of code that is already using log4j right
now. The loggers
that are used to log messages are your standard logfactor.getlog (
ClassName.class). I would like to capture all the logging
messages for a
given unit of work into a new appender that is set up at
runtime. I would
like all the code that runs after setting up this appender
to send log
messages to this new appender as well as the pre-existing configured
appenders, and I imagine the way to do this is via ThreadId.
Something like this
1. Setup a new appender
2. Somehow insert the appender into the log4j configuration
tied to the
current threadID
3. call a bunch of old code that is already using log4j, all the log
messages are caught by the existing configured appenders in
addition to my
new appender
4. return from calling code
5. Shutdown the new appender and remove it from the existing log4j
configuration.
So I am asking if its possible to insert an appender such
that subsequent
log messages for a certain threadID go to that appender,
and then remove
that appender
after code has run.
I will be looking at the docs and code for log4j but
thought I would ask
to
see if anyone has done anything like this.
Thanks
Will