public static Logger getLogger() {
final Throwable t = new Throwable();
final StackTraceElement methodCaller = t.getStackTrace()[1];
final Logger logger
Google Flogger logging API supports this e.g.
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
See https://github.com/google/flogger for more details.
A good alternative is to use (one of) the lombok logs annotations : https://projectlombok.org/features/Log.html
It generate the corresponding log statement with the current class.
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());
I guess it adds a lot of overhead for every class. Every class has to be 'looked up'. You create new Throwable objects to do that... These throwables don't come for free.
A nice way to do this from Java 7 onwards:
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
The logger can be static
and that fine.
Here its using the SLF4J API
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
But in principal can be used with any logging framework. If the logger needs a string argument add toString()
I just have the following line at the beginning of most of my classes.
private static final Logger log =
LoggerFactory.getLogger(new Throwable().getStackTrace()[0].getClassName());
yes there is some overhead the very first time an object of that class is created, but I work mostly in webapps, so adding microseconds onto a 20 second startup isn't really a problem.