[ Team LiB ] Previous Section Next Section

Recipe 14.5 Using a Pattern with a Logger's Appender

Problem

You want to create your own logger for a servlet and give the logger an appender.

Solution

Include the appender configuration in the log4j.properties file.

Discussion

This recipe creates a new logger, which brings us to the discussion of log4j's inheritance structure. The root logger is the "super logger" that all logger's inherit from, similar to java.lang.Object in Java's object oriented programming setup. Example 14-7 creates a new logger named com.jspservletcookbook, which inherits the root logger's level (DEBUG) and console appender (named cons). Example 14-7 also creates an appender for the com.jspservletcookbook logger. Place this log4j.properties file in the WEB-INF/classes directory.

Example 14-7. The configuration for a logger named com.jspservletcookbook
log4j.rootLogger=DEBUG, cons
log4j.logger.com.jspservletcookbook=, myAppender

#the root logger's appender
log4j.appender.cons=org.apache.log4j.ConsoleAppender

#the com.jspservletcookbook logger's appender
log4j.appender.myAppender=org.apache.log4j.RollingFileAppender

log4j.appender.myAppender.File=h:/home/example.log

log4j.appender.myAppender.MaxBackupIndex=1

log4j.appender.myAppender.MaxFileSize=1MB

#the root logger's layout
log4j.appender.cons.layout=org.apache.log4j.SimpleLayout

#the com.jspservletcookbook logger's layout
log4j.appender.myAppender.layout=org.apache.log4j.PatternLayout

log4j.appender.myAppender.layout.ConversionPattern=%-5p Logger:%c{1}
Date: %d{ISO8601} - %m%n

You probably noticed the similarity between package names and the name of the new logger in Example 14-7: com.jspservletcookbook. log4j uses a naming scheme based on Java's. Here's the basic rundown on this scheme:

  • All loggers inherit from the root logger.

  • All loggers whose name contains a prefix that matches a configured logger's name (such as com.jspservletcookbook) also inherit from that configured logger. Therefore, a logger named com.jspservletcookbook.LoggerWconfig derives its characteristics from the com.jspservletcookbook logger.

In Example 14-7, the com.jspservletcookbook logger specifies that it will use an appender named myAppender. The myAppender appender is a rolling file appender, which is a log file that automatically creates a backup file when the original log reaches a certain size. The appender is based on the Java class org.apache.log4j.RollingFileAppender, which is among the set of classes that log4j uses.

If you look at the Javadoc for that class, then you see that it has a bunch of methods that look like getXXX( ), where XXX is one of the logger's properties. You set these properties of the appender in the configuration file by giving each property a value. To set the myAppender appender's File property, the syntax is:

log4j.appender.myAppender.File=h:/home/example.log

This configuration element specifies the file location where the appender will log its messages. When this file reaches its MaxFileSize of 1 MB, log4j renames the file example.log.1 and creates a new example.log to receive log messages. The MaxBackupIndex means that log4j will create only one backup file.

The Javadoc for RollingFileAppender can be found at: http://jakarta.apache.org/log4j/docs/api/org/apache/log4j/RollingFileAppender.html.


Example 14-7 also specifies a layout for the com.jspservletcookbook logger, and a rather elaborate one at that:

log4j.appender.myAppender.layout=org.apache.log4j.PatternLayout

log4j.appender.myAppender.layout.ConversionPattern=%-5p Logger:%c{1} Date: 
%d{ISO8601} - %m%n

The first line specifies that the myAppender layout will use an org.apache.log4j.PatternLayout, which is based on the conversion pattern of the printf function in C, according to the PatternLayout Javadoc. This pattern language combines literal text and conversion specifiers to generate a formatted log message. The conversion specifiers are letters (like c) that have special meanings as placeholders. For example, the letters may represent dates or logger names.

The % character precedes the conversion pattern symbols. For example, consider the following pattern:

Logger:%c{1}

This translates to "the literal text `Logger:' followed by the logger's name." The number 1 in curly braces ({1}) following the %c characters is a precision specifier, which means "display just one segment of the name beginning from the righthand side." If the logger is com.jspservletcookbook.LoggerServlet, then the %c{1} pattern displays "LoggerServlet" in the log text. This is because the c conversion specifier is a placeholder for the logger name.

The letter m displays the log message itself, the letter n produces the platform-specific line separator, and the letter d represents the date. The entire string %d{ISO8601} is a log4j date formatter, which displays the date in detailed form. See http://jakarta.apache.org/log4j/docs/api/org/apache/log4j/helpers/ISO8601DateFormat.html.

Example 14.8 shows a servlet that uses a logger that inherits its characteristics from two configured loggers: the root logger and the com.jspservletcookbook logger.

Example 14-8. A servlet uses a descendant logger
package com.jspservletcookbook;           

import org.apache.log4j.Logger;

import javax.servlet.*;
import javax.servlet.http.*;

public class LoggerNewConfig extends HttpServlet {

private Logger log = null;

  public void init( ){
      
      //the logger's name is the same as the class name:
      //com.jspservletcookbook.LoggerNewConfig
      log = Logger.getLogger(LoggerNewConfig.class);
      
      log.info("LoggerNewConfig started.");
  }

  public void doGet(HttpServletRequest request, 
    HttpServletResponse response)
      throws ServletException, java.io.IOException {
    
      //display a DEBUG-level message
      log.debug("Sending a DEBUG message");

      // display an INFO-level message
      log.info("Sending an INFO message");
    
      //better display some HTML
      response.setContentType("text/html");
      java.io.PrintWriter out = response.getWriter( );
      out.println(
        "<html><head><title>Servlet logging</title></head><body>");

      out.println(
      "<h2>Hello from a Logger with its own configuration in the "+
      log4j.properties file</h2>");

      out.println("Your logger name is: " + log.getName( )+"<br>");

      out.println(
        "Your logger parent is: " + log.getParent( ).getName( )+"<br>");

      out.println("</body></html>");
  } //end doGet
}

The static org.apache.log4j.Logger.getLogger(Class className) method creates a logger named after the class in Example 14.8 (com.jspservletcookbook.LoggerNewConfig). Therefore, this new logger inherits the appender that the properties file in Example 14-7 set up for the logger com.jspservletcookbook, because the new logger's name has com.jspservletcookbook as a prefix. In fact, any other logger created in classes that are part of the com.jspservletcookbook package inherits these properties, as long as the developer keeps naming her loggers after the Java class in which they are created.

Here is an example of what the entire pattern the configuration file of Example 14-7 created generates in the log file:

INFO  Logger:LoggerNewConfig Date: 2003-07-10 17:16:22,713 - LoggerNewConfig started
DEBUG Logger:LoggerNewConfig Date: 2003-07-10 17:16:34,530 - Sending a DEBUG message
INFO  Logger:LoggerNewConfig Date: 2003-07-10 17:16:34,530 - Sending an INFO message

Visit http://jakarta.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html for more details on pattern layouts.

Because of the inheritance structure established by the log4j configuration file, the servlet in Example 14-8 also logs its messages to the console.


See Also

Recipe 14.2 on downloading and setting up log4j; Recipe 14.3 on using a log4j logger without a properties file; Recipe 14.4 on adding an appender to the root logger; Recipe 14.6 on using loggers in JSPs; Recipe 14.7 and Recipe 14.8 on using log4j with application event listeners; the log4j download site: http://jakarta.apache.org/log4j/docs/download.html; the log4j Javadoc page: http://jakarta.apache.org/log4j/docs/api/index.html; the log4j project documentation page: http://jakarta.apache.org/log4j/docs/documentation.html.

    [ Team LiB ] Previous Section Next Section