Programming Jakarta Struts, 2nd Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming Jakarta Struts, 2nd Edition [Electronic resources] - نسخه متنی

Chuck Cavaness

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








15.4 Using the log4j Package


You may have heard or read about the log4j library from
other sources, but in case you haven't,
let's briefly discuss the library's
history here. Like Struts, log4j is an open
source project that is part of the Jakarta set of projects.
It's essentially a set of Java classes and
interfaces that provides logging functionality to multiple types of
output destinations. It has been around for several years and is
constantly being refined and tuned for all types of Java development.
In fact, log4j has been so successful that it
has been ported to several other very popular languages, including C,
C++, Python, and even .NET.


At the time of this writing, log4j has released
Version 1.2.8, which is its 22nd major public release. The next major
version, 1.3, is in the works, but it won't be
released for a while. Version 1.2 is backward compatible with earlier
versions, so if you are using 1.1.3, this material will still be
relevant for you.

Recently, the Apache Software Foundation has created a new Apache
project called Apache Logging Services.
According to the release, the new project is intended to provide
"cross-language logging services."
Log4j is a central theme to this project.

According to the creators of log4j, it was built
with two central concepts in mind: speed and flexibility. One of the
distinctive features of the logging framework is its notion of
inheritance in
categories, or
loggers as they are
now called. log4j supports a parent/child
relationship between the configured loggers in the environment. For
example, if we configured a logger for all the classes in the
com.oreilly.struts package and another logger for
all the classes in the
com.oreilly.struts.storefront package, the first
logger would be the parent of the second. This hierarchical structure
gives us the flexibility to control what log messages are written out
based on such things as the package structure.

You don't need to go this far if your requirements
don't call for it. If you want, you can configure a
single root logger for your entire environment. You can configure
log4j for your specific needs, and you can
change its behavior whenever you like by simply editing an external
configuration fileyou don't have to change
the application's source code.

A discussion of log4j could fill a small book.
I'll assume that you are familiar with the basic
concepts and will cover only the essentials of how to integrate
log4j with the Struts framework here. If you
haven't yet become familiar with
log4j, this is a good time to do so. For a more
detailed discussion, you can download or view the documentation at
the Jakarta log4j web site
at http://logging.apache.org/log4j.


15.4.1 Integrating log4j with Struts


To ensure that the log4j libraries
are available to your Struts applications, you should place the
log4j JAR file in the
WEB-INF/lib directory for each web application
that you deploy. Resist the temptation to put it inside the
container-wide lib directory, even if
you're deploying multiple web applications with
log4j. If you do attempt to install it at the
container level, you probably will encounter one or more
ClassNotFoundException problems.

Based on the requirements set forth in the 2.3 Servlet specification,
the web container should automatically load all JAR files in the
WEB-INF/lib directory, including the
log4j library. After this initial step is
complete, you are free to use log4j as the
logging implementation for the Commons Logging package.


