David Thielen wrote:
>
> I looked at that - org.apache.log4j.examples.appserver adds it's data at
> Category constructor time. I need to add items at the time the log line item
> is written. I need to log the user - we attach a user token to each session
> and I can get that from the thread. But when an object is created - it can
> be used by multiple users so I can't set it at construction time.
This is from memory, so bear with me.
You can do what you want by extending Category and LoggingEvent and
adding method(s) to your subclass of Category which takes additional
arguments (whatever custom data you need to log). Those new methods
creates instances of your subclass of LoggingEvent. This subclass has
attributes for holding your additional data. Then you write a subclass
of PatternLayout which recognizes your additional conversion characters
and pulls data out of your custom LoggingEvent accordingly. This is the
scheme described in Pauls appserver example.
You say that your data is availeble to the thread doing the logging. If
this means it's also available to the PatternLayout subclass then
there's a simpler and better way of doing things. Basically, you just
don't extend Category and LoggingEvent, but rather, in your sublcass of
PatternLayout you just extract data for your custom conversion
characters dircely from the "context" (e.g. ThreadLocals if that's what
you're usign). This is a good thing because using Category subclasses
can be problematic and is best avoided if possible.
Another approach which also avoids creating subclasses of Catgeory is to
define a "data class" holding your custom app data elements, and then
log instance of this class rather than Strings, e.g.
public class AppData {
public Foo foo;
public Bar bar;
public Baz baz;
...
}
and then in your logging code:
category.info(new AppData(...));
In your PatternLayout subclass you can then cast the result of
LoggingEvent.getMessage() and retrieve the attributes as appropriate.
You could define a custom ObjectRenderer but that has limitations
compared to subclassing PatternLayout. Still, if you define a toString()
on AppData, then the defaultRenderer will use that method be get a
String for %m. Maybe I make all this sound very complicated, but it
really isn't.
Cheers,
Anders
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]