Wednesday, 11 March 2015

Log4j:-java api(tool)



INTRODUCTION TO Log4J

Introduction

Any Real Time Java Application contains many components(projects) with different package structure with N number of classes,interfaces,jsp files etc.
Although developer tries their level best to write robust code, Real Time Applications are not  guaranteed to be 100% bug free.Most often we have also encountered bug in live environment.
If We talk about live environment,then tracing bugs in live environment must be quick else we may lose customer and so the business.


RealTime UseCase

It was a vacation period and I was just trying to book my ticket from Hyderabad to Bhubaneswar and in my CITIBANK payment page I got Some Exception,I tried again for a couple of time but still got the same Exception.Then I had to book my ticket from HDFC Account and it went good
My booking time was around 12:00 AM and in this period generally the Application undergoes maintance window. Which means certain patches are installed and few things are re-configured if needed.That may not be the only reason of the Exception? Sometimes few services may go down due to some failure.

Certainly CITIBANK might have lost many customer at that time until it was fixed by support team.

If you are working on support,then you will have to deal with these kind of situation.You are not the actual programmer  of the Application and You need to find the root cause of the Problem and also need to provide atleast some temporary solution to keep it running. You will not have access to Server console
So the question is,How to start analyzing the problem.

So we need some mechanism to write the exception outputs to a file(log file),so that we can analyse the log file later which can help us identifying and resolving  the problem.

Introduction to Logging:

Logging is a technique or process to record various information  to any output device such as files,outputScreens etc.

ü    Aeroplanes logs about 2.5 GB of Data each 30 minutes to its black box,so that those data can be read later to study any failure if it comes on the flight.

ü    All Software Programs writes the Exception,Error,Information data to a file(log file),so that it can be  used to understand the flow of program or to debug the application

Why Logging is needed:-

ü    To understand the flow of the application.
ü    To log Exceptions occurred in the application.
ü    To log some Application information to the file.

Advantage of Logging Framework
Problem diagnosis: No matter how well written our code is, there may be some problems hidden in it. As soon as the triggering conditions occur, the hidden problems come to the surface. If our applications have well-written code for logging the internal state of the system, we will be able to detect the problems precisely and quickly.

Quick debugging: Once we diagnose the problem, we know exactly how to solve the problem. The logging trace should be aimed at showing the precise location of the problem,which means we will be able to debug the application in less time. Well-planned and well-written logging code greatly reduces the overall cost of debugging the application.

Easy maintenance: Applications with a good logging feature are easy to debug and therefore easy to maintain compared to any application without a similar logging feature. The logging information typically contains more information than the debugging trace.

History: A good logging feature in an application results in logging information being preserved in a structured way at a desired location. The location may be a file, database, or remote machine. All this enables system a future date by going through the logging history.

Cost and time savings: As explained, well-written logging code offers quick debugging,easy maintenance, and structured storage of an application’s runtime information. This makes installation, day-to-day maintenance, and debugging much more cost- and time-effective.

Disadvantage of Logging Framework
ü    Logging adds runtime overhead due to the generation of logging information and the        device Input/Output (I/O) related to publishing logging information. Log4j needs 5           nanoseconds each time to log a statement.
ü    Logging adds programming overhead due to the extra code required for producing            logging information. The logging process increases the size of the code.
ü    Badly produced logging information can cause confusion.
ü    Badly written logging code can seriously affect the application’s performance.
ü    Last but not least, logging requires planning ahead, as adding logging code at a late           stage of development is difficult.

Popular Java-Based Logging APIs
Once logging concepts were proven successful, they were put into use as generic logging APIs. A few Java-based logging APIs are available in the market. Some of them are proprietary, and some are open source. Out of all the available APIs, the following are most popular in the Java community.


JDK Logging API
JDK has its own logging API in its java.util.logging package. This API originated from the JSR 47.
The JDK logging API is, in essence, a scaled-down version of Apache log4j (discussed in the next section). The logging concepts captured in this API involve logging levels and different logging destinations and formats. The JDK logging API is well suited for simple applications with simple logging requirements. Despite a few limitations, this API provides all the basic features that you need to produce effective logging information.

