e martë, 2 tetor 2007

Log4J

Log4j


Logging within the context of program development constitutes inserting statements into the program that provide some kind of output information that is useful to the developer. Inserting log statements into your code is a general method for debugging it. Examples of logging are trace statements, dumping of structures and the familiar System.out.println or printf debug statementsLog4j is a open source debugging tool developed for putting log statements into your application., written in Java, which logs statements to a file, a java.io.Writer, or a syslog daemon. Log4j offers a hierarchical way to insert logging statements within a Java program. Multiple output formats and multiple levels of logging information are available.One of the distinctive features of log4j is the notion of inheritance in loggers. Using a logger hierarchy it is possible to control which log statements are output at arbitrarily fine granularity but also great ease. This helps reduce the volume of logged output and minimize the cost of logging.By using a dedicated logging package, the overhead of maintaining thousands of System.out.println statements is alleviated as the logging may be controlled at runtime from configuration scripts.It's speed and flexibility allows log statements to remain in shipped code while giving the user the ability to enable logging at runtime without modifying any of the application binary. All of this while not incurring a high performance cost.Logging does have its drawbacks. It can slow down an application. If too verbose, it can cause scrolling blindness. To alleviate these concerns, log4j is designed to be reliable, fast and extensible. Since logging is rarely the main focus of an application, the log4j API strives to be simple to understand and to use. All enterprise architectures adopt a global logging framework. The logging framework provides classes/interfaces for logging messages, errors and debug statements to destinations like files, databases, e-mails and consoles throughout the system. The logged information is useful to an end-user of an application or to a system administrator. Internationalization in a logging framework is the ability to log the messages in different languages. All logging frameworks will be rated on internationalization and extensibility. The following logging frameworks are available:• JavaTM Logging• Jlog• Log4j• Protomatter• BEA mechanism for logging (technically not a full feature framework)• Message LFW

Log4J Features


Basic features of any logging library are: 1. Control over which logging statements are enabled or disabled - the Logger, the central class in the log4j package. 2. Manage output destinations - Appenders, there are appenders for files, the console, Unix Syslog, NT Event Log, remote servers, SMTP e-mail, etc.3.Manage output format- Layouts, the most popular layouts are the PatternLayout and HTMLLayout.As mentioned above Log4j has three main components: loggers, appenders and layouts.1. public class Logger- Logger is responsible for handling the majority of log operations. 2. public interface Appender - Appender is responsible for controlling the output of log operations. 3. public abstract class Layout-Layout is responsible for formatting the output for Appender.These three types of components work together to enable developers to log messages according to message type and level, and to control at runtime how these messages are formatted and where they are reported.
Log4J Loggers


