Log don't SOP

Stick to basics. This is generally my opening line to any discussion around best architecture and coding practices.

People - particularly those who are newcomers (say who have spent less than 5 years in the IT industry) - tend to feel a bit cheated with this statement. Generally the expectation is that we will discuss what I term as *ity ( flexibility, modularity, scalability, ...). I generally tend to swipe all those glamorous words aside and talk about just the basics. I leave the *ity discussions to salesperson of frameworks and products.

Ranting aside, I wanted to talk about one of the basic practices that I think is grossly underutilized. Logging and auditing. Particularly I wanted to talk about logging in this article. Auditing, in my mind, is limited by the quality of logging that we have (of course that is not strictly true in all scenarios, but you get the general idea, I hope).

As far as logging is concerned, I maintain that all professional code, need to have a well thought out logging strategy. Period. I have heard all sort of excuses and logic against it - too small code, not really strategic, don't have time etc etc - and my personal stand is, I don't buy any one of those excuses against logging. If you need to put in a single "System.out.println" in your code, don't. Put a logger.debug instead.

Logging framework / tool is free. It is simple. It could do what System.out.println would have done. It could do much much more. You should have put a logger anyway. Just take a deep breath, break the habit of System.out.println, follow the simple steps that I have mentioned here, do yourself and your project a good karma.

What do I need to do to use logger instead of using System.out.println()?


Use log4j. You could use logback. It's your choice. I am just giving a vanilla version that works.

You could just get the jars and put them in your classpath. If you are using Maven (and in my humble opinion you should) you could just tell pom to use log4j with slf4j. It will give you the flexibility to move to logback on a later day if you so wanted. Add these dependencies.
<!-- Logging -->
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>${slf4j.version}</version>
</dependency>
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>jcl-over-slf4j</artifactId>
 <version>${slf4j.version}</version>
 <scope>runtime</scope>
</dependency>
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>${slf4j.version}</version>
 <scope>runtime</scope>
</dependency>
Mention the correct version. I am using 1.6.1 in the example below. I guess the latest is 1.6.4 at the time of writing this article. Feel free to check that out. 

<properties>
...
<slf4j.version>1.6.1</slf4j.version>
... 
</properties>


Configure log4j to write to console like the System.out.println would have done. In my case the configuration file is at /src/main/resources/log4j.properties. I use Maven. If you dont use Maven, the basic fundamental is that this configuration should be available at the classpath. 

# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1

# configure A1 to spit out data in console
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout 
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n


That's if you are done with all the configurations. Now in each of your classes, before you do anything else, put in the following line. 

private final static Logger logger = LoggerFactory.getLogger(YourClass.class);

And wherever you need to write a System.out.println(message) write the following 
logger.debug(message); 
So, instead of just writing System.out.println (and being lazy) you logged the message (and did the right thing). It took you all of 10 minutes (ok, lets be really generous with time and account for the coffee breaks, it took you half a day) to get the logging framework in place.

It means you will never have to go back and cleanse your code of System.out.println(). It means you will never have to go and face the customer / client and explain the funny messages showing up on console. It means you will always have a nice way of switching on debugging in production when you need. You will be able to switch on debugging and switch off really easily. I can go on and on about the benefits.  But I hope the point has been proved that the 10 minutes (or half a day as the case might be) is definitely worth it.

So, that's one more discussion about "sticking to basics". Happy coding.
If you want to get in touch, you can look me up at Linkedin or Google + .

1 comment:

  1. Nicely explained. I agree there is no real excuse for not using logging framework.

    ReplyDelete