I decided to use Log4J logging framework for a new Java project. I am wondering what strategy should I use for creating/managing Logger instances and why?
Common convention is "a logger pr class and use the class name as its name". This is good advice.
My personal experience is that this logger variable should NOT be declared static but an instance variable which is retrieved for each new. This allows the logging framework to treat two calls differently depending on where they come from. A static variable is the same for ALL instances of that class (in that class loader).
Also you should learn all the possibilities with your logging backend of choice. You may have possibilities you did not expect possible.
If your application is following SOA principles, for every service A you'll have the following components:
So it makes life easier to have a aController.log aService.log aExecutor.log and aPersistance.log
This is a layer based separation so all your Remoting/REST/SOAP classes will write to the aController.log
All your scheduling mechanism, backend service etc will write to aService.log
And all task executions are written to aExecutor.log and so on.
If you have a multi-threaded executor you might have to use a log accumulator or another technique to properly align log messages for multiple threads.
This way you'll always have 4 log files which is not alot and not too less, I'm telling you from experience this makes life really easier.
When deploying multiple EARs / WARs, it may be better to package the log4j.jar higher up in the classloader hierarchy.
i.e. not in WAR or EAR, but in the System-classloader of your container, otherwise multiple Log4J instances will write to the same file concurrently leading to strange behaviour.
The strategy that is most used is to create a logger per class. If you create new threads give them a usefull name, so their logging is easily distinguishable.
Creating loggers per class has the benefit of being able to switch on/off logging in the package structure of your classes:
log4j.logger.org.apache = INFO
log4j.logger.com.example = DEBUG
log4j.logger.com.example.verbose = ERROR
The above would set all apache library code to INFO
level, switch logging from your own code to DEBUG
level with the exception of the verbose package.