A Simple log4j Example
The application uses five servlets (
SetupServlet (which runs when your servlet engine starts up),
RegisterServlet); four JSPs (
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
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
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-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,email@example.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.
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
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 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
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:
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.
- 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.
- 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.
- Start logging using any of the methods of the logger you acquired in step 2 (
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
SimpleLayoutthat 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.