5

so I had a look into best practices regarding logging in Java (slf4j, log4j, logback, etc.) and it seems, that there is a consent among libraries how a logging API should look like. The recommendation I read all the time is code like this, where you create a logger per class:

class Foo{
  Logger logger = Logger.getLogger(Foo.class);
  //...
  logger.info("my log message");
  //...
}

Now I don't really get the benefit of having seperate loggers for different classes. Why are the info/debug/etc. methods in the Logger class not static?

Please don't give an anwser like "The benefit is that you can configure your logger depending on the class. For example you could set the log level for individual classes to DEBUG...", because I think this is something that you could accomplish with a completely static Logger class as well.

If you look around (e.g. here on stackoverflow: Log4J: Strategies for creating Logger instances) you find people using idioms like this:

Logger.getLogger(Thread.currentThread().getStackTrace()[2].getClass().getCanonicalName());

Now instead of creating a logger for every class, you could just call the above code inside of a static (e.g.) info() method, where you could determine the calling class and apply all the logger configuration equally as you would do otherwise.

So can anyone tell me a real reason why someone should use a logger per class instead of using one static logger? Is it for purely historical reasons? Am I missing something? I am aware that there might be a performance impact, but it will be actually positive in terms of memory usage (and of course negative in terms of runtime)...

UPDATE I figured you can even use this code in static info/debug/etc. methods, which is beautiful and more performant than above code:

Reflection.getCallerClass()

However support for that method seems problematic >=JDK7

Wolf
  • 892
  • 2
  • 8
  • 22

1 Answers1

0

Calling that line inside a static info() method would have a detrimental effect on performance, since it would need to create the entire stack trace each time, and that is very slow.

Assigning the logger instance to a static variable per class means that either you can be explicit about the class, or you can use the expensive method to determine the class name from the stack trace just once when the class is loaded. Then, you can just use the same logger over and over without having to resolve the calling class again.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • When and why was my comment on this response deleted? The arguments given in the reply are totally bogus, which I previously explained in detail in a comment, that doesn't exist anymore... – Wolf Nov 17 '22 at 09:07
  • Literally no idea when it was deleted; it could have been any time over the past 7 years. What is "totally bogus" about my answer? Are you sure you're talking about my answer, rather than [the answer given by Slava Vedenin](https://stackoverflow.com/a/34055163/3788176) which I can see that you did comment on (but you may not have sufficient privilege to see)? – Andy Turner Nov 17 '22 at 17:52
  • Your first comment on that answer started "I disagree. As I already mentioned in my question I am well aware of a negative performance impact, but I think in most cases it can be neglected.", if it helps jog your memory. – Andy Turner Nov 17 '22 at 17:56
  • Interesting... I can't see or remember Slava's response. Your link only directs me to this question. Do you have any idea why the answer isn't visible anymore? Sorry if I confused your answer with Slava's. If my memory serves me right, I made the case as to why performance issues in regard to accessing the stacktrace/reflection in this case isn't detrimental, in which case that comment would seem to apply to exactly your answer. Well... I guess only stackoverflow moderators will know... – Wolf Nov 19 '22 at 01:03
  • Slava deleted it; I can still see it because I have sufficient rep. – Andy Turner Nov 20 '22 at 07:37