Posted by : Munish Gogna Sunday, January 2, 2011

We all are familiar with log4j and use it in our projects to log various information. One of the most stunning features of log4j API is its manageability. Once the log statements have been inserted into the code, they can be controlled with configuration files. They can be selectively enabled or disabled, and sent to different and multiple output targets in user-chosen formats. Though there is nothing special in today's post yet it could be helpful to most of people out there. 
So let's get started....
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.
Loggers: are named entities. Logger names are case-sensitive and they follow the hierarchical naming rule. For example, the logger named "com.mg.log4j.test" is a parent of the logger named "com.mg.log4j.test.Log4j"  same as "java" is a parent of "java.util" and an ancestor of "java.util.Vector". This naming scheme is familiar to most of us. Loggers may also be assigned levels. The set of possible levels, that is: TRACE, DEBUG, INFO, WARN, ERROR and FATAL (For the standard levels, we have DEBUG < INFO < WARN < ERROR < FATAL)
Appenders and Layouts: 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.
The PatternLayout, part of the standard log4j distribution, lets the user specify the output format according to conversion patterns similar to the C language printf function.
For example, the PatternLayout with the conversion pattern "%r [%t] %-5p %c - %m%n" will output something akin to:
12 [main] INFO  com.mg.log4j.test - Happy New Year !!!
The first field is the number of milliseconds elapsed since the start of the program. The second field is the thread making the log request. The third field is the level of the log statement. The fourth field is the name of the logger associated with the log request. The text after the '-' is the message of the statement.
Also more than one appender can be attached to a logger.
Lets understand all with some example.
log4j.xml (should be in classpath, for a quick eclipse run keep it in src folder)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

 <!-- Append messages to the console -->
 <appender name="console" class="org.apache.log4j.ConsoleAppender">
  <param name="Target" value="System.out" />
  <param name="Threshold" value="DEBUG" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%d{ABSOLUTE} %5p [%c{1}:%L] - %m%n" />
  </layout>
 </appender>

 <!--
  Append messages to the file file.log , creating a new file once the
  size of file exceeds 1KB
 -->
 <appender name="file" class="org.apache.log4j.RollingFileAppender">
  <param name="file" value="C:/devel/workspace/log4j/file.log" />
  <param name="MaxFileSize" value="1KB" />
  <param name="Threshold" value="DEBUG" />
  <param name="Append" value="true" />
  <!-- maximum number of backup files that will be created -->
  <param name="maxBackupIndex" value="5" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%d{dd-MMM-yy HH:mm:ss} %5p [%c{1}] - %m%n" />
  </layout>
 </appender>


 <!-- The level is set to WARN -->
 <logger name="com.mg.log4j">
  <level value="WARN" />
  <appender-ref ref="console" />
 </logger>


 <!-- The level is set to DEBUG -->
 <logger name="FileAppener">
  <level value="DEBUG" />
  <appender-ref ref="file" />
 </logger>

 <root>
  <priority value="ALL" />
 </root>

</log4j:configuration>
Let's test this configuration...
package com.mg.log4j.test;

import org.apache.log4j.Logger;

public class Log4j {

 public static void main(String[] args) {
  // Get the default console appender, level is WARN
  // Note as you can see there is no such appender
  // 'com.mg.log4j.test.Log4j' defined in log4j.xml file, it fall backs on
  // the parent package
  Logger logger = Logger.getLogger("com.mg.log4j.test.Log4j");

  // Remember: The hierarchy is DEBUG < INFO < WARN < ERROR < FATAL

  // This request is not enabled as INFO < WARN
  logger.info("INFO");
  // This request is not enabled as DEBUG < WARN
  logger.debug("DEBUG");
  // This request is enabled as FATAL > WARN
  logger.fatal("FATAL");
  // This request is enabled as ERROR > WARN
  logger.error("ERROR");
  // This request is enabled as WARN >= WARN
  logger.warn("WARN");

  // // let's write to file appender now, level is DEBUG meaning it will
  // log everything
  logger = Logger.getLogger("FileAppener");
  for (int i = 1; i < 100; i++)
   logger.info("log me to file please, i want to see what happens after the size exceeds 1KB");

 }

}

OUTPUT:
11:44:35,984 FATAL [Log4j:21] - FATAL
11:44:35,987 ERROR [Log4j:23] - ERROR
11:44:35,987 WARN [Log4j:25] - WARN
and six log files - file.log, file1.log, file2.log, file3.log, file4.log and file5.log ( ignoring rest of the log statements after file5.log file because our threshhold limit for backup files was 5)


Please make sure that in real code you always check before logging, something like:
if(logger.isDebugEnabled())
logger.debug("Log only if debug is enabled");


Hope this small capsule will be helpful in some or other way. For more detailed understanding of log4j please visit official page at -  http://logging.apache.org/log4j/index.html

Wish you all a happy new year !!!!

One Response so far.

Leave a Reply

Subscribe to Posts | Subscribe to Comments

Popular Post

Labels

enums (1) java (2) JAX-RS (1) JPA (1) mysql (1) request 2 (1) RESTful (1) sphinx (1) tomcat (1) web service (2) ws (2)