views:

458

answers:

4

I want to configure an appender at startup and then dynamically add and remove it from various loggers on demand. I'd prefer to have log4j configure this appender itself, and just grab a reference to it when needed. If that's not possible, I'll have to instantiate the appender myself and hold onto it.

A: 

The Logger class has methods to getAllAppenders(), getAppender(), addAppender(), and removeAppender() methods, inherited from the Category class. However, the Category class is deprecated, and on top of that, I've never tried to do this before, but this might be a useful starting point.

Thomas Owens
`Category` has been superseeded by `Logger` class. `Logger` just inherits from `Category`. So, if `Category`'s method itself is not deprecated it's perfectly fine to use.
Alexander Pogrebnyak
Doesn't the use of getAppender() or getAllAppenders() assume that the appender's already on the Logger? I want to configure the Appender at startup, but not attach it to any categories at startup. Only at runtime would I grab it to call addAppender() on a Logger.
Seth Weiner
You can make an Appender on demand and add it.
Thomas Owens
That's probably what I'll wind up doing.
Seth Weiner
+1  A: 

Appenders are generally added to the root logger. Here's some pseudocode

// get the root logger and remove the appender we want
Logger logger = Logger.getRootLogger();
Appender appender = logger.getAppender("foo");
logger.removeAppender(appender)

// when we want to add it back...
logger.addAppender(appender);

I'm pretty sure you can do this on other loggers than the root logger as well, though I've never tried that.

Alan Krueger
Right, I know I can retrieve an appender off of a Logger if it's already been configured to be attached to it. However, I'm looking for a way to grab an appender configured at startup that is *NOT* already attached to a logger.
Seth Weiner
A: 

I want to do exactly the same thing. I want to configure appenders in log4j.properties and then select some and add the to the rootLogger dynamically at runtime.

I could not figure out how to access the appenders other than via a logger to which they had been attached, so I ended up creating a dummy logger, and attaching the appenders to it so i could retrieve them dynamically. This is not ideal though as any resources used by the appenders (e.g. files) are created upfront even if they are not used.

Joel
A: 

I would do it this way :

  1. have you appender specified in log4j.properties, but not added to root logger.
  2. at run time, when needed, grab log4j.properties, extract from it the properties you need, instantiate your appender and set its options by reading extracted properties.
  3. activate the appender
  4. Logger.getRootLogger().addAppender(appender);
  5. Kick it off when finished using it - Logger.getRootLogger().removeAppender(..)

Now, if this is your own appender, doing (2) would be easy since you know the meaning of the properties and know what to expect. Otherwise you would probably want to use reflection to instantiate the class and call its property setters before doing (3).

Dima