Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any reason to use private instead of private final static on the LogBack Logger?

Tags:

When instantiating Logger in a Spring Controller, is there any reason to declare it as a static final? The Logger is not used outside MyController.class. I've seen both examples in use, but can't see why I should use one or the other.

private Logger logger = LoggerFactory.getLogger(MyController.class); 

vs

private static final Logger logger = LoggerFactory.getLogger(MyController.class); 
like image 271
Tommy Avatar asked Nov 24 '11 20:11

Tommy


People also ask

Should logger always be static?

Loggers should be declared to be static and final. It is good programming practice to share a single logger object between all of the instances of a particular class and to use the same logger for the duration of the program.

Why do we declare logger static final?

Because that is usually the kind of functionnality that can be shared accross all instances of your objects. It does not make much sense (90% of the time) to have a different logger for two instances of the same class.

What is the use of Loggerfactory getLogger?

getLogger(java. lang. String): This method is used to find or create a logger with the name passed as parameter. It will create a new logger if logger does not exist with the passed name.

What is additivity in Logback?

1.2 Logback Additivity Appenders are added to the loggers. One logger may include more than one appenders. Thus, its log messages are written more than one desired destination systems. Additivity is exactly about this point. The output of a log statement of logger A will go to all the appenders in A and its ancestors.


2 Answers

Personally, I use

private final Logger logger = LoggerFactory.getLogger(this.getClass()); 

The main advantage of this is I can cut and paste this into new classes without having to change the name of the class.

As for whether or not they should be static, please see Should Logger members of a class be declared as static?, from the slf4j website, which says:

We used to recommend that loggers members be declared as instance variables instead of static. After further analysis, we no longer recommend one approach over the other.

Taken from that page:

Advantages for declaring loggers as static

  1. common and well-established idiom
  2. less CPU overhead: loggers are retrieved and assigned only once, at hosting class initialization
  3. less memory overhead: logger declaration will consume one reference per class

Disadvantages for declaring loggers as static

  1. For libraries shared between applications, not possible to take advantage of repository selectors. It should be noted that if the SLF4J binding and the underlying API ships with each application (not shared between applications), then each application will still have its own logging environment.
  2. not IOC-friendly

Advantages for declaring loggers as instance variables

  1. Possible to take advantage of repository selectors even for libraries shared between applications. However, repository selectors only work if the underlying logging system is logback-classic. Repository selectors do not work for the SLF4J+log4j combination.
  2. IOC-friendly

Disadvantages for declaring loggers as instance variables

  1. Less common idiom than declaring loggers as static variables
  2. higher CPU overhead: loggers are retrieved and assigned for each instance of the hosting class
  3. higher memory overhead: logger declaration will consume one reference per instance of the hosting class

Explanation

Static logger members cost a single variable reference for all instances of the class whereas an instance logger member will cost a variable reference for every instance of the class. For simple classes instantiated thousands of times there might be a noticeable difference.

However, more recent logging systems, e.g log4j or logback, support a distinct logger context for each application running in the application server. Thus, even if a single copy of log4j.jar or logback-classic.jar is deployed in the server, the logging system will be able to differentiate between applications and offer a distinct logging environment for each application.

More specifically, each time a logger is retrieved by invoking LoggerFactory.getLogger() method, the underlying logging system will return an instance appropriate for the current application. Please note that within the same application retrieving a logger by a given name will always return the same logger. For a given name, a different logger will be returned only for different applications.

If the logger is static, then it will only be retrieved once when the hosting class is loaded into memory. If the hosting class is used in only in one application, there is not much to be concerned about. However, if the hosting class is shared between several applications, then all instances of the shared class will log into the context of the application which happened to first load the shared class into memory - hardly the behavior expected by the user.

For more information, see that page.

like image 171
Matthew Farwell Avatar answered Oct 16 '22 21:10

Matthew Farwell


Just private field will be initialised for each instance of your class. However, private static field will be initialised one time per class.

In case of logger most probably (depends on logging implementation), in both cases you will get the same instance of logger and you won't use noticeably bigger amount of memory. But still LoggerFactory.getLogger will be called with every object you create.

like image 33
Aleksejs Mjaliks Avatar answered Oct 16 '22 21:10

Aleksejs Mjaliks