The first and foremost advantage of any logging API over plain System.out.println resides in its ability to disable certain log statements while allowing others to print unhindered. This capability assumes that the logging space, that is, the space of all possible logging statements, is categorized according to some developer-chosen criteria. This observation had previously led to choose category as the central concept of the package. However, since log4j version 1.2, Logger class has replaced the Category class. For those familiar with earlier versions of log4j, the Logger class can be considered as a mere alias to the Category class. Loggers are named entities. Logger names are case-sensitive and they follow the hierarchical naming rule. A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger. For example, the logger named "com.parent" is a parent of the logger named "com.parent.child". Similarly, "ancestor" is a parent of "ancestor.parent" and an ancestor of " ancestor.parent.child". The root logger resides at the top of the logger hierarchy. It is exceptional in two ways: 1.it always exists, 2. it cannot be retrieved by name. Invoking the class static Logger.getRootLogger method retrieves it. All other loggers are instantiated and retrieved with the class static Logger.getLogger method. This method takes the name of the desired logger as a parameter. Some of the basic methods in the Logger class are listed below. The logger is the core component of the logging process. In log4j, there are 5 normal levels Levels of logger available (not including custom Levels), the following is borrowed from the log4j API (http://jakarta.apache.org/log4j/docs/api/index.html): static Level DEBUG - The DEBUG Level designates fine-grained informational events that are most useful to debug an application. static Level INFO - The INFO level designates informational messages that highlight the progress of the application at coarse-grained level. static Level WARN - The WARN level designates potentially harmful situations.static Level ERROR - The ERROR level designates error events that might still allow the application to continue running.static Level FATAL - The FATAL level designates very severe error events that will presumably lead the application to abort. In addition, there are two special levels of logging available: (descriptions borrowed from the log4j API http://jakarta.apache.org/log4j/docs/api/index.html): static Level ALL -The ALL Level has the lowest possible rank and is intended to turn on all logging.static Level OFF - The OFF Level has the highest possible rank and is intended to turn off logging.There are a number of ways to create a logger, one can retrieve the root logger:Logger logger = Logger.getRootLogger(); One can create a new logger:Logger logger = Logger.getLogger("MyLogger");More usually, one instantiates a static logger globally, based on the name of the class:static Logger logger = Logger.getLogger(test.class);All these create a logger called "logger", one can set the level with:logger.setLevel((Level)Level.DEBUG);You can use any of 7 levels; Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.FATAL, Level.ALL and Level.OFF.

Log4J Appenders


The ability to selectively enable or disable logging requests based on their logger is only part of the picture. Log4j allows logging requests to print to multiple destinations. In log4j speak, an output destination is called an appender. Currently, appenders exist for the console, files, GUI components, remote socket servers, JMS, NT Event Loggers, and remote UNIX Syslog daemons. It is also possible to log asynchronously. More than one appender can be attached to a logger. The Appenders available are
Common Appenders

FileAppender, it appends log events to a file.

RollingFileAppender, it extends FileAppender to backup the log files when they reach a certain size.

DailyRollingFileAppender -it extends FileAppender so that the underlying file is rolled over at a user chosen frequency.

ConsoleAppender - it appends log events to System.out or System.err using a layout specified by the user. The default target is System.out.

Network Appenders

SocketAppender - it sends LoggingEvent objects to a remote a log server, usually a SocketNode.

SocketHubAppender - it sends LoggingEvent objects to a set of remote log servers, usually a SocketNodes .

JMSAppender - A simple appender that publishes events to a JMS Topic. The events are serialized and transmitted as JMS message type ObjectMessage. .

NTEventLogAppender - Append to the NT event log system.

Third-party Appenders

JDBCAppender by Danko Mannhaupt (recommended over the current JDBCAppender included)

SNMPTrapAppender

Special Appenders

AsyncAppender - it lets users log events asynchronously. It uses a bounded buffer to store logging events.

ExternallyRolledFileAppender - This appender listens on a socket on the port specified by the PORT_OPTION for a "RollOver" message. When such a message is received, the underlying log file is rolled over and an acknowledgment message is sent back to the process initiating the roll over.

JDBCAppender - it provides for sending log events to a database.

LF5Appender - it logs events to a swing based logging console. The swing console supports turning categories on and off, multiple detail level views, as well as full text searching and many other capabilties.

NullAppender (there’s two, one for internal operations & one for benchmarking)

SMTPAppender - it sends an e-mail when a specific logging event occurs, typically on errors or fatal errors.

SyslogAppender - it sends messages to a remote syslog daemon.

TelnetAppender - it is a log4j appender that specializes in writing to a read-only socket.

WriterAppender - WriterAppender appends log events to a Writer or an OutputStream depending on the user's choice.
One may also implement the Appender interface to create ones own ways of outputting log statements. Using A ConsoleAppenderA ConsoleAppender can be created like this:ConsoleAppender appender = new ConsoleAppender(new PatternLayout());Which creates a console appender, with a default PatternLayout. The default output of System.out is used. Using A FileAppenderA FileAppender can be created like this:FileAppender appender = null;try {appender = new FileAppender(new PatternLayout(),"filename");} catch(Exception e) {}The constructor in use above is:FileAppender(Layout layout, String filename) Instantiate a FileAppender and open the file designated by filename.Another useful constructor is:FileAppender(Layout layout, String filename, boolean append) Instantiate a FileAppender and open the file designated by filename. So that one may choose whether or not to append the file specified or not. If this is not specified, the default is to append. Using A WriterAppenderA WriterAppender can be created like this:WriterAppender appender = null;try {appender = new WriterAppender(new PatternLayout(),new FileOutputStream("filename"));} catch(Exception e) {}This WriterAppender uses the constructor that takes a PatternLayout and an OutputStream as arguments, in this case a FileOutputStream is used to output to a file, there are other constructors available.

Log4J Layouts


The output of an appender can be customized by associating with it a Layout. These are the types of Layout available: Simple layout-- org.apache.log4j.SimpleLayoutSimpleLayout formats the output in a very simple manner, it prints the Level, then a dash '-' and then the log message.
PatternLayout --org.apache.log4j.PatternLayoutPatternLayout formats the output based on a conversion pattern specified, or if none is specified, the default conversion pattern. HTML layout-- org.apache.log4j.HTMLLayoutHTMLLayout formats the output as a HTML table. XMLLayout-- org.apache.log4j.xml.XMLLayoutXMLLayout formats the output as a XML. Illustrating Examples
SimpleLayout and FileAppenderHere is a very simplistic example of a program implementing a SimpleLayout and FileAppender:import org.apache.log4j.Level;import org.apache.log4j.Logger;import org.apache.log4j.SimpleLayout;import org.apache.log4j.FileAppender;public class simpandfile {static Logger logger = Logger.getLogger(simpandfile.class);public static void main(String args[]) {SimpleLayout layout = new SimpleLayout();FileAppender appender = null;try {appender = new FileAppender(layout,"output1.txt",false);} catch(Exception e) {}logger.addAppender(appender);logger.setLevel((Level) Level.DEBUG);logger.debug("Here is some DEBUG");logger.info("Here is some INFO");logger.warn("Here is some WARN");logger.error("Here is some ERROR");logger.fatal("Here is some FATAL");}}HTMLLayout and WriterAppenderHere is a very simplistic example of a program implementing a HTMLLayout and WriterAppender:import java.io.*;import org.apache.log4j.Level;import org.apache.log4j.Logger;import org.apache.log4j.HTMLLayout;import org.apache.log4j.WriterAppender;public class htmlandwrite {static Logger logger = Logger.getLogger(htmlandwrite.class);public static void main(String args[]) {HTMLLayout layout = new HTMLLayout();
WriterAppender appender = null;try {FileOutputStream output = new FileOutputStream("output2.html");appender = new WriterAppender(layout,output);} catch(Exception e) {}
logger.addAppender(appender);logger.setLevel((Level) Level.DEBUG);
logger.debug("Here is some DEBUG");logger.info("Here is some INFO");logger.warn("Here is some WARN");logger.error("Here is some ERROR");logger.fatal("Here is some FATAL");}}PatternLayout and ConsoleAppenderHere is a very simplistic example of a program implementing a PatternLayout and ConsoleAppender:
import org.apache.log4j.Level;import org.apache.log4j.Logger;import org.apache.log4j.PatternLayout;import org.apache.log4j.ConsoleAppender;public class consandpatt {static Logger logger = Logger.getLogger(consandpatt.class);public static void main(String args[]) {
// Note, %n is newlineString pattern = "Milliseconds since program start: %r %n";pattern += "Classname of caller: %C %n";pattern += "Date in ISO8601 format: %d{ISO8601} %n";pattern += "Location of log event: %l %n";pattern += "Message: %m %n %n"; PatternLayout layout = new PatternLayout(pattern);ConsoleAppender appender = new ConsoleAppender(layout);
logger.addAppender(appender);logger.setLevel((Level) Level.DEBUG);
logger.debug("Here is some DEBUG");logger.info("Here is some INFO");logger.warn("Here is some WARN");logger.error("Here is some ERROR");logger.fatal("Here is some FATAL");}}Substitute symbol%c Logger, %c{2 } last 2 partial names%C Class name (full agony), %C{2 } last 2 partial names%d{dd MMM yyyy HH:MM:ss } Date, format see java.text.SimpleDateFormat%F File name%l Location (caution: compiler-option-dependently)%L Line number%m user-defined message%M Method name%p Level%r Milliseconds since program start%t Threadname%x, %X see Doku%% individual percentage signCaution: %C, %F, %l, %L, %M slow down program run!
Log4J Levels


Log4J Levels
Loggers may be assigned levels. The set of possible levels, that is DEBUG, INFO, WARN, ERROR and FATAL are defined in the org.apache.log4j.Level class. If a given logger is not assigned a level, then it inherits one from its closest ancestor with an assigned level.
The root logger resides at the top of the logger hierarchy. It always exists and always has an assigned level.
The logger is the core component of the logging process. In log4j, there are 5 normal levels Levels of logger available (not including custom Levels), the following is borrowed from the log4j API (http://jakarta.apache.org/log4j/docs/api/index.html): static Level DEBUG - The DEBUG Level designates fine-grained informational events that are most useful to debug an application. static Level INFO - The INFO level designates informational messages that highlight the progress of the application at coarse-grained level. static Level WARN - The WARN level designates potentially harmful situations.static Level ERROR - The ERROR level designates error events that might still allow the application to continue running.static Level FATAL - The FATAL level designates very severe error events that will presumably lead the application to abort. In addition, there are two special levels of logging available: (descriptions borrowed from the log4j API http://jakarta.apache.org/log4j/docs/api/index.html):static Level ALL -The ALL Level has the lowest possible rank and is intended to turn on all logging.static Level OFF - The OFF Level has the highest possible rank and is intended to turn off logging.
Log4j Installation


In order to use the tools we are about to install it is necessary to setup the operating environment so that the tools know where to find stuff they need and the operating system knows where to find the tools. A understanding of how to do this is essential as you will be asked to change the operating environment. I have comprehensively covered this in documents entitled Configuring A Windows Working Environment and Configuring A Unix Working Environment. 1. Download the log4j distribution from http://jakarta.apache.org/log4j/docs/download.html.
2. Extract the archived files to some suitable directory.3. Add the file dist/lib/log4j-1.2.6.jar to your CLASSPATH environment variable. 4. Download http://apache.rmplc.co.uk/dist/xml/xerces-j/Xerces-J-bin.2.6.0.zip and unzip it to a temporary directory. Copy the files xercesImpl.jar and xmlParserAPIs.jar to some permanent location and append their paths to the CLASSPATH environment variable.
Log4j vs. JSR47



Log4j
JSR47
Required JDK
1.1 or above
1.4 or above
Authorship
actual users
closed committee
License
Apache Public License
Sun Community Source License
Loggerconfiguration order
order independent
order independent (as of spec. version 0.75)
Support for API extensions
pervasive
none
Appender inheritance
cumulative
cumulative (as of spec. version 0.75)
Support for object rendering
yes
no
Configuration file formats
XML and key=value formats
key=value format only with very limited syntax
Support for ErrorHandlers
Yes
yes (as of version 0.75)
Filter logic
à la Linux ipchains
boolean
Part of JDK
no
yes
Pros & Cons of Log4j


Pros:• log4j is optimized for speed. The burden of logging is minimized.• log4j is based on a named logger hierarchy.• log4j is thread-safe.• The format of the logged message can be specified similar to C language’s printf()function. For e.g. Formatting can be specified as “%r [%t] %-5p %c{2} %x - %m\n”• log4j is not restricted to a predefined set of facilities.• Logging behavior can be set at runtime using a configuration file. Configuration files canbe property files or in XML format.• log4j is designed to handle Java Exceptions from the start.• log4j can direct its output to a file, the console, a java.io.OutputStream, java.io.Writer, aremote server using TCP, a remote Unix Syslog daemon, to a remote listener using JMS,to the NT EventLog or even send e-mail.• The format of the log output can be easily changed by extending the Layout class. Thetarget of the log output as well as the writing strategy can be altered by implementationsof the Appender interface.• log4j supports multiple output appenders per logger.• It supports hierarchical logging. It is possible to select (at runtime) which log statementsare output at arbitrary granularity. Users can choose to implement their own log formatsand output strategies.Cons:• Internationalization (Though specified in features, it is not mentioned anywhere else inthe documentation) is not provided• Asynchronous logging facility is not provided• Threads are used in Handler objects. As threads should be managed only by the EJBcontainer and should not be created in the code written by a developer, we have to find aworkaround for this issue. The solutions like writing Java Messaging Service handler orcalling the initialization code of the framework from start-up classes of application serverneed more investigation.

No comments: