In my project I've got a top-level abstract class FrameProducer
. I added a slf4j logger at this level, so that every inheriting class already has it. Here the code:
public abstract class FrameProducer extends Observable {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
protected BufferedImage frame;
public BufferedImage getFrame() {
return frame;
}
public void fireEvent() {
logger.debug("Firing event. Implementing class: {}", this.getClass());
setChanged();
notifyObservers();
}
}
There are also two inheriting classes: CameraFrameGrabber
and GrayscaleFilter
. Yet, when the method fireEvent()
is being called from CameraFrameGrabber
or GrayscaleFilter
the message is being logged at FrameProducer
level. Here the log, for clarity:
FrameProducer.fireEvent - Firing event. Implementing class: class com.ofj.frameaccess.CameraFrameGrabber
FrameProducer.fireEvent - Firing event. Implementing class: class com.ofj.frameaccess.GrayscaleFilter
Is it possible to initialize the logger in FrameProducer
in a way that everything gets logged at the most-specialized level in my class hierarchy?
Thanks for any help.
Edit: My log4j.properties looks like this:
log4j.rootCategory=TRACE, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%C{1}.%M - %m%n
Thanks for pointing out the right direction to look for possible corrections skaffman. I eventually changed my log4j.properties
to (as one of the examples in the PatternLayout documentation says):
log4j.rootCategory=TRACE, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%-6r [%15.15t] %-5p %30.30c %x - %m%n
...and everything gets logged right.
Logging in abstract classes is considered an anti-pattern by some because it introduces a potentially unexpected dependency. However if you are sure that all the stuff you are dealing with is your own that that's no problem I guess.
If you want to get the log message to show the concrete implementation rather than the abstract class name (which makes sense) then change your logging initialization statement in the abstract class to:
private final Logger logger = LoggerFactory.getLogger(getClass());
instead of something like:
private static final Logger logger = LoggerFactory.getLogger(MyAbstractClass.class);
i.e.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With