Keep in mind that the configuration of log4j is
totally independent of the configuration of the logging
implementation for the Commons Logging package. You still need to
understand how to configure log4j (if
that's the implementation you choose) and perform
the necessary steps required by the log4j
package.


15.4.2 What Are Loggers?


The
org.apache.log4j.Logger is the central class in
the log4j toolkit. Other than configuration,
most of the functionality is performed through this class. In earlier
versions of the log4j project, the
org.apache.log4j.Category class implemented this
functionality. To promote backward compatibility, the
Logger class extends the
Category class. Although the methods in the
Category class have not yet been deprecated, you
should always go through the Logger class itself.
Eventually, the Category class will be removed
from the library.

When used with Struts, most of the log4j classes
and interfaces (other than the configuration aspects of
log4j) are encapsulated within the Commons
Logging API.


15.4.3 Configuring log4j Appenders


With log4j, you can
send log messages to multiple destinations.
log4j refers to a message destination as an
appender. The
log4j framework provides the following appenders
for you to use out of the box:

  • Console Appender

  • File Appender

  • Socket Appender

  • Java Message Service (JMS) Appender

  • NT Event Logger Appender

  • Unix Syslog Appender

  • Null Appender

  • SMTP Appender

  • Telnet Appender

  • Asynchronous Appender


The log4j framework allows one or more appenders
to be established for a logging environment. You can even send log
messages to particular appenders, based on various conditions. The
other nice feature of the appender architecture is that if none of
these default appenders meets your application's
requirements, you can create your own by extending the
org.apache.log4j.AppenderSkeleton class.


15.4.4 Understanding the log4j Log Levels


A log message in log4j can
be assigned one of five different levels or priorities. The levels
allow you to set a threshold for a particular logger and filter out
any log messages that don't reach the threshold for
which the Logger is configured. The five logging levels are:

  • DEBUG

  • INFO

  • WARN

  • ERROR

  • FATAL



An earlier version of log4j also defined the
levels OFF and ALL; however, these seem to have been deprecated and
probably should be avoided. If you set the threshold to DEBUG,
you'll get the same results as using ALL, and OFF
isn't really necessary because you can simply choose
not to configure an appender for the environment, which will stop all
logging from occurring.

There is a cascading effect that causes only levels equal to the
threshold and higher to be logged. For example, if a threshold of
WARN is configured, only messages with a level of WARN, ERROR, or
FATAL will make it to an output destination.


15.4.5 Initializing log4j


There are many properties that can be configured for the
log4j
toolkit. In fact, log4j is so flexible that all
the configuration options can't be covered here. The
best source of information is the log4j manual
itself. You can find the manual online at
http://logging.apache.org/log4j/docs/documentationl,
and it's also available locally when you
download log4j.

Because log4j doesn't make any
assumptions about the environment in which it is running, you need to
configure the environment for your particular needs. In other words,
no default appenders are configured out of the box.

There are various ways in which you can initialize the configuration
properties for the log4j environment. We will
focus on two related, but distinct, approaches here.


15.4.5.1 Initializing using the log4j.properties file

The first approach is to create a file called
log4j.properties that
contains the necessary configuration elements for your logging
needs. This file must follow the guidelines of the
java.util.Properties format. One of these
guidelines is that each property is in the format
key=value.

Example 15-5 illustrates a very simple
log4j configuration file that logs messages with
a logging threshold of INFO to the console using an
org.apache.log4j.ConsoleAppender.


Example 15-5. j.properties file

# A basic log4j configuration file that creates a single console appender
# Create a single console appender that logs INFO and higher
log4j.rootLogger=INFO, stdout
# Configure the stdout appender to go to the console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Configure the stdout appender to use the PatternLayout
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's filename and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

The configuration file shown in Example 15-5 is a
very simple example of setting up a single appenderin this
case, the ConsoleAppender, which directs log
messages to System.out.

This log4j.properties file must be installed in
the WEB-INF/classes directory so that the
log4j environment will be able to locate it and
use it to configure the logging environment for the web application.
If you have multiple web applications, you can have a separate
log4j.properties file for each.

The log4j configuration file shown in Example 15-5 sends log messages to only a single
destination, the console. However, you can configure the log messages
to go to multiple locations and also have certain messages go to
certain locations based on the level of the message and other
parameters. Example 15-6 shows a simple example using
two appenders.


Example 15-6. j configuration file using two appenders

# A sample log4j configuration file
# Create two appenders, one called stdout and the other called rolling
log4j.rootLogger=DEBUG, stdout, rolling
# Configure the stdout appender to go to the console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Configure the stdout appender to use the PatternLayout
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's filename and line number
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
# Configure the rolling appender to be a RollingFileAppender
log4j.appender.rolling=org.apache.log4j.RollingFileAppender
# Configure the name of the logout for the rolling appender
log4j.appender.rolling.File=output.log
# Set up the maximum size of the rolling log file
log4j.appender.rolling.MaxFileSize=100KB
# Keep one backup file of the rolling appender
log4j.appender.rolling.MaxBackupIndex=1
# Configure the layout pattern and conversion pattern for the rolling appender
log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling.layout.ConversionPattern=%d{ABSOLUTE} - %p %c - %m%n

The log4j configuration file in Example 15-6 creates one appender that logs messages to the
console, just as in Example 15-5, and another
appender that logs messages to a log file called
output.log. Again, we won't try
to cover all of the configuration settings for
log4j; you can learn more from the
log4j web site.


15.4.5.2 Initializing using an XML file

The second approach to initializing the configuration properties for
the log4j environment is to use an XML file.
Example 15-7 illustrates an XML file that configures
the same information as in Example 15-5.


Example 15-7. j configuration file using an XML format

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j=http://logging.apache.org/log4j'>
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%5p [%t] (%F:%L) - %m%n"/>
</layout>
</appender>
<root>
<priority value ="INFO" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>

You normally place this XML file in the
WEB-INF/classes directory, just as with the
log4j.properties file. However, you must set the
log4j.configuration system property equal to the
name of the file, so that the log4j environment
knows which file to load. There's no default
filename when using the XML format. (We didn't have
to do this with the properties file because the name
log4j.properties is part of the
log4j default initialization. If it locates this
file anywhere in the classpath, it will use it to initialize the
log4j environment.)

There are various ways to set the
log4j.configuration property, and the various
containers may provide alternative methods. In
Tomcat Version 4.0, for example, you can
set a variable called CATALINA_OPTS in the
catalina.bat file to provide this information to
the logging environment. For example:

set CATALINA_OPTS=-Dlog4j.configuration=log4j.xml

When you start up Tomcat, the log4j environment
will then be able to locate the XML configuration file. Other
containers may provide alternate methods for setting the value, but
you can always set the value on the Java command line as a system
property. You will probably need to modify the
container's startup script using this approach,
however:

java -Dlog4j.configuration=log4j.xml

If the log4j environment is unable to find a
valid configuration file, either properties- based or XML-based, you
will see something similar to the following message when you first
attempt to initialize the logging environment:

log4j:WARN No appenders could be found for logger XXX.
log4j:WARN Please initialize the log4j system properly.

The XXX in the first message will actually show
the name of the logger for which no appenders were configured.


15.4.5.3 Specifying a relative versus an absolute path

When you use a system property to configure the
log4j configuration file within a web
application, the file is relative to the web application by default.
The following example tells log4j to search for
a file called log4j.xml in the
WEB-INF/classes directory for the web
application:

java -Dlog4j.configuration=log4j.xml

Most containers use a separate class loader for each web application,
and some containers may not allow the web applications to know about
classes or JARs loaded by the container itself. However, if you need
to use an absolute path, you can specify one like this:

java -Dlog4j.configuration=file:/c:/dev/env/log4j.xml

Be careful when using an absolute pathbecause the
configuration file is not relative to a web application, all web
applications will share the same one.

Generally speaking, specifying a relative path is much more flexible
than using an absolute path because you can't always
guarantee the directory structure of all your target environments.


15.4.5.4 Synchronization issues

There's one more issue that you should be aware of
when logging to resources such as filesystems. Even though
log4j is able to handle multiple client threads
using the same appender (because all threads are synchronized), if
you have multiple appenders writing to the same resource or file, you
will have unpredictable results. In other words, there is no
synchronization between appenders, even
within the same JVM.

This really has nothing to do with a deficiency in the
log4j design; it's just a case
of not being able to easily synchronize multiple writers to a
resource. The easiest way to solve this problem is to ensure that if
you have multiple appenders or web applications logging to the
filesystem, you don't allow them to log to the same
file. If you do, you will probably experience synchronization-related
issues.


15.4.6 Log File Rollover


In a normal production environment,
log files can grow quite large if not managed properly. If the
logging threshold is set to DEBUG or
INFO or if the files are not purged from time to
time, the files can grow without bounds.

It's a good idea to periodically back up the log
files and start again with an empty log file. For some production
environments, this "rollover"
period may be nightly; others may only need to perform this routine
weekly. Unless you can shut down the application while you back up
the log files, it's very cumbersome to back them up
manually.

Fortunately, log4j provides a type of appender
that automatically swaps the log file out with a new one while at the
same time maintaining a backup of the old log file. The
org.apache.log4j.DailyRollingFileAppender class
provides the ability to log to a file and roll over or back up the
log file while the application is still running. You can also specify
the rollover frequency and the date pattern that will be used for the
backup names. Having this functionality available out of the box
makes log4j invaluable to any application that
needs to roll over log files at user-defined intervals.


    / 181