When coding, people usually program to print out certain information , and that’s the “logging” I am talking about.
In this post I would like to share some experience about good practices of logging in Java, mostly with SLF4J. But those tips should be applied for other logging frameworks (Apache commons-logging, log4j or JUL, etc) .
(I’ll briefly state the practices, when I have more spare time I will update this post to make a longer explanation)
.
Use static logger
“private” and “static” are good, and it can be “final” most of the times.
private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class.getName());
.
Get logger by String
Favour getName() (or getCanonicalName() ) over Class object when passing param to factory method, to avoid memory leak.
private static Logger logger = LoggerFactory.getLogger(MyClass.class.getName());
.
Use approriate level (priority) for log message
For exceptions you can use ERROR level, for accepted exceptions you can use WARN, main information should be INFO, and more details for debugging is DEBUG , … (nowadays it’s common knowledge of developer, I guess).
Then in the logging configuration, you can adjust the level of some certain packages to reduce the noise, or get more logging information to debug easier.
.
Don’t pollute the code with “performance” check
Those checkings such as “isDebugEnabled()” , is making the code complicated, lengthy and less readable (at least). It’s not worth the performance saving, in fact. I’m sure 99% the times you can “optimize” a lot of other things before consider logging which has very minor impact.
If you still insist on that, I would recommend using SLF4J as main logging framework, which have a handy syntax for that and still efficient:
http://slf4j.org/faq.html#logging_performance
.
Separate big log file to smaller files
Not necessary to seperate by “functions” since it’s usually better to have a “central” log file then mixed files. However a central log file will grow size quickly so we can utilize the logging framework to seperate to smaller files by date (for example: server.log, server.20121020.log, server.20121021.log, … ) .
If daily files are still big, you can also utilize the framework to seperate by size too. That means when the file size reach a certain size (50MB, 20MB, YMMV… ) , the log files are split (and still by date): server.log, server.20121020-1.log, server.20121020-2.log, server.20121020-3.log, . . .
.
Prefer logging over comment in code
It’s obvious that user can read both at compile time, but logging is much more useful at runtime or later. Look at below code and think over it:
try { // set some variable } catch ( Exception e ) { // do nothing } // if variable is null, tell user there was a problem
.
Keep stacktrace info when logging exceptions
The mentioned frameworks all have a log methods which reserve the stacktrace when logging exceptions. Use it to help more infor when the exception occurs.
try { // do some nasty thing } catch ( NumberFormatException e ) { LOGGER.error("Unable to format number: " + e.getMessage(), e); }
Log things once per happening
Duplicated log messages are noisy, confusing, and eventually counter-productive.
.
Use format wisely
The patterns (timestamp, class+method+line, thread id, …) should be used approriately, depending on the application. But it should be enough information on a single line, so that it can be “grep”ed and split easily.
It’s wise when the log convey its messages in a succint but informative way.
.
AOP can help logging sometimes
For example, when you want to log the entrance and exit of some methods, AOP is recommended (if possible).
In such cases, AOP reduces duplication and boiler-plate typing.
.
.
./.
Pingback: Dan ong 30 | DucQuoc's Blog
Pingback: Learnt or Learned | DucQuoc's Blog
Pingback: 5 cm 1 second | DucQuoc's Blog