Implement logging in your applications with Log4[insert-language]

In my Information Architecture class we’ve been discussing the benefits of logging and best practices for implementing logging in your applications. Because logging seems to be such a tedious task, it is something that is often overlooked or neglected in custom software development projects.

It seems that it is too much work to open up a handle to write to a log file just to record that an event happened on your server. Add the complications of rolling log files to older versions as soon as you log files reach a certain size, and it seems that logging events in your application is overkill. I used to think this way until I was introduced to Log4J and its ports.

Log4J is a Java library that was written to solve all of your logging needs. It provides a simple interface for logging messages as easy as logger.debug("Error encountered..."); which can be configured to output to a log file, an SMTP email message, a database record, a network socket, a console, or even a Jabber client for instant message alerts.

Log4J offers different levels of debugging, which allows developers to log debugging information all over the application, and then simply switch off that level of log messages with a simple configuration file.

The levels of logging include:

  • Trace
  • Debug
  • Info
  • Warn
  • Error
  • Fatal

If the configuration file is set to trace-level logging, then messages will be logged for everything below it as well. Debug-level logging will ignore trace statements, and info-level logging will ignore both trace and debug.

Making log calls at the different levels is extremely easy. It’s just a matter of calling the right method on your logger object. Here are some example calls that can be used:

logger.trace("Use this instead of print lines");
logger.debug("SQL: " + sqlStatement + "Executed in: " + executionTime );
logger.info("invalid login attempted at: " ipAddress);
logger.warn("a warning statement");
logger.error("could not connect to socket");
logger.fatal("application crashed");

This type of logging is pretty simple and straight forward.

Another really cool thing about Log4J is that you can specify the format of your log messages in the log file. If you want to capture timestamps, class name and line number of a log message, etc. you can set that up all in the configuration file.

Log4J can also automatically roll your log files at certain size limits and set to only keep X number of rolled log files so that you don’t eat up your entire hard disk and crash your system.

Because Log4J has made logging so simple and easy, Log4* ports have been created for several other languages including C, C++, .NET, PHP, Ruby, Perl, and even JavaScript.

I wish I would have known about this years ago so that I could have taken advantage of easy logging in php and Java.

Mobilefish.com has posted a simple tutorial on using Log4J. I recommend checking it out.

5 thoughts on “Implement logging in your applications with Log4[insert-language]”

  1. Check out Chainsaw from the log4j folks (http://logging.apache.org/log4j/docs/chainsaw.html) – you can use it to receive log events sent by log4j, java.util.logging, log4net, log4php and log4cxx.

    It also can also process log events stored in a database, or any log file with a consistent file format (for example, you could use Chainsaw and a LogFilePatternReceiver to process logfiles generated by Ruby’s Logger class).

  2. Thanks Scott!

    I could see that coming in very useful when managing multiple applications written in different languages on various platforms.

  3. I´m developing a Web Application with Java and I need to save trace information on a file. Can I do it that?
    I need some help.
    My App is on Sun Application Server 8.0.

  4. You should be able to log that type of information from catching the exception and logging the trace. I don’t know what the exact syntax would be for Java, but I do it in Ruby all of the time.

  5. Anyone got a tip on how to separate the logging to separate files based on class? I.e i want com.foo.* packages logged to log1.txt and com.bar.* packages logged to log2.txt. Sooo confusing with all these appenders

Comments are closed.