Around IT in 256 seconds

Clean code, clean logs: log method arguments and return values (7/10)

May 16, 2010 | 2 Minute Read

When you find a bug during development, you typically run a debugger trying to track down the potential cause*. Now imagine for a while you can’t use a debugger. For example, because the bug manifested itself on a customer environment few days ago and everything you have are logs. Would be able to find anything in them?

If you follow the simple rule of logging each method input and output (arguments and return values), you don’t even need debugger any more. Of course, you must be reasonable but every method that: accesses external system (including database), blocks, waits, etc. should be considered. Simply follow this pattern:

public String printDocument(Document doc, Mode mode) {
log.debug("Entering printDocument(doc={}, mode={})", doc, mode);
String id = //Lengthy printing operation
log.debug("Leaving printDocument(): {}", id);
return id;

Because you are logging both the beginning and the end of method invocation, you can manually discover inefficient code and even detect possible causes of deadlocks and starvation – simply by looking after "entering" without corresponding "leaving". If your methods have meaningful names, reading logs would be a pleasure. Also analyzing what went wrong is much simpler as on each step you know exactly what has been processed. You can even use a simple AOP aspect to log a wide range of methods in your code. This reduces code duplication, but be careful, since it may lead to enormous amount of huge logs (do you know what you are logging?)

You should consider DEBUG or TRACE levels as best suited for these types of logs. And if you discover some method are called too often and logging might harm performance, simply decrease logging level for that class or remove the log completely (maybe leaving just one for the whole method invocation?) But it is always better to have too much rather than too few logging statements. Treat logging statements with same respect as unit tests – your code should be covered with logging routines as it is with unit tests. No part of the system should stay with no logs at all. Remember, sometimes observing logs rolling by is the only way to tell whether your application is working properly or hangs forever.

* If you start by writing failing test case exposing the bug, my congratulations, I am proud of you!

Tags: aop, logging

Be the first to listen to new episodes!

To get exclusive content: