Solved

Tomcat Log4J

Posted on 2006-07-11
4
1,351 Views
Last Modified: 2007-12-19
Hello I have a couple of questions regarding Tomcat and Log4J ( I am completely new to this ) ...I have been asked to provde for Log4J support for a web application that uses TomCat and Struts
I am looking for ansers for the following questions ..

1.What is Logj4 used for ?

2.How is it different from the regular tomcat log files ? Does it add new functionality to the logging ?

3.Do I need to change the existing code ...or can be done without toching the existing application.


Any Good tutorial or link which answer my questions ..will go a long way in answering my questions ....


Thanks for your time
0
Comment
Question by:micro_learner
4 Comments
 
LVL 19

Assisted Solution

by:Kuldeepchaturvedi
Kuldeepchaturvedi earned 100 total points
Comment Utility
Here is a link which tells you all about log4j

http://logging.apache.org/log4j/docs/documentation.html
0
 
LVL 8

Assisted Solution

by:kaliyugkaarjun
kaliyugkaarjun earned 100 total points
Comment Utility
0
 
LVL 2

Accepted Solution

by:
pankilmpatel earned 300 total points
Comment Utility
Hi,

Please find following material which i have.

1.Introduction

Almost every large application includes its own logging or tracing API. In conformance with this rule, the E.U. SEMPER project decided to write its own tracing API. This was in early 1996. After countless enhancements, several incarnations and much work that API has evolved to become log4j, a popular logging package for Java. The package is distributed under the Apache Software License, a fully-fledged open source license certified by the open source initiative. This logging API, currently in version 1.2.11, became so popular that it has been ported to other languages such as C, C++, Python, and even C# to provide logging framework for these languages.

2.Defining
Log4j is an OpenSource logging API for Java. It provides a robust, reliable, fully configurable, easily extendible, and easy to implement framework for logging Java applications for debugging and monitoring purposes. Log4j allows developers to insert log statements in their code and configure them externally.

3.Why Log4j?
Logging, or writing the state of a program at various stages of its execution to some repository such as a log file, is an age-old method used for debugging and monitoring applications. By inserting simple yet explanatory output statements (such as system.out.println () in the case of Java) in the application code that write to a simple text file, console, or any other repository, a reliable monitoring and debugging solution can be achieved. Although low-level, this is the mechanism to fall back upon when sophisticated debugging tools are either unavailable for any reason or useless such as in a distributed application scenario.
Inserting log statements manually is tedious and time-consuming, not to mention managing them (such as modifying and updating) down the road due to various reasons such as ongoing upgrading and bug-fixing process for application code, and so forth. To ease this process, there is a useful, efficient, and easy-to-use utility available, called log4j API.

4.How does Log4j work?
Log4j has three main components: loggers, appenders and layouts. 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.
Logger
The component logger accepts or enables log requests generated by log statements (or printing methods) during application execution and sends their output to appropriate destination, i.e. appender(s), specified by user.
The logger component is accessible through the Logger class of the log4j API. This class provides a static method Logger.getLogger (name) that either retrieves an existing logger object by the given name, or creates a new logger of given name if none exists.
      Each class in the Java application being logged can have an individual logger assigned to it or share a common logger with other classes. One can create any number of loggers for the application to suit specific logging needs. It is a common practice to create one logger for each class, with a name same as the fully qualified class name. This practice helps organize log outputs in groups by the classes they originate from, and identify origin of log output, which is useful for debugging.
Log4j provides a default root logger that all user-defined loggers inherit from. Root logger is at the top of the logger hierarchy; in other words, root logger is either parent or ancestor of all logger objects created. If an application class doesn't have a logger assigned to it, it can still be logged using the root logger.
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.foo" is a parent of the logger named "com.foo.Bar". Similarly, "java" is a parent of "java.util" and an ancestor of "java.util.Vector".
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.
Priority levels of log statements
Loggers can be assigned different levels of priorities. These priority levels decide which log statement is going to be logged. There are five different priority levels: DEBUG, INFO, WARN, ERROR, and FATAL; in ascending order of priority. As we can see, log4j has corresponding printing methods for each of these priority levels. These printing methods are used to generate log requests of corresponding priority level for log statements. For example: mylogger.info("logstatement-1"); generates log request of priority level INFO for logstatement-1.
The root logger is assigned the default priority level DEBUG. All loggers inherit priority level from their parent or nearest existing ancestor logger, which is in effect until they are assigned another priority level. A logger object can be assigned a priority level either programmatically by invoking its method setLevel (Level.x) where x can be any of the five priority levels, or through external configuration files. The latter is the most preferred way to do so.
After assigning a priority level to a logger, it will enable only those log requests with a priority level equal to or greater than its own. This technique helps prevent log statements of lesser importance from being logged. This concept is the core of log4j functionality.
Example of priority level of logger and log requests.
/* Instantiate a logger named MyLogger */
Logger mylogger = Logger.getLogger("MyLogger");
...
/* Set logger priority level to INFO programmatically. Though
   this is better done externally  */
mylogger.setLevel(Level.INFO);
...
/* This log request is enabled and log statement logged,
   since INFO = INFO */
mylogger.info("The values of parameters passed to do_something( )
               are: " + a, b);
...
/* This log request is not enabled, since DEBUG < INFO */
mylogger.debug("Operation performed successfully");
...
/* this log request is enabled and log statement logged, since
   ERROR > INFO*/
mylogger.error("Value of X is null");

Appender
Appender component is interface to the destination of log statements, a repository where the log statements are written/recorded. A logger object receives log request from log statements being executed, enables appropriate ones, and sends their output to the appender(s) assigned to it. The appender writes this output to repository associated with it. There are various appenders available; such as ConsoleAppender (for console), FileAppender (for file), JDBCAppender (for database), SMTPAppender (for SMTP server), SocketAppender (for remote server) and even IMAppender (for Instant Messenger).
An appender is assigned to a logger using the addAppender () method of the Logger class, or through external configuration files. A logger can be assigned one or more appenders that can be different from appenders of another logger. This is useful for sending log outputs of different priority levels to different destinations for better monitoring. For example: All log outputs with levels less than FATAL and ERROR being sent to files, while all those with levels equal to ERROR and FATAL sent to console for faster detection.
A logger also implicitly inherits appenders from its parents (and from ancestors, in that effect). Therefore, the log requests accepted by logger are sent to its own appenders along with that of all its ancestors. This phenomenon is known as appender additivity.
Using A ConsoleAppender
A 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 FileAppender
A 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 WriterAppender
A 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.

Layout
The Layout component defines the format in which the log statements are written to the log destination by appender. Layout is used to specify the style and content of the log output to be recorded; such as inclusion/exclusion of date and time of log output, priority level, info about the logger, line numbers of application code from where log output originated, and so forth. This is accomplished by assigning a layout to the appender concerned.
Layout is an abstract class in log4j API; it can be extended to create user-defined layouts. Some readymade layouts are also available in a log4j package; they are PatternLayout, SimpleLayout, DateLayout, HTMLLayout, and XMLLayout.

Configuring log4j
The log4j can be configured both programmatically and externally using special configuration files. External configuration is most preferred, because to take effect it doesn't require change in application code, recompilation, or redeployment. Configuration files can be XML files or Java property files that can be created and edited using any text editor or XML editor, respectively.
The simplest configuration file will contain following specifications that can be modified, both programmatically and externally, to suit specific logging requirements.
·      The priority level and name of appender assigned to root logger.
·      The appender's type (for example ConsoleAppender or FileAppender, and so forth).
·      The layout assigned to the appender (as SimpleLayout or PatternLayout and the like).
Configuration file in java property format.
# The root logger is assigned priority level DEBUG and an appender
# named myAppender.
log4j.rootLogger=debug, myAppender

# The appender's type specified as FileAppender, i.e. log output
# written to a file.
log4j.appender.myAppender=org.apache.log4j.FileAppender

# The appender is assigned a layout SimpleLayout.
# SimpleLayout will include only priority level of the log
# statement and the log statement itself in log output.
log4j.appender.myAppender.layout=org.apache.log4j.SimpleLayout
Configuration file log4j.xml in XML format.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="myAppender"
              class="org.apache.log4j.FileAppender">
        <layout class="org.apache.log4j.SimpleLayout"/>
    </appender>

    <root>
        <priority value="debug" />
        <appender-ref ref="myAppender"/>
    </root>

</log4j:configuration>

To use a log4j configuration file, it should be loaded using following code, preferably inserted in startup class of the application.
import org.apache.log4j.PropertyConfigurator;
...
PropertyConfigurator.configure("path/to/configuration_file");

5.      Since when
The first ancestor of log4j was written for the E.U. sponsored SEMPER project. N. Asokan, Ceki Gülcü and Michael Steiner came up with the idea of hierarchical loggers back in 1996. Their idea is still at the heart of log4j. The package was considerably improved over the years at the IBM Zurich Research Laboratory. However, log4j is no longer associated nor supported by IBM.
The log4j logo was designed and kindly donated by Cyberlab SA of Switzerland.
The latest version of log4j is 1.2.11. The next major release of log4j will be version 1.3

6.      Other Alternatives
Although log4j has received competition from new a logging API integrated into JSDK 1.4, log4j's strengths of being a mature, feature-rich, and efficient logging API framework, and wide usage for a long time are bound to hold against any competition. Also, compatibility with JSDK 1.4's logging API for easy to-and-fro migration, possibility for further improvements in this API, and new features to suit growing needs will surely make log4j's use continue for a long time to come.
7.      Advantages
·      The log4j printing methods used for logging can always remain in application code because they do not incur heavy process overhead for the application and assist in ongoing debugging and monitoring of application code, thus proving useful in the long term.
·      Log4j organizes the log output in separate categories by the name of generating loggers that in turn are same as the names of the classes they log. This approach makes pinpointing the source of an error easy.
·      Log4j facilitates external configuration at runtime; this makes the management and modification of log statements very simple and convenient as compared to performing the same tasks manually.
Log4j assigns priority levels to loggers and log requests. This approach helps weed out unnecessary log output and allows only important log statements to be logged.

8.      Shortcomings
·      Appender additivity may result in the log requests being unnecessarily sent to many appenders and useless repetition of log output at an appender. Appender additivity is countered by preventing a logger from inheriting appenders from its ancestors by setting the additivity flag to false.
·      When configuration files are being reloaded after configuration at runtime, a small number of log outputs may be lost in the short time between the closing and reopening of appenders. In this case, Log4j will report an error to the stderr output stream, informing that it was unable send the log outputs to the appender(s) concerned. But the possibility of such a situation is minute. Also, this can be easily patched up by setting a higher priority level for loggers.
9.      Usage
SimpleLayout and FileAppender
Here 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 WriterAppender
Here 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 ConsoleAppender
Here 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 newline      String 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");   }}
0
 

Author Comment

by:micro_learner
Comment Utility
Thanks all for your timer
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

In this step by step tutorial with screenshots, we will show you HOW TO: Enable SSH Remote Access on a VMware vSphere Hypervisor 6.5 (ESXi 6.5). This is important if you need to enable SSH remote access for additional troubleshooting of the ESXi hos…
In this article, I will show you HOW TO: Create your first Windows Virtual Machine on a VMware vSphere Hypervisor 6.5 (ESXi 6.5) Host Server, the Windows OS we will install is Windows Server 2016.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now