To enable things like
logger.info("This is a formatted number: %.2f", number)
I decided to write a subclass of org.apache.log4j.Logger
. I know, I could have written a wrapper class to achieve the same result but since I'm adding a lot of appenders to the logger at runtime I prefer to use inheritance.
The subclass looks like this:
public final class FormatLogger extends Logger {
private final static FormatLoggerFactory factory = new FormatLoggerFactory();
protected FormatLogger(String name) {
super(name);
}
public static Logger getLogger(String name) {
return Logger.getLogger(name, factory);
}
public void fatal(String formatter, Object... args) {
log(Level.FATAL, formatter, args);
}
public void log(Level level, String formatter, Object... args) {
if (super.isEnabledFor(level)) {
super.log(level, String.format(formatter, args));
}
}
}
Everything works nicely - everything but one thing: the message text now adds the name of the logger subclass instead of the name of the class calling the logger. As pattern layout, I use the following format:
[%d{yyyyMMdd HHmmss}] %-5p [%t] %C: %m%n
i.e. things look like this:
[20110525 214515] INFO [main] org.xyz.FormatLogger: This is a formatted number: 23.23
instead of:
[20110525 214515] INFO [main] org.xyz.Main: This is a formatted number: 23.23
Is there some way to do such thing "properly" so that "%C" keeps printing the original class name?
log4j2 is a library that must be used by a running java process, to be vulnarable.
To disable log4j logging, set the logging level for the component to OFF in both log4j. conf and log4j.
Unlike log4j, SLF4J (Simple Logging Facade for Java) is not an implementation of logging framework, it is an abstraction for all those logging frameworks in Java similar to log4J. Therefore, you cannot compare both. However, it is always difficult to prefer one between the two.
I did something similar, but I ended up creating a wrapper and passing in the class name to it. Then with this class name I prepended it to the front of all the 4 logging levels which I was already wrapping anyway. It's quite messy, but I couldn't find another way of doing so. My logging statements now spit out the logger name then the package/class name. Its a bit cumbersome, but I'd rather have the extra information vs having not enough information.
The solution is quite simple: add a fully qualified class name (FQCN), i.e.:
static String FQCN = FormatLogger.class.getName() + ".";
The log(..) method must then be modified like this:
super.log(FQCN, level, String.format(formatter, args), null);
This is perfectly shown in the example MyLogger.java that comes with log4j. -1 for my own laziness!
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