Apache log4j
Apache log4j is an open-source logging API. This API, which evolved from the E.U. SEMPER (Secure Electronic Marketplace for Europe) project, is a popular logging package in Java. It allows great control over the granularity of logging statements. A main benefit of this API is that it is highly configurable through external configuration files at runtime. It views the logging process in terms of levels of priorities and offers mechanisms to direct logging information to a great
variety of destinations, such as a database, file, console, Windows NT event log, UNIX Syslog, Java Message Service JMS), and so on. It also allows application developers to choose from various formatting styles, such as XML, HTML, etc. Overall, log4j is a feature-rich, well-designed extendible logging framework, and provides more capabilities than the JDK logging API. For example, the configuration of log4j is much more flexible than that of the JDK logging API. The JDK logging API can be configured only through a properties-style configuration file, but log4j supports both properties- and XML-style configuration.
Commons Logging API
The Commons logging API is another logging effort from Apache. The goal of this API is to provide a seamless transition from one logging API to another. Depending upon the presence of a logging framework in the classpath, the Commons logging API will try to use the available API to carry out application logging. The Commons logging API runs its own discovery process to find out which logging API is available in the classpath. It tends to provide the lowest common denominator of any two logging APIs. For example, between log4j and the JDK logging API, it will provide a seamless transition for the features common in both—so we would miss any extra features used in log4j implementation is a highly scalable, robust, and versatile logging framework.This API simplifies the writing of logging code within an application, yet allows the flexibility of controlling logging activity from an external configuration file. It also allows us to publish logging information to desired granularity depending on the detail of the logging information suitable to each application.
Apache log4j is also capable of publishing logging information to various destinations such as files, consoles, and NT event logs. Moreover, logging information can even be distributed over Java Message Service ( JMS) or Java Database Connectivity (JDBC), or can be output to a TCP/IP socket. This API lets us take logging information and publish or print it in different formats and layouts that are human-readable and reusable by any error-handling and analyzer program

Log4J Framework Features:
·                     log4j is optimized for speed.
·                     log4j is based on a named logger hierarchy.
·                     log4j is fail-stop but not reliable.
·                     log4j is thread-safe.
·                     log4j is not restricted to a predefined set of facilities.
·                     Logging behavior can be set at runtime using a configuration file. Configuration files         can be 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, an java.io.OutputStream,    java.io.Writer, a remote server using TCP, a remote Unix Syslog daemon, to a remote         listener using JMS, to the NT EventLog or even send e-mail.
·                     log4j uses 5 levels, namely DEBUG, INFO, WARN, ERROR and FATAL.
·                     The format of the log output can be easily changed by extending the Layout class.
·                     The target of the log output as well as the writing strategy can be altered by           implementations of the Appender interface.
·                     log4j supports multiple output appenders per logger.
·                     log4j supports internationalization.

Installing log4j
Apache log4j is an open-source project from Apache. You must meet the following criteria to successfully install and use log4j:
 Get the latest version of the log4j binary distribution from           http://jakarta.apache.org/log4j.We will use 1.2 version. So download them from below link. https://logging.apache.org/log4j/1.2/download.html

Add log4j-1.2.17.jar to your eclipse build path


Overview of the log4j Architecture

The architecture of the log4j API is layered. Each layer consists of different objects performing different tasks. The top layer captures the logging information, the middle layer is involved in analyzing and authorizing the logging information, and the bottom layer is responsible for formatting and publishing the logging information to a destination. In essence, log4j consists of three types of primary objects:

ü  Logger: The Logger object (known as the Category object in releases prior to log4j 1.2) is responsible for capturing logging information. Logger objects are stored in a namespace hierarchy.
ü  Appender: The Appender object is responsible for publishing logging information to various preferred destinations. Each Appender object will have at least one target destination attached to it. For example, a ConsoleAppender object is capable of printing logging information to a console.
ü  Layout: The Layout object is used to format logging information in different styles. Appender objects utilize Layout objects before publishing logging information. Layout objects play an important role in publishing logging information in a way that is human-readable and reusable.
The preceding core objects are central to the architecture of log4j. Apart from them, there are several auxiliary objects that can plug and play to any layer of the API. These objects help manage the different Logger objects active within an application and fine tune the logging process.
Next, let’s go over the principal auxiliary components in the log4j framework that play a vital role in the logging framework:

