Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4j2: How can I get Class Name and Line Number without using Throwable?

I have developed a wrapper class on Log4j2. Using declarative services of OSGi I have published a custom logger service using my own logger interface with the wrapper class being the implementation. The wrapper class is only used to configure the logger programmatically, message formatting & add a few more methods, at last it is calling the logging methods of Log4j2.

I want to print source class/file name and line number of each logs requested in the log file. The options %C/%F and %L only print information about the location inside my wrapper class where I actually call the log method.

So as a workout I am passing new Throwable as an argument each time so that I can use the layout %throwable{short.lineNumber}. But this is an expensive process for embedded applications.

My main problem is in getting the line number because for the file name I could at least request a new logger from Log4j2 with the name of each service requesting for logger service and keep it in a map.

Is there a solution to trace back the caller? I hope there is a similar solution for applications where you don't want to have the LOG4j2 jars on each consumer of the logger service. Just for info, I don't want to use any XML files, all configurations are made programmatically.

like image 725
Habeshaw Avatar asked Jan 20 '15 19:01

Habeshaw


2 Answers

You can use

StackTraceElement[] stes = Thread.currentThread().getStackTrace();

however I am not sure this is much cheaper.

What I do is make each message unique (for the class) and avoid including the line number. You can search for the unique message in your IDE to find the line number. The class should be in the name of the logger.

like image 121
Peter Lawrey Avatar answered Nov 15 '22 07:11

Peter Lawrey


Log4j2 internally walks the stacktrace to extract location information. It knows where to stop in the stack trace by specifying the correct FQCN (fully qualified class name) to the org.apache.logging.log4j.spi.ExtendedLogger#logMessage method.

Log4j2 contains a tool that generates code for logger wrappers. The documentation is here (in the Custom Log Levels manual page): http://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers

Try generating a logger wrapper with this tool and base your custom wrapper on the generated code. This generated code will use the correct FQCN and will be able to produce the correct location information.

like image 25
Remko Popma Avatar answered Nov 15 '22 06:11

Remko Popma