Logging involves sending messages from your application and displaying this information in a variety of ways for web developers and administrators. The messages can be delivered to a console, or they can be stored persistently in files or databases. Logging may be used only for sending debug- related information while a web application is being developed, or these messages may provide information from an application in production, including data about warnings and fatal errors.
This chapter describes a very powerful open source logging tool called log4j . This is a Java ARchive (JAR) file ( log4j-1.2.8.jar ) that you can add to your web application by placing it in your WEB-INF/lib directory. This makes it available for use in any servlets or beans that you want to send logging messages from. This section provides only a brief introduction to log4j , because its power does entail some complexity.
log4j involves three main concepts: loggers , appenders , and layouts . log4j uses an external configuration file, similar to a deployment descriptor, to configure these three logging elements. The upcoming recipes provide some examples of these configuration files, which are mostly simple text files involving a list of name /value pairs. The power of using external files is that you can change the properties in these text files to alter a logger (for instance, modify the format of its messages) instead of recompiling the servlet code.
A logger is the entity that a servlet uses to log messages. To use one, import the log4j classes into the servlet, create an instance of a logger ( specifically an org.apache.log4j.Logger ), then call the logger's methods. The methods are named after the logging level of the message. For example, to log an informational message (an INFO level) you would call:
logger.info("HttpServlet init method called.");
log4j has five different levels of log categories: DEBUG , INFO , WARN , ERROR , and FATAL . The log categories are organized in ascending order beginning with DEBUG ”a logger configured for INFO -level logging logs only INFO , WARN , ERROR , and FATAL messages (but not DEBUG -level messages, because in this hierarchy DEBUG is beneath INFO and the other levels). Here is a brief description of the purpose of each level:
Every logger is configured with a level (such as DEBUG ) in the log4j properties or configuration file (see Recipe 14.4). log4j also associates the messages that you log with a specified level, which makes it easy to use because the method names are the same as the level names . The logger does not send these messages unless the logger's level is equal to or greater than the level represented by the method call (as in logger.debug( Object message ) ).
For example, let's say you configure the logger with a level of DEBUG , then develop a servlet with a number of logger.debug( Object message ) calls.
Later, you can change the configuration file and give the logger an INFO level. Changing the configuration in this manner "turns off" DEBUG -level logging in that servlet, so that these logging messages no longer show up in the log files, database, or other logging repository. This is because DEBUG is not equal to or greater than INFO in the hierarchy of logging categories.
Similarly, you can turn back on DEBUG -level logging in the prior example by simply switching the logger's configuration back from INFO to DEBUG . As a result, the debug-level messages will no longer be filtered out.
Programmers writing software with several DEBUG -level method calls can easily switch into WARN - or ERROR -level debugging once the application moves into its next stage of development, or goes into production.
log4j is also very powerful in terms of the different ways you can log messages. You can use log4j to log messages to a console, a file, a rolling file (which automatically creates a backup file when a log file reaches a specified size), a database, an email server, and several other types of log repositories. log4j calls each of these logging mechanisms an appender . Recipe 14.4 introduces the configuration file in which you can describe appenders.
What does the actual logged message look like? What information does it include? log4j shines in this area too. You can specify numerous different layouts for the messages using the log4j configuration file. log4j lets you specify very complex (or simple) layouts using conversion patterns , which are somewhat similar to regular expressions. To achieve the most basic layout, you can specify an org.apache.log4j.SimpleLayout . With this format, the log contains the level name, followed by a dash ( - ) and the actual message:
INFO - HttpServlet init method called.
Using an org.apache.log4j.PatternLayout is more powerful, and Recipe 14.5 provides some examples of different layouts for logging messages.