ü  Level: The Level object, previously referred to as the Priority object, defines the granularity and priority of any logging information. Each piece of logging information is accompanied by its appropriate Level object, which tells the Logger object about the priority of the information. There are seven levels of logging defined within the API: OFF, DEBUG, INFO, ERROR, WARN, FATAL, and ALL. Each level has a unique integer value. The Level values can be arranged in an ascending manner:
ALL<DEBUG<INFO<WARN<ERROR<FATAL<OFF
where ALL means most of the logging information will be published and OFF means none of the logging information will be published.

Levels in Log4j

Level
Description
ALL
All levels including custom levels.
DEBUG
Designates fine-grained informational events that are most useful to debug an application.
ERROR
Designates error events that might still allow the application to continue running.
FATAL
Designates very severe error events that will presumably lead the application to abort.
INFO
Designates informational messages that highlight the progress of the application at coarse-grained level.
OFF
The highest possible rank and is intended to turn off logging.


WARN
Designates potentially harmful situations.

ü  Filter: The Filter object is used to analyze logging information and make further decisions on whether that information should be logged or not. In the log4j context, Appender objects can have several Filter objects associated with them. If logging information is passed to a particular Appender object, all the Filter objects associated with that Appender need to approve the logging information before it can be published to the preferred destination attached to the Appender. Filter objects are very helpful in filtering out unwanted logging information based on any application-specific criteria.
ü  ObjectRenderer: The ObjectRenderer object is specialized in providing a String representation of different objects passed to the logging framework. More precisely, when the application passes a custom Object to the logging framework, the logging framework will use the corresponding ObjectRenderer to obtain a String representation of the passed Object.This is used by Layout objects to prepare the final logging information.
ü  LogManager: The LogManager object manages the logging framework. It is responsible for reading the initial configuration parameters from a system-wide configuration file or a configuration class. The LogManager stores in a namespace hierarchy each Logger instance created with a namespace within an application. When we try to obtain the reference named logger, the LogManager class returns the already created instance of it, or creates a new instance of the named logger, stores it in a repository for future reference, and returns the new instance to the caller application.

Now that you have seen the log4j core components, it is time to briefly discuss how they interact with each other.
ü  The central part of the log4j framework is the Logger object.
ü  An application instantiates a named Logger instance and passes various logging information to it.
ü  A Logger object has a designated Level object associated with it. The Logger object provides several logging methods

that are capable of logging information into categorized levels.
ü  A Logger logs only the messages with Level objects equal to or greater than its assigned Level object, or else it rejects the logging request.
ü  Once the Level condition has been met, the Logger object passes the logging information to all its associated Appender objects and to all the Appender objects associated with its parent Logger, recursively up the logging hierarchy.
ü  Similar to Logger objects, Appender objects can also have threshold Levels attached to them.The logging information is validated against the threshold Level attached to the Appender.If the log message has a Level equal to or greater than the threshold Level, the logging message is passed to the next stage.
ü  The Appender objects then look for any Filter object associated with them. If there are any, the logging information is passed through all the Filter objects in a chain.
ü  Once all the Filter objects approve a message, the Appender utilizes any Layout object associated with it to format the message, and finally it publishes the logging information to the preferred destination.
The following figure depicts the overall flow of the log4j logging architecture in a UML sequence diagram

Naming and Placing the Configuration File
By default, the LogManager class will look for a file named log4j.properties or log4j.xml in the classpath used for loading the log4j classes.
Note:Up to version 1.2.6, log4j would look for only the log4j.properties file in the classpath. Since version 1.2.7, log4j looks for both log4j.properties and log4j.xml in the classpath.
If you decide to name your configuration file differently, you are free to do that. However,you have to let the log4j framework know by supplying a command line argument as follows:   -Dlog4j.configuration="file_name"

Sample Configurations

Let’s look at a sample configuration file. The below listinng shows a simple log4j configuration.
It defines the level and appender for the root logger. You can name this file log4j.properties
and place it in the application’s classpath. The log4j framework will pick up any log4j.
properties file in the classpath.

A Simple log4j Configuration File
#set the level of the root logger to DEBUG and set its appender
#as an appender named testAppender
log4j.rootLogger = DEBUG, testAppender
#define a  named logger
log4j.logger.dataAccessLogger = com.it.logging.logger

