综合

img httpnet

18.2 Log4J in a Web Application

发表于2004/11/3 23:27:00  1380人阅读

Now that we have the basics of Log4J we shall move on to using it in a Java web application. The developer of the application would usually add the logging statements before it is handed to the administrator. However, it is useful to know the syntax and usage of the different options available. We'll start off by using the simple example again, but this time we'll use it from a JSP page in a web application called logging. First though, we need to configure the Logger.

现在我们已经有了Log4J的基础,我们将转移到在一个Java Web应用程序中使用它.
我们再一次通过一个简单的例子出发,但这次我们从Web应用程序中的JSP页调用.首先,我们需要配置
Logger.

Configuring a Logger in a Web Application

在Web应用程序中配置Logger

.As we saw earlier, the easiest way to configure a Logger was to use a configuration file. When using Log4J in a web application it is a good idea to set up a Logger for the entire web application at startup. This can be achieved by using an initialization servlet that loads the configuration file into the web application.

前面我们看到,配置Logger最容易的方法是使用配置文件,当在Web应用程序中使用Log4J时,在启动时为整个应用程序设置一个Logger是一好想法.这可以通过使用一个初始化Servlet完成,它在启动的时候加载配置文件到应用程序中.

The Initialization Servlet

Here is the initialization servlet:

   package wrox;

   import javax.servlet.ServletException;

   import javax.servlet.http.HttpServlet;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;

   import java.io.PrintWriter;
   import java.io.IOException;

   import org.apache.log4j.PropertyConfigurator;

   public class Log4JInitServlet extends HttpServlet {

应用范围内的配置都在init()方法中调用,当Servlet第一次被Tomcat加载的时候,init()方法被自动调用.The application-wide configuration happens in the init() method. 使Logger自启动后就可以是用:

      // Initialize the servlet by loading the Log4J properties file
      public void init() throws ServletException {

The properties file will be stored in the $CATALINA_HOME/webapps/logging/WEB-INF/classes directory of our web application. We need to get the path to the properties file before we can load it, so we get the full path to the web application on the filesystem and then append the name of the file. In this case, the name of the file comes from the properties initialization parameter specified in web.xml. This allows us to specify the location of the properties file outside of the application's code:

属性文件被存储在Web应用程序的 $CATALINA_HOME/webapps/logging/WEB-INF/classes 目录中,在我们加载它之前必须获得它的路径,因此
这允许我们指定应用程序代码之外属性文件的位置

        // First we get the fully qualified path to the web application
        String path = getServletContext().getRealPath("/");
        String properties = path + getInitParameter("properties");

The final step is to call the configure () method to make the Logger available for all the other files in the application:

        // Next we set the properties for all the servlets and JSP
        // pages in this web application
        PropertyConfigurator.configure(properties);
        }

The final methods are required to be in any servlet:

     // The doPost() method forwards all requests to the doGet() method
     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws
   ServletException, IOException {
       doGet(req, resp);
     }

     // The doGet() method informs users of the purpose of this servlet
     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws
   ServletException, IOException {
       PrintWriter out = resp.getWriter();

       out.println("Initialization servlet for Log4J");
     }

     public void destroy() {}
   }

Compile this class and place it in $CATALINA_HOME/webapps/logging/WEB-INF/classes/wrox.

web.xml

Next we need a web.xml file for our web application so that we can specify the location of our properties file:

   <?xml version="1.0" encoding="ISO-8859-1"?>

   <!DOCTYPE web-app
       PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
       "http://java.sun.com/dtd/web-app_2_3.dtd">

   <web-app>
     <servlet>
       <servlet-name>log4Jinit</servlet-name>
       <servlet-class>wrox.Log4JInitServlet</servlet-class>
       <init-param>
         <param-name>properties</param-name>
         <param-value>WEB-INF/classes/log4j.properties</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
     </servlet>
   </web-app>

The <load-on-startup> element loads the servlet when Tomcat is started. This is exactly what we want as we need the Logger to be available to the web application as soon as Tomcat starts.

Logging To Files

In this section we will start with a simple file example, then show the following formats that are made available to Log4J:

  • HTMLFormat

  • PatternFormat

Simple File

The configuration file for this first example is very similar to the one we saw before. However, this time we'll log to the $CATALINA_HOME/logs directory:

   # A simple logger
   log4j.logger.wrox.simple=DEBUG, simple

   # This simple example will log to a file
   log4j.appender.simple=org.apache.log4j.FileAppender
   log4j.appender.simple.File=<CATALINA_HOME>/logs/log4jsimple.log

   # We will use a simple layout for this example
   log4j.appender.simple.layout=org.apache.log4j.SimpleLayout

