Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java logger that automatically determines caller's class name

public static Logger getLogger() {     final Throwable t = new Throwable();     final StackTraceElement methodCaller = t.getStackTrace()[1];     final Logger logger = Logger.getLogger(methodCaller.getClassName());     logger.setLevel(ResourceManager.LOGLEVEL);     return logger; } 

This method would return a logger that knows the class it's logging for. Any ideas against it?

Many years later: https://github.com/yanchenko/droidparts/blob/master/droidparts/src/org/droidparts/util/L.java

like image 993
yanchenko Avatar asked Sep 17 '08 07:09

yanchenko


People also ask

What is the best logger for Java?

One of the most popular solutions for the Java world is the Apache Log4j 2 framework. Maintained by the Apache Foundation, Log4j 2 is an improvement on the original Log4j, which was the most popular logging framework in Java for many years.

What is LogManager getLogger?

public class LogManager extends Object. The anchor point for the Log4j logging system. The most common usage of this class is to obtain a named Logger . The method getLogger() is provided as the most convenient way to obtain a named Logger based on the calling class name.

Which method is used to find or create a logger with the name passed as a parameter?

getLogger(java. lang. String): This method is used to find or create a logger with the name passed as parameter. It will create a new logger if logger does not exist with the passed name.


2 Answers

The MethodHandles class (as of Java 7) includes a Lookup class that, from a static context, can find and return the name of the current class. Consider the following example:

import java.lang.invoke.MethodHandles;  public class Main {   private static final Class clazz = MethodHandles.lookup().lookupClass();   private static final String CLASSNAME = clazz.getSimpleName();    public static void main( String args[] ) {     System.out.println( CLASSNAME );   } } 

When run this produces:

Main 

For a logger, you could use:

private static Logger LOGGER =    Logger.getLogger(MethodHandles.lookup().lookupClass().getSimpleName()); 
like image 94
Neeraj Avatar answered Sep 25 '22 08:09

Neeraj


Creating a stack trace is a relatively slow operation. Your caller already knows what class and method it is in, so the effort is wasted. This aspect of your solution is inefficient.

Even if you use static class information, you should not fetch the Logger again for each message. From the author of Log4j,Ceki Gülcü:

The most common error in wrapper classes is the invocation of the Logger.getLogger method on each log request. This is guaranteed to wreak havoc on your application's performance. Really!!!

This is the conventional, efficient idiom for getting a Logger is during class initialization:

private static final Logger log = Logger.getLogger(MyClass.class); 

Note that this gives you a separate Logger for each type in a hierarchy. If you come up with a method that invokes getClass() on an instance, you will see messages logged by a base type showing up under the subtype's logger. Maybe this is desirable in some cases, but I find it confusing (and I tend to favor composition over inheritance anyway).

Obviously, using the dynamic type via getClass() will require you to obtain the logger at least once per instance, rather than once per class like the recommended idiom using static type information.

like image 29
erickson Avatar answered Sep 23 '22 08:09

erickson