[slf4j-user] Double Checking log level when logging with log4j
Ceki Gulcu
listid at qos.ch
Thu Oct 23 19:20:52 CEST 2008
Hello Srinivasan,
The logger.isEnabledFor(...) operation takes about 25 nanoseconds with log4j and
about 10 nanoseconds with logback. new InterpolatedMessage probably takes longer
than that..
Srinivasan Raguraman wrote:
> When we are using log4j as underlying logger, sl4j actually does double
> checking of 'isErrorEnabled()' for every Log, if that LEVEL is enabled.
>
>
>
> public void error(String format, Object arg) {
>
> if (logger.isEnabledFor(Level.ERROR)) {
>
> String msgStr = MessageFormatter.format(format, arg);
>
> logger.log(FQCN, Level.ERROR, msgStr, null);
>
> }
>
> }
>
>
>
> This is because, once we pass the message to log4j
>
>
>
> logger.log(FQCN, Level.ERROR, msgStr, null);
>
>
>
>
>
> log4j library again does the check isErrorEnabled() before the actual
> logging. This code is the same as the isErrorEnabled check.
>
>
>
> *public*
>
> *void* log(String callerFQCN, Priority level, Object message,
> Throwable t) {
>
> *if*(repository.isDisabled(level.level)) {
>
> *return*;
>
> }
>
> *if*(level.isGreaterOrEqual(*this*.getEffectiveLevel())) {
>
> forcedLog(callerFQCN, level, message, t);
>
> }
>
> }
>
>
>
> To avoid this double checking why don't we wrap the format, arguments
> inside an Object, and use log4j renderer for that object to generate the
> final message? Or even override toString() method of that object to
> return the formatted message.
>
>
>
>
>
> Instead of this:
>
>
>
> logger.log(FQCN, Level.ERROR, msgStr, null);
>
>
>
> It could be something like:
>
>
>
> public void error(String format, Object arg) {
>
> logger.log(FQCN, Level.ERROR, new InterpolatedMessage(formate, arg), null);
>
> }
>
>
>
>
>
> Where
>
>
>
> public final class InterpolatedMessage {
>
>
>
> private final String format;
>
> private final Object arg;
>
>
>
> public InterpolatedMessage(final String format, final Object
> arg) {
>
> this.format = format;
>
> this.arg = arg;
>
> }
>
>
>
> @Override
>
> public String toString() {
>
> return MessageFormatter.format(this.format,
> this.arg);
>
> }
>
>
>
> }
>
>
>
>
>
> As you see, this will
>
>
>
> * Delay the message construction unless it really going to be used.
> * Avoid double checking with if LevelEnabled, when that level is
> actually enabled
>
>
>
> The negatives are
>
>
>
> * Creation of InterpolatedMessage Object for every log statement –
> since the object is just going to hold the reference of the format
> and args, this may not be expensive?
> o as it avoids construction of log message
> * Using toString() method of interpolated message is a trick! -
> Yes, for that we can otherwise add log4j renderer for objects of
> InterpolatedMessage type.
>
>
>
>
>
> I just gave my thoughts here; let me know what you guys think. I could
> follow up or help to verify if this will really gives us performance
> advantage.
>
>
>
> Regards,
>
> Srini
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> user mailing list
> user at slf4j.org
> http://www.slf4j.org/mailman/listinfo/user
--
Ceki Gülcü
Logback: The reliable, generic, fast and flexible logging framework for Java.
http://logback.qos.ch
More information about the slf4j-user
mailing list