Note that Log4j does not consider <CATALINA_HOME> to be a shortcut; it is merely a neat piece of notation for us. Be sure and provide the full path in your files.

Save this file as log4j.properties in logging/WEB-INF/classes.

Finally, we need a JSP page to use the Logger (logsimple.jsp):

   <%@ page import="org.apache.log4j.Logger" %>
   <html>
     <head><title>Logging with Log4J</title></head>

     <%
     Logger logger = Logger.getLogger("wrox.simple");

     logger.debug("A debug message");
     logger.info("An info message");
     logger.warn("A warn message");
     logger.error("An error message");
     logger.fatal("A fatal message");
     %>

     <body>
       <h1>Logging completed</h1>
     </body>
   <html>

Place this in $CATALINA_HOME/webapps/logging. Now, point your browser at http://localhost:8080/logging/logsimple.jsp. You should see the confirmation message. This should have set off the Logger and written the logging messages to $CATALINA_HOME/logs/log4jsimple.log.

HTML

Now we will look at a different kind of Layout, the HTMLLayout. This Layout formats the logging information into HTML tables that can be customized to fit most needs. We shall send the logging information to an HTML file in the logging web application so that we can view it online. However, it would be possible to put this file under a password-protected context, such as admin in Tomcat 4.1.3 onwards.

Here is the configuration file:

   # An HTML logger
   log4j.logger.wrox.html=DEBUG, html

   # This simple example will log to an HTML file
   log4j.appender.html=org.apache.log4j.FileAppender
   log4j.appender.html.File=<CATALINA_HOME>/webapps/logging/log.html

   # This line stops additional log sessions being appended to the end
   # of the file
   log4j.appender.html.Append=false

   # We will use an HTML Layout for this example
   log4j.appender.html.layout=org.apache.log4j.HTMLLayout

   # This line shows where in the servlet/JSP page the logging
   # statement is placed
   log4j.appender.html.layout.LocationInfo=true

   # The Title parameter sets the HTML <title> tag for the HTML page
   log4j.appender.html.layout.Title=Wrox Log

The JSP page for this example, loghtml.jsp, has only one change:

    <%@ page import="org.apache.log4j.Logger" %>
    <html>
      <head><title>Logging with Log4J</title></head>

      <%
      Logger logger = Logger.getLogger("wrox.html");

      logger.debug("A debug message");
      logger.info("An info message");
      logger.warn("A warn message");
      logger.error("An error message");
      logger.fatal("A fatal message");
      %>

      <body>
        <h1>Logging completed</h1>
      </body>
    <html>

Access this page at http://localhost:8080/logging/loghtml.jsp and then view http://localhost:8080/logging/log.html. You should see something similar to the following:

 

Pattern

The final Layout that we will look at is the PatternLayout. This Layout allows us to specify a custom format for the logging messages. The format can be configured in a number of ways with various format modifiers and conversion characters playing their part. We saw one example earlier, but here is the example we will be using in this section:

   %-5p : %m %d{dd-MM-yy HH:mm:ss}%n

We have already seen the %m and %n conversion characters, as well as a different version of the %d character. This time we have specified a custom format for the date between the {} markers. The initial %-5p section can be further broken down into the -5 and %p blocks. %p displays a string representation of the priority (a throwback to earlier versions of Log4J when a Priority did the same job as a Level), that is, 'DEBUG', 'WARN', and so on. -5 is a format modifier that says 'right pad with spaces if the priority is less than 5 characters long'.

A full list of the format modifiers and conversion characters is available in the Log4J documentation: http://jakarta.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html.

We specify this pattern for our file as follows:

   # A pattern logger
   log4j.logger.wrox.pattern=DEBUG, pattern

   # This simple example will log to a custom format file
   log4j.appender.pattern=org.apache.log4j.FileAppender
   log4j.appender.pattern.File=<CATALINA_HOME>/logs/log4jpattern.log

   # We will use a custom layout for this example
   log4j.appender.pattern.layout=org.apache.log4j.PatternLayout
   # Here we set our custom pattern
   log4j.appender.pattern.layout.ConversionPattern=%-5p : %m %d{dd-MM-yy HH:mm:ss}%n

The only line that has changed since our last JSP page is:

     Logger logger = Logger.getLogger("wrox.pattern");

