Question

I am stuck at understanding a concept related to Logger creation, especially in the context of Java EE.

In my experience, I nearly always used one logger per application, with few cases when I needed a specific logger for a specific part of the application. Only in these cases I was creating through my wrapper a new logger. And, if we talk about identifying the class which called the logger, I was doing a simple thing:

public const String ThisIdentifier = "MyLoggerCallingClass";

And I was passing this as a parameter to the logger method, even if there were some additional keystrokes I needed to do.

Now I'm facing a conceptual problem: Why create logger per class, and not one per application.
I have found the following answers:

Best way to initialize loggers

Why loggers per class recommended

However, if I get this info from apache documentation on getLogger:

Retrieve a logger named according to the value of the name parameter. If the named logger already exists, then the existing instance will be returned. Otherwise, a new instance is created.

I understand that if I do the per class way, and let's say that I have 50 packages in a Java EE application, and 10 classes per package, I will have 500 logger instances in my app!

I come from a C, C++ and C# perspective, and always in my mind I have the following:
"Use memory sparingly, create instances only as needed, cleanup after yourself, don't abuse etc..."

I don't know the actual details of the logger creation, and I understand the idea of being able to better filter log results, but can anyone explain me why to go that way and how useful it is in the end, to create instance per class, why waste memory and have many instances, instead of just calling a logger method with a parameter?

EDIT

While maybe it's true, that in general people do not care about the many so called "lightweight" logger instances created, I ended up with my colleagues on the project to create a wrapper class for log4j, that I instance in every class where I want to use logger. This wrapper class contains a reference to a single instance of logger by default

Logger.getLogger(Wrapperclass.getName())

and also the name of the class where this specific logger is called, so to log the logging class name. In the case when I will need specific classes to be logged, I will just change the

Logger.getLogger(Wrapperclass.getName())

to

Logger.getLogger(Callingclass.getName())

rebuild the app and run it. In my opinion this solution seems more clean and neat.

EDIT 2:

Found out this:

Based on our previous work on log4j, logback internals have been re-written to perform about ten times faster on certain critical execution paths. Not only are logback components faster, they have a smaller memory footprint as well

Based on the quote above, in which we can clearly see the phrase containing "smaller memory footprint", I can make the conclusion that my suspicions weren't so false. With the team we now take into the consideration the idea of switching to logback if we will be able to achieve the same logging functionality we need and do with log4j.

Hope that this question helps others make the right decision!

Was it helpful?

Solution

There seems to be a mismatch between what you mean by the word "logger" and what the Log4J framework means with "logger".

Within the Log4J framework, a logger is a very lean class. It is not much more than a wrapper around the ThisIdentifier that you use and an container for functions that generate logging statements.
All the heavy lifting of the logging happens in the Appenders, Filters and Layouts.

As stated in the Log4J architecture

Logger

As stated previously, Loggers are created by calling LogManager.getLogger. The Logger itself performs no direct actions. It simply has a name and is associated with a LoggerConfig. It extends AbstractLogger and implements the required methods. As the configuration is modified Loggers may become associated with a different LoggerConfig, thus causing their behavior to be modified.

So, having several hundreds of Logger instances does not put any burden of consequence on your system.

Licensed under: CC-BY-SA with attribution
scroll top