ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Build Flexible Logs With log4j
Pages: 1, 2, 3

A Simple log4j Example

The application uses five servlets (SetupServlet (which runs when your servlet engine starts up), LogonServlet, GetCommentsServlet, ForgotPasswordServlet, RegisterServlet); four JSPs (forgotpassword, logon, register, welcome); and a file-based database for storing user information (userDB, which should be in the WEB-INF folder; make sure that the path to it is correct in the web.xml file).



To see the example in action, deploy the log4jdemo.war file in your servlet engine. Once deployed, modify the web.xml file to make sure that the SetupServlet's init parameter for the props file contains the location of config-simple.properties. This file is in the WEB-INF directory of the deployed application (and so are three other configuration files: config-JDBC, config-MDC, and config-NDC). Restart your server. On your server's console, some messages will appear. If the StartupServlet was able to find userDB, you'll probably see messages like this on the screen:

Using properties file: 
C:\jakarta-tomcat-4.0.1\webapps\Log4JDemo\WEB-INF\config-simple.properties
  Watch is set to: null
  DEBUG - Added line: JohnDoe,herbert,johndoe@john.com,John Doe

The first two statements appearing on the screen are simple System.out.println statements. The next one and the ones after that, if any, are through log4j. Let us see how this was done.

Open up config-simple.properties in a text editor. It contains three lines (besides comments). The first line, log4j.rootLogger=debug, R tells log4j that the level of the root logger is at DEBUG. This is the default and is not required. The value after the comma, R, is required. It tells log4j that the root logger has an appender attached to it and that the name of the appender is "R." The rest of the lines in this file tell log4j about the properties of this appender R.

The line log4j.appender.R=org.apache.log4j.ConsoleAppender tells that this particular appender R is of the type ConsoleAppender; in short, that it will write to the console. The line log4j.appender.R.layout=org.apache.log4j.SimpleLayout tells log4j to use the simple layout, which, as you will see on the screen, simply writes two things: the level of the log request and the actual log message.

Now that we have understood the configuration of our simple example, lets see how we are actually logging in our code. Open up SetupServlet.java in a text editor and look up line 81:

PropertyConfigurator.configure(props);

Ignore the other statements around it for the moment. This particular line tells log4j to look up a file referenced by the variable props and use it to configure log4j's settings. This is the same file we just looked at, config-simple.properties. This line needs to be called once in your whole application, typically at the start of your application. A startup servlet is ideally suited to do this configuration in a Web application, as it is run when the servlet engine starts.

Having configured our log4j settings, we are ready to start logging. The next step is to get hold of a logger and use it to write our log statements. We can do this either using the root logger by invoking the Logger.getRootLogger() method, or, as we have done, by getting a logger of the class we are in, SetupServlet. This gives us a logger by the name of demo.log4j.servlet.SetupServlet) by invoking the following line:

Logger log = Logger.getLogger(SetupServlet.class);

These methods return to you an object of the type Logger that we call our logging requests on. So, for example, on line 112 we have invoked the DEBUG method of this logger: log.debug("Added line: " + data);. And this is what we see on our console. Note that since in our configuration file we had set the level of our root logger at DEBUG, and we had not set any level for the demo.log4j.servlet.SetupServlet logger, our demo.log4j.servlet.SetupServlet logger also inherits this level. So when we say log.debug("Added line: " + data); from within our class, this log request is sent to our appender (ConsoleAppender). Try changing the level of the root logger to ERROR. The earlier line(s) will disappear, as the level of the logger has become higher than the actual log request. Note that to change the level of the root logger, you only need to modify the configuration file and restart your servlet engine (although it is not necessary if you are using configureAndWatch -- I will cover this in the "Tips and Tricks" section).

This completes our simple example. Let us recap what needs to be done in order to start using log4j in a simple example.

  1. Write a configuration file. In this file:
    • Specify the level of the root logger and attach an appender to it.
    • Specify the properties of the appender.
    • Specify a layout for the appender.
  2. In your code, get hold of a logger by class or name. Typically, this should be the logger associated with the class that you are currently in.
  3. Start logging using any of the methods of the logger you acquired in step 2 (log.debug(), log.info(), log.warn(), log.error(), log.fatal()).

Management Requirements

Although we have completed a fairly simple example and seen the power of log4j, our simple example will fall short in the real world. Let me point out the shortcomings in our simple example, as I am sure your boss would if he saw it!

  • Logging on the console is tiresome and requires someone to be constantly monitoring it for ERROR or FATAL levels.
  • The SimpleLayout that we used is too simple. The information that it provides is minimal.
  • In a Web-based application, different users accessing various servlets will generate a variety of log messages. It can become very difficult to identify, separate, and isolate messages coming from different users accessing the application.

Let us see how we can cover these problems with log4j. I will not elaborate much on the second point, as it is a simple matter of replacing the SimpleLayout with the PatternLayout and specifying a conversion pattern for it. Let me point you to the Javadoc of the PatternLayout for all of the available conversion patterns.

Pages: 1, 2, 3

Next Pagearrow