Point your browser to http://localhost:8080/logger/logpattern.jsp and then view $CATALINA_HOME/logs/log4jpattern.log. The log entries should look something like this:

   DEBUG : A debug message 06-08-02 01:54:21
   INFO  : An info message 06-08-02 01:54:21
   WARN  : A warn message 06-08-02 01:54:21
   ERROR : An error message 06-08-02 01:54:21
   FATAL : A fatal message 06-08-02 01:54:21

Logging To the Console

Log4J allows us to log to other destinations other than files. In this section we shall send logging messages to the console. This allows an application to instantly notify the administrator of any problems that occur. To log to the console we need to attach a ConsoleAppender to our Logger:

   # A console Logger
   log4j.logger.wrox.console=DEBUG, console

   # This simple example will log to the console
   log4j.appender.console=org.apache.log4j.ConsoleAppender
   # Set the target to Sysytem.out
   log4j.appender.console.Target=System.out

   # We will use the simple format for the console example
   log4j.appender.console.layout=org.apache.log4j.SimpleLayout

The Target parameter must be one of System.out (the default) or System.err.ConsoleAppenders accept the same Layouts as FileAppenders: in this case we are using a SimpleLayout.

Again, our JSP page (logconsole.jsp) only needs one change:

     Logger logger = Logger.getLogger("wrox.console");

Accessing http://localhost:8080/logging/logconsole.jsp will cause the log messages to be logged to Tomcat's console:

Click To expand

Logging To Multiple Destinations

One of the more useful features of Log4J is the ability to log to several destinations at once. This can allow us to send serious error messages to a location where they will be instantly noticed, for example the console, while other more routine messages can be sent to a regular logging file.

We shall look at the following examples in this section:

  • Logging FATAL events to the console and all events to a file

  • Logging FATAL events to the console and all events to Unix's syslog system Logger

  • Logging FATAL events to the console and FATAL and ERROR level events to WinNT's Event Logger

Console and a File

Our first example will log all FATAL level events to the console so that an administrator will be instantly alerted to any serious problems with an application. Also, we still need a record of other events (and a permanent record of FATAL events) so we will log all events to a file.

First we assign two Appenders to the wrox.multifile Logger: fatalconsole and errorfile. We also set the default logging level:

   # A multi-destination logger
   # FATAL errors will go to the console
   # All errors will go to a file
   log4j.logger.wrox.multifile=DEBUG, fatalconsole, errorfile

Now we set the fatalconsole Appender's type to ConsoleAppender, set the target to System.out, and set the logging level to FATAL, using the Threshold parameter of the Appender:

   # All fatal messages for this example go to the console
   log4j.appender.fatalconsole=org.apache.log4j.ConsoleAppender
   log4j.appender.fatalconsole.Target=System.out
   log4j.appender.fatalconsole.Threshold=FATAL

Next we set up the file where all log messages will be sent. We also set the logging level to DEBUG:

   # All messages go to a file
   log4j.appender.errorfile=org.apache.log4j.FileAppender
   log4j.appender.errorfile.File=<CATALINA_HOME>/logs/log4jerrors.log
   log4j.appender.errorfile.Threshold=DEBUG

   # We will use simple layouts for both the console and the file
   log4j.appender.fatalconsole.layout=org.apache.log4j.SimpleLayout
   log4j.appender.errorfile.layout=org.apache.log4j.SimpleLayout

Now all we need to do to set up this example is change the same line of code in our JSP page (fatalconsole.jsp):

     Logger logger = Logger.getLogger("wrox.multifile");

The logging method calls remain the same. Now each time a logging message is logged by the wrox.multifile Logger it is compared to the level of each Appender and only sent to its destination if it is less than or equal to this level.

Now if you point a browser at http://localhost:8080/logging/fatalconsole.jsp you should see the following in the Tomcat console:

 

Now look at $CATALINA_HOME/logs/log4jerrors.jsp:

   DEBUG - A debug message
   INFO - An info message
   WARN - A warn message
   ERROR - An error message
   FATAL - A fatal message

As you can see, Log4J has only sent FATAL level messages to the console, but has sent all messages to the regular logging file.

Console and Syslog

The Unix syslog program is an integral part of all Unix systems. It was designed with two important functions in mind: liberating programmers from having to write log files and putting logging in the hands of the administrator.