#set the appender named testAppender to be a  console appender
log4j.appender.testAppender=org.apache.log4j.ConsoleAppender

#set the layout for the appender testAppender
log4j.appender.testAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.testAppender.layout.conversionPattern=%m%n

The preceding configuration defines the level of the root logger as DEBUG and specifies the appender to use as testAppender. Next, we define the appender testAppender as referencing the org.apache.log4j.ConsoleAppender object and specify the layout of the appender as org.apache.log4j.PatternLayout. A PatternLayout also requires that a conversion pattern or a format be supplied. We supply the conversion pattern %m%n in this case, which means the
logging message will be printed followed by a newline character.
Note Within the conversion pattern, %m represents the message string and %n represents a newline character.
A more complex configuration can attach multiple appenders to a particular logger. Each
appender, in turn, can have a different layout, and that layout can have a conversion pattern
associated with it. The below listing is an example of a more complex configuration file.

Complex log4j Configuration File
# define the root logger with two appenders writing to console and file
log4j.rootLogger = DEBUG, CONSOLE, FILE

#define your own logger named com.foo
#and assign level and appender to your own logger

log4j.logger.com.foo=DEBUG,FILE

#define the appender named FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${user.home}/log.out

#define the appender named CONSOLE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.conversionPattern=%m%n

This configuration file defines the root logger as having level DEBUG and attaches two appenders named CONSOLE and FILE to it. We define one of our own custom loggers with the name com.foo and the level DEBUG and attach an appender named FILE to the custom logger. The appender FILE is defined as org.apache.log4j.FileAppender. The FILE appender writes to a file named log.out located in the user.home system path.

It is important to note that log4j supports UNIX-style variable substitution such as ${variableName}. The variable name defined is considered as the key and searched first in the system properties. If the log4j framework does not find the name, it then looks for the value for the variable in the properties file being parsed. The CONSOLE appender is then assigned to the org.apache.log4j.ConsoleAppender and the conversion pattern defined is %m%n, which means the printed logging message will be followed by a newline character.

XML-Style Configuration
With log4j, it is possible to define configuration parameters in an XML file and pass that file to the application at startup to configure different logging components. The XML configuration follows a document type definition (DTD) named log4j.dtd.

The configuration parameters and values are described in tag formats. For example, the config-
uration information in below lisitng can be defined in XML format as follows:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="dataAccessLogger" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="conversionPattern" value="%m%n"/>
</layout>
</appender>

<logger name="com.it.logging.log4j" additivity="false">
<level value="debug"/>
<appender-ref ref="dataAccessLogger"/>
</logger>

</log4j:configuration>

Both the XML-style configuration and properties-style configuration are quite effective in configuring log4j. Both are flexible and good configuration styles. However, a few components in log4j, such as Filter, AsyncAppender, etc., can be configured only through XML-style configuration. It seems that log4j is evolving from properties-style configuration toward XML-style configuration, and gradually it will embrace XML-style configuration as the standard. For the time being, you need to master both configuration styles.
Log4j Initialization
In general, log4j makes no assumption about the environment it is running in. Therefore, it is the application developer’s responsibility to configure log4j. Configuring log4j essentially means specifying loggers, appenders, layouts, etc. The LogManager class performs the initialization operation at startup only once through a class-level static initializer block. The default initialization operation consists of the following steps:
1.  The LogManager class looks for the system property log4j.configuration.
2.  If the log4j.configuration property is not defined, then it tries to look for a resource named  log4j.properties/log4j.xml in the application classpath.
3.  It then attempts to convert the defined configuration resource string to a URL object. If the resource string cannot be converted into a valid java.net.URL object, then it throws a java.net.MalformedURLException.
4.  If no resource can be found, the initialization is aborted.
5.  If the resource is found and if it is a normal Java properties-style file containing configuration information in a key-value format, then the org.apache.log4j.PropertyConfigurator class is used to parse the configuration file. If the configuration file is an XML file, the org.apache.log4j.xml.DOMConfigurator class is used to parse the XML file and initialize the logging objects.
It is possible to avoid the default initialization classes such as LogManager and write your own configuration class. The custom configuration class can be specified as a log4j.configurationClass to the Java runtime at application startup. Any custom configuration class should implement the org.apache.log4j.spi.Configurator interface by default.

No comments:

Post a Comment