Rajkumar Palani
Rajkumar Palani

Reputation: 2281

Log4j logging performance

Log4j pattern layout docs warns that generating caller class information is costly and should be used only when performance is not a concern. I want to have the class name in logs for easy analysis and also doesn't want to have an impact in performance. Having stated that I have two options,

  1. Store class name using getClass().getName() in every class and use that string in logging String class = getClass().getName(); ... ... logger.debug(class + "log message");

  2. Hardcode the class name and give it in log String class = "com.foo.myclass"; ... ... logger.debug(class + "log message");

Which would give better performance or is there any other way to log fully qualified class name and method name without affecting performance. Thanks in Advance!

Note: I am using log4j 1.2.16

Upvotes: 1

Views: 1074

Answers (2)

ben75
ben75

Reputation: 28706

A usual pattern for loging with log4j is the following

public class Foo {

    private static final Logger LOG = Logger.getLogger(Foo.class);

    someMethod(){
         ...
         if(LOG.isDebugEnabled()){
              LOG.debug("log message");
         }
    }
}

The classname is the logger name so it will (by default) appears in the log message.

Most importantly regarding performance: there is a guard preventing the overhead of the computation of the log message when the log level is not enabled.

Upvotes: 2

Ian Roberts
Ian Roberts

Reputation: 122364

Generating the caller class name is costly but if you're following the typical Log4J design pattern of one Logger per class with the Logger name being the same as the class name

private static final Logger LOG = Logger.getLogger(ThisClassName.class);

then it may be sufficient to simply use %c instead of %C in your layout pattern. This uses the logger name (which is a property of the logger itself) rather than inspecting the call stack, and does not involve the overhead incurred with patterns like %C or %L.

If you really do need the runtime class of the caller rather than the static name of the class that textually encloses a particular logging call, then you could use a per-instance logger rather than (or as well as) the per-class one

private final Logger instLog = Logger.getLogger(this.getClass());

and now the logger name will be the runtime type of this, i.e. if B extends A and we call a method on an instance of B then the logger name will be B, even for methods that are actually defined by the superclass A.

Upvotes: 4

Related Questions