Log4J provides the SyslogAppender for working with syslog. It needs a bit more configuring than the other Appenders we have seen before, but it is still relatively straightforward. In this example, we will again send FATAL level events to the console, but this time we will send all events to syslog as user-level events:

   # A multi-destination logger
   # FATAL errors will go to the console
   # All errors will go to syslog
   log4j.logger.wrox.multisyslog=DEBUG, fatalconsolesys, syslog

   # All fatal messages for this example go to the console
   log4j.appender.fatalconsolesys=org.apache.log4j.ConsoleAppender
   log4j.appender.fatalconsolesys.Target=System.out
   log4j.appender.fatalconsolesys.Threshold=FATAL

Here is the SyslogAppender configuration. After setting the syslog Appender type, we set its logging level. We then need to set the syslog facility using the SyslogAppender's Facility parameter. syslog uses facilities alongside a severity index to decide where the logging message should be sent, much like Log4J does with the logging level and Appender name. Many system functions have their own facility, for example sendmail has the mail facility and the kernel has the kern facility. In our example we will use the user facility that is designed for user-level processes.

The final piece of configuration for a SyslogAppender is the SyslogHost parameter. This should specify the central logging host of your network, or localhost if you are logging to the local machine:

   # All messages go to syslog
   log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
   log4j.appender.syslog.Threshold=DEBUG
   log4j.appender.syslog.Facility=USER
   log4j.appender.syslog.SyslogHost=localhost

   # We will use simple layouts for both the console and syslog
   log4j.appender.fatalconsolesys.layout=org.apache.log4j.SimpleLayout
   log4j.appender.syslog.layout=org.apache.log4j.SimpleLayout


Important 

Note that if syslog is running on a Linux box over a network, you will have to start it with the -r switch to enable network logging. This can be set in the /etc/init.d/syslog file. Run /etc/init.d/syslog restart to restart syslog.

Again, there is only one change to the JSP file:

   Logger logger = Logger.getLogger("wrox.multisyslog");

Point a browser at http://localhost:8080/logging/fatalsyslog.jsp and then examine the log file where syslog sends all user-level log messages. You should see the messages listed in syslog's format, which should look like the following:

   Aug 5 16:48:40 matthew user: DEBUG - A debug message

Console and WinNT Event Logger

Our final example will be logging messages to the console and WinNT's Event Logger. The Event Logger can be found under Start | Settings | Control Panel | Administrative Tools | Event Viewer. This is where WinNT logs its system messages. These messages include serious errors in applications like Internet Explorer, as well as less important messages such as print job completion messages. WinNT messages have error types that are similar in concept to Log4J Levels. For example, WinNT Errors correspond to Log4J's FATAL and ERROR levels.

In this example, we will again send only FATAL errors to the console, but this time only FATAL and ERROR messages will be sent to the Event Logger:

   # A multi-destination logger
   # FATAL errors will go to the console
   # FATAL and ERROR will go to the NT Event Logger
   log4j.logger.wrox.multiwinnt=DEBUG, winntconsole, winntlogger

   # All fatal messages for this example go to the console
   log4j.appender.winntconsole=org.apache.log4j.ConsoleAppender
   log4j.appender.winntconsole.Target=System.out
   log4j.appender.winntconsole.Threshold=FATAL

Here is where we configure the NTEventLogAppender that allows us to write to the Event Logger:

   # All fatal and error messages go to the WinNT logger
   log4j.appender.winntlogger=org.apache.log4j.nt.NTEventLogAppender
   log4j.appender.winntlogger.Threshold=ERROR

The Event Logger displays the source of the message in its window. By default, Log4J messages are given the name 'log4j'. This isn't very useful if we have a number of applications using Log4J, so we will add our own source name:

   # We will set the Source parameter so we know which application
   # this message came from
   log4j.appender.winntlogger.Source=Wrox Logging

The Event Logger can take the same Layouts as other Layouts, but only SimpleLayout and PatternLayout make sense in this situation (as we shall see when we examine the log message):

   # We will use a simple layout for both the console and the Event Logger
   log4j.appender.winntconsole.layout=org.apache.log4j.SimpleLayout
   log4j.appender.winntlogger.layout=org.apache.log4j.SimpleLayout

Here's that line of code again:

   Logger logger = Logger.getLogger("wrox.multiwinnt");

Viewing the page http://localhost:8080/logging/fatalwinnt.jsp will send the usual FATAL message to the console as well as an ERROR message and a FATAL message to the Event Logger:

 

Both messages are logged as WinNT errors, but are given different categories. Double-clicking on a log message will show its properties:

 

The Description box explains why the SimpleLayout and PatternLayout are the only sensible options for this kind of Appender: putting HTML tables into this box would make it almost unreadable.

阅读全文
0 0

相关文章推荐

img
取 消
img