Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Logging: show the source line number of the caller (not the logging helper method)

The numerous (sigh...) logging frameworks for Java all do a nice job of showing the line number of the source file name for the method that created the log message:

log.info("hey");   [INFO] [Foo:413] hey 

But if have a helper method in between, the actual caller will be the helper method, and that is not too informative.

log_info("hey");  [INFO] [LoggingSupport:123] hey 

Is there a way to tell the logging system to remove one frame from the callstack when figuring out the source location to print?

I suppose that this is implementation specific; what I need is Log4J via Commons Logging, but I am interested to hear about other options.

like image 619
Thilo Avatar asked Sep 28 '09 09:09

Thilo


People also ask

What is the function of Java logging?

Loggers in Java are objects which trigger log events, They are created and are called in the code of the application, where they generate Log Events before passing them to the next component which is an Appender. You can use multiple loggers in a single class to respond to various events or use Loggers in a hierarchy.

What is logging in Java examples?

Java Logging FormattersSimpleFormatter: This formatter generates text messages with basic information. ConsoleHandler uses this formatter class to print log messages to console. XMLFormatter: This formatter generates XML message for the log, FileHandler uses XMLFormatter as a default formatter.

What is debug logging in Java?

Debug is used a lot for debugging the application at development time. Every log message will appear to log files once this level is set. It basically belongs to developers. INFO. The INFO logging level is used to record messages about routine application operation.

Where does logger info write to Java?

After passing this initial (cheap) test, the Logger will allocate a LogRecord to describe the logging message. It will then call a Filter (if present) to do a more detailed check on whether the record should be published. If that passes it will then publish the LogRecord to its output Handlers. `


2 Answers

Alternative answer.

It is possible to ask log4j to exclude the helper class by using the method

Category.log(String callerFQCN, Priority level, Object message, Throwable t)

and specifying the helper class as 'callerFQCN'.

For example here is a class using a helper:

public class TheClass {     public static void main(String...strings) {         LoggingHelper.log("Message using full log method in logging helper.");         LoggingHelper.logNotWorking("Message using class info method"); }} 

and the code of the helper:

public class LoggingHelper { private static Logger LOG = Logger.getLogger(LoggingHelper.class);  public static void log(String message) {     LOG.log(LoggingHelper.class.getCanonicalName(), Level.INFO, message, null); }  public static void logNotWorking(String message) {     LOG.info(message); } } 

The first method will output your expected result.

 Line(TheClass.main(TheClass.java:4)) Message using full log method in logging helper. Line(LoggingHelper.logNotWorking(LoggingHelper.java:12)) Message using class info method 

When using this method, Log4j will work as usual, avoiding calculating the stack trace if it is not required.

like image 143
vdr Avatar answered Sep 22 '22 17:09

vdr


Please note that giving the line number is something very costly, either for what you get naturally from Log4j or the following. You have to accept that cost...

You could use the following APIs:

    StackTraceElement[] stackTraces = Thread.currentThread().getStackTrace();     StackTraceElement stackTraceElement = ...;     stackTraceElement.getLineNumber(); 

Updated:

You would have to calculate it yourself. So:

  • ask log4j not to output it (in your logging format),
  • and insert yourself the line number explicitement in the beginning of your message (the String you send to log4j).

Depending how you prefer your loggers, your helper method may:

  • use an explicit Logger (passed as a parameter I guess), when appropriate (we sometimes define specific loggers for specific context ; for example, we have a logger for sending our database requests, no matter what class does it ; this allow us to reduce to one place the changes made to our configuration file, when we want to (de-)activate them ...)
  • use a Logger for the calling class : in this case, instead of passing the parameter, you can deduce the caller class name likewise...
like image 39
KLE Avatar answered Sep 18 '22 17:09

KLE