What is the ideal way to create a singleton wrapper on top of log4j2 #2243
-
What is the ideal way to create a singleton wrapper on top of log4j2? I created this singleton wrapper but realised it will not get the correct class name because of multiple threads using it. Should the wrapper be even Singleton?
|
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 21 replies
-
We discourage the use of wrappers since:
Loggers use multiple methods to retrieve the location of the caller. The problem with you code is that the detected caller of Your class should look like this: public class Log4JLogger {
private static final Adapter ADAPTER = new Adapter();
private static final String FQCN = Log4JLogger.class.getName();
public static Log4JLogger getLog4JLogger(Class<?> clazz) {
return ADAPTER.getLogger(clazz.getCanonicalName());
}
private final ExtendedLogger logger;
private Log4jLogger(final ExtendedLogger logger) {
this.logger = logger;
}
public void entering() {
logger.logIfEnabled(FQCN, Level.TRACE, null, "ENTER");
}
private static class Adapter extends AbstractLoggerAdapter<Log4jLogger> {
protected Log4jLogger newLogger(final String name, final LoggerContext context) {
return new Log4jLogger(context.getLogger(name));
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Why we need to pass
Also is there an alternative method to pass params in logIfEnabled, just like |
Beta Was this translation helpful? Give feedback.
-
Like Piotr I have to ask what is your requirement? Why do you need to implement your own Logger wrapper. Doing so is an anti-pattern. Using the Log4j API already allows you to use any other logging implementation. We have seen this many times and invariably the wrappers are implemented incorrectly. Note that Piotr mentioned using LogBuilder. It includes a withLocation() method so you can get the StackTraceElement of the caller and pass that in directly. |
Beta Was this translation helpful? Give feedback.
@mehulparmariitr,
We discourage the use of wrappers since:
Loggers use multiple methods to retrieve the location of the caller. The problem with you code is that the detected caller of
Logger.traceEntry()
is alwaysLog4jLogger
. To change this you need to use the SPIExtendedLogger
that allows you to specify which classes to ignore, when looking for the caller.Your class should look like this: