Showing posts with label Log4j. Show all posts
Showing posts with label Log4j. Show all posts

Log4j setup and configuration specific to module

Lets assume you would like to enable logging for the modules which starts with the package called com.sample.*.*.*. You need to create a log4j.properties file in \web-inf\classes folder. And place foloowing entries in the log4j.properties file. And make sure that log4j.jar file needs to be there in your class path (Ex: web-inf\lib folder)

log4j.logger.com.sample=DEBUG, sample
log4j.appender.sample.File=${user.dir}/sample/logs/sample.log
log4j.appender.sample.MaxFileSize=10MB
log4j.appender.sample.MaxBackupIndex=10
log4j.appender.sample.Append=false
log4j.appender.sample=org.apache.log4j.RollingFileAppender
log4j.appender.sample.layout=org.apache.log4j.PatternLayout
log4j.appender.sample.layout.ConversionPattern=%d{ABSOLUTE} %5p [%t] %c - %m%n

Log4J - Importance of logging In Java Applications

Logging can be defined as a process of storing information about events that occurred during program execution. There are different options to show/store log messages:


- show on console
- store in a file
- send to a remove monitor


Choosing the right option depends on the requirements and type of application.


Normally every java coder does logging even if he is not uing any logging framework. For instance, System.out.println statement is used to print informative message on the console. These messages can also contain the timestamp and other useful information which will make these messages interesting for the viewer and can help in error tracking and performance monitoring. But if you use a logging framework, then there is a big plus. The logging framework adds contextual information like line number, timestamp etc which prevents the developers from writing extra code. Result is better logging and less cost.


Importance of logging applications


Logging helps in debugging as well. Although debuggers are available but frankly it takes time to debug an application using a debugger. An application can be debugged more easily with few well-placed logging messages. So we can safely say that logging is a very good debugging tool. If logging is done sensibly and wisely, it can provide detailed context for application failures.


In distributed applications (e.g. web/remote applications), the logging is very important. The administrator can read logs to learn about the problems that occurred during some interval.


Java's built-in APIs provide logging options but they are not that flexible. Another option is to use Apache’s open source logging framework called log4j. 


Drawbacks of logging applications


There are some drawbacks of use logging in your application. For example: logging will


- pollute the code
- increase the size of the code
- reduce the speed


These are important points because, we ultimately want efficient applications. Log4J has the solution to this. You may turn on or turn off the logging at runtime by changing the configuration file. This means no change in the Java source code (binary).


Log4j


log4j is an open source project created by Apache and is part of Apache Logging Services Project. Currently Apache has 3 logging frameworks: 


- log4j for Java
- log4cxx for C++ 
- log4net for the Microsoft .NET framework


Apache also provides a tool called Chainsaw, which can be used for log analysis. If you are interested to learn about Chainsaw, visit the following link:
Apache Chainsaw -
API docs available at:
Logger (Apache Log4j 1.2.15 API)


The log4j package can be downloaded from 
Apache Logging Services Project - Apache log4j


Standard API vs log4j


A common question asked by Java developers is: 


Why we should use log4j logging framework when Java provides an API for logging (java.util.logging)?


Log4j has following advantages over standard logging API:
- log4j provides robust logging
- log4j has more features available than standard logging API
- configuring and using log4j is easier
- log4j also has a much more robust formatting system
- many add-on programs and handlers are available for log4j


Configuring log4j


Configuring log4j is very simple. You have to download the log4j-xxx.jar (xxx is the version no) file from the Apache logging services web site which is:
Apache Logging Services Project - Apache log4j


Currently there are 3 different versions available which are log4j 1.2, log4j 1.3 and log4j 2.0.


Once you have the jar file, you have to include that in your CLASSPATH. In Eclipse, you can simply import that jar file in your project. 


Categories of log messages


Before using log4j framework, one should be aware of different categories of log messages. Following are 5 categories:


DEBUG
The DEBUG Level is used to indicate events that are useful to debug an application. Handling method for DEBUG level is: debug().


INFO
INFO level is used to highlight the progress of the application. Handling method for INFO level is: info().


WARN
The WARN level is used to indicate potentially harmful situations. Handling method for WARN level is: warn().


ERROR
The ERROR level shows errors messages that might not be serious enough and allow the application to continue. Handling method for ERROR level is: error().


FATAL
The Fatal level is used to indicate severe events that will may cause abortion of the application. Handling method for FATAL level is: fatal().


If you declare log level as debug in the configuration file, then all the other log messages will also be recorded. 
If you declare log level as info in the configuration file, then info, warn, error and fatal log messages will be recorded.
If you declare log level as warn in the configuration file, then warn, error and fatal log messages will be recorded.
If you declare log level as error in the configuration file, then error and fatal log messages will be recorded.
If you declare log level as fatal in the configuration file, then only fatal log messages will be recorded.


Main Components


There are 3 main components that are used to log messages based upon type and level. These components also control the formatting and report place at runtime. These components are:


- loggers
- appenders
- layouts




log4j.properties file


log4j.properties file is a configuration file (not in XML format). If you have a stand alone application, then log4j.properties should be in the directory where you issued the java command. In case of web application (JSP/Servlet), place log4j.properties at /WEB-INF/classes/.


A sample properties file is given below:


log4j.appender.stdout=org.apache.log4j.ConsoleAppe nder
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.Patt ernLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{MMM dd HH:mm:ss}] %-5p (%F:%L) - %m%n
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.file=C:\\Log4J\\src\\tmp\\logs \\log.txt
log4j.appender.FILE.layout=org.apache.log4j.Patter nLayout
log4j.appender.FILE.layout.ConversionPattern=[%d{MMM dd HH:mm:ss}] %-5p (%F:%L) - %m%n
log4j.rootLogger=debug, FILE,stdout


We have used only two appenders (ConsoleAppender and FileAppender)in the example above. All the possible appender options are:


AppenderSkeleton, AsyncAppender, ConsoleAppender, DailyRollingFileAppender, ExternallyRolledFileAppender, FileAppender, JDBCAppender, JMSAppender, LF5Appender, NTEventLogAppender, NullAppender, RollingFileAppender, SMTPAppender, SocketAppender, SocketHubAppender, SyslogAppender, TelnetAppender, WriterAppender


We have used PatternLayout with both the appenders. All the possible options are:


DateLayout, HTMLLayout, PatternLayout, SimpleLayout, XMLLayout


So interesting thing is, you can generate log in HTML and in XML format as well.


If you use HTMLLayout or XMLayout, then you should not mention ConversionPattern. 

Enable JDBC Logging

import java.net.URL;
import java.sql.*;


class JDBCapp  {
  static MyConnection theConn;


  public static void main (String args[]) {
    new JDBCapp().doit();
    }


  public void doit() {
    theConn = new MyConnection();
    theConn.connect("EAS Demo DB V3", "dba", "sql");


PreparedStatement prepstmt;
try {
  prepstmt = theConn.dbConn.prepareStatement
   ("SELECT emp_id FROM employee" );
  prepstmt.execute();
  prepstmt.close();
  }
catch (Exception e) { e.printStackTrace(); }
  theConn.disconnect();
  }
}




class MyConnection {
  Connection dbConn = null;
  void connect(String db, String user, String passw) {
    try {
      Driver d = 
       (Driver)Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
      String URL = "jdbc:odbc:" + db;
      dbConn = DriverManager.getConnection(URL, user, passw);
      java.io.PrintWriter w =
        new java.io.PrintWriter
           (new java.io.OutputStreamWriter(System.out));
      DriverManager.setLogWriter(w);
      }
    catch (Exception e) {
      e.printStackTrace();
      }
    }


  void disconnect() {
    try {
      dbConn.close();
      }
    catch (Exception e) {
      e.printStackTrace();
      }
    }
}

Logging Example in Java

import java.util.logging.*;
import java.io.*;


public class TestLog {


public static Logger logger;


static {
    try {
      boolean append = true;
      FileHandler fh = new FileHandler("TestLog.log", append);
      //fh.setFormatter(new XMLFormatter());
      fh.setFormatter(new SimpleFormatter());
      logger = Logger.getLogger("TestLog");
      logger.addHandler(fh);
    }
    catch (IOException e) {
      e.printStackTrace();
    }
}


public static void main(String args[]) {
    logger.severe("my severe message");
    logger.warning("my warning message");
    logger.info("my info message");
    }
}


Output :



2005-02-28 21:19:28 TestLog main
GRAVE: my severe message
2005-02-28 21:19:28 TestLog main
ATTENTION: my warning message
2005-02-28 21:19:28 TestLog main
INFO: my info message

Configuring Java Logging in Tomcat

As stated above the default logging supplied by the Java packages does not have the ability to distinguish between different web applications because all the configuration is done at the VM level. For this reason Tomcat 5.5.9 replaces the default LogManager with a more web application friendly implimentation called JULI (Note: on the Tomcat site it implies that all 5.5.x versions include JULI but it wasn't actually included until 5.5.9). To configure JULI you can place a file called logging.properties in the the directory $CATALINA_HOME/common/classes or in your web applications WEB-INF/classes directory. The format of the file is very similar to that of the default Java configuration but it has some additional options that allow it to set up logging on a per-web application basis.

The most important extenstion is to the handler definitions. Each handler can take an optional prefix which takes the form of a numeral followed by any alphanumerics and ends with a ".". For instance a valid perfix would be "7foo.". This lets you define different handlers for different loggers and configure them separatly. Loggers are still shared at the VM level but you can at least now turn sections of logging on and off. For instance to define handlers for the logger "com.crazysquirrel" you might place a file such as this in the WEB-INF/class directory of your web application
handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

org.apache.juli.FileHandler.level=ALL
org.apache.juli.FileHandler.directory=${catalina.base}/logs
org.apache.juli.FileHandler.prefix=cs-logging-test-

java.util.logging.ConsoleHandler.level=FINE
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

Logging configuration properties


JBoss uses the Log4jService (in JBoss AS 5.x and earlier) or the LoggingService (in JBoss AS 6.x and later) to configure logging.
This service is not configured until after the bootstrap phase.

During the bootstrap the microkernel logs into log/boot.log using the configuration
from log4j.properties (in 5.x and earlier) or logging.properties (in 6.x and later) in $JBOSS_HOME/bin/run.jar.

Customizing Boot Logging

You can either change the configuration inside run.jar or use a system property to reference an outside configuration file.

Changing log4j.properties or logging.properties inside run.jar

The simplest strategy is to un-jar $JBOSS_HOME/bin/run.jar, change the appropriate properties file and re-jar. (the Open Source archiving software 7-zip does a good job at editing files inside of archives). For AS 5.x and earlier, two pre-configured alternate property files exist in run.jar for DEBUG and TRACE logging.  In 6.x and later, the following system properties may be used to override the log level setting:
  • jboss.boot.server.log.level sets the log level for the root logger (i.e. controls what is returned byisXXXEnabled() calls against the root logger or any subcategory that isn't otherwise configured. Default is INFO.
  • jboss.boot.server.log.console.level sets the minimum level for messages to be handled by the handler that writes to the console. Default is INFO. 
  • jboss.boot.server.log.file.level sets the minimum level for messages to be handled by the handler that writes to the boot.log file. Default is DEBUG.
  • jboss.boot.server.log.serverinfo.level sets the log level for the org.jboss.system.server.ServerInfo category. Default is DEBUG, which allows some useful configuration information to be written to the boot.log (whose handler by default accepts DEBUG messages). This property was added for 6.0.0.M2.

Referencing an outside configuration

If you're looking for a less intrusive option, follow these steps:
  • extract log4j.properties or logging.properties from run.jar into, e.g. bin/log4j.properties or bin/logging.properties
  • edit run.bat (or .sh) and add:
set JAVA_OPTS=%JAVA_OPTS% -Dlog4j.configuration=file:%DIRNAME%log4j.properties
or for 6.x and later:
set JAVA_OPTS=%JAVA_OPTS% -Dlogging.configuration=file:%DIRNAME%logging.properties
During the bootstrap your log4j initialization file will be used in place of the one located in run.jar

You can also specify the boot log configuration at the command line, instead of editing run.bat/run.sh, for example:
   run.bat -Dlog4j.configuration=file:./log4j.properties
or for 6.x and later:
   run.bat -Dlogging.configuration=file:./logging.properties
or better, specify the full (URL) path to the file
   run.bat -Dlog4j.configuration=file:///C:/jboss/jboss-4.0.2/bin/log4j.properties
or for 6.x and later:
   run.bat -Dlogging.configuration=file:///C:/jboss/jboss-6.0.0/bin/logging.properties

Logging command line options in boot.log

Since AS 5.1.0.Beta1, command line parameters, including VM parameters, are shown in the boot.log. This has been achieved taking advantage of the following method available since JDK5:java.lang.management.RuntimeMXBean.getInputArguments(). See JBAS-5240 for further details. Example:
13:44:43,226 INFO [ServerInfo] VM arguments: -Dprogram.name=run.sh
-Xms128m -Xmx512m -XX:MaxPermSize=256m
-Dorg.jboss.resolver.warning=true
-Dsun.rmi.dgc.client.gcInterval=3600000
-Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.net.preferIPv4Stack=true
-Djava.endorsed.dirs=/home/galder/jboss/code/as/trunk/build/output/jboss-6.0.0.Alpha1/lib/endorsed

Logging configuration properties (6.x and up)

As of AS 6.0.0, the boot-time logging subsystem may be configured through the use of a logging.properties file.  The following properties may be specified:

  • Logger options
    • loggers=<category>[,<category>,...] - Specify a comma-separated list of logger categories which will be configured.  Any categories not listed here will not be configured from the following properties.
    • logger.<category>.level=<level> - Specify the level for a category.  The level can be a JDK logging level (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST), a log4j-style level (FATAL,ERROR, WARN, INFO, DEBUG, TRACE), or a special level (OFF, ALL).  If unspecified, the nearest parent's level will be inherited.
    • logger.<category>.handlers=<handler>[,<handler>,...] - Specify a comma-separated list of the names of handlers to attach to this logger.  The handlers must be configured in the same properties file.
    • logger.<category>.filter=<filter> - Specify a filter for a category.  The filter must be configured in the same properties file.
    • logger.<category>.useParentHandlers=(true|false) - Specify whether log messages should cascade up to parent handlers.  The default value is true.
  • Handler options
    • handler.<name>=<className> - (Required) Specify the class name of the handler to instantiate.
    • handler.<name>.level=<level> - Restrict the level of this handler.  If unspecified, the default value of ALL is retained.
    • handler.<name>.encoding=<encoding> - Specify the character encoding, if it is supported by this handler type.  If not specified, a handler-specific default is used.
    • handler.<name>.errorManager=<name> - Specify the name of the error manager to use.  The error manager must be configured in the same properties file.  If unspecified, no error manager is configured.
    • handler.<name>.filter=<name> - Specify the name of the filter to use.  The filter must be configured in the same properties file.  If unspecified, messages are not filtered.
    • handler.<name>.formatter=<name> - Specify the name of the formatter to use, if it is supported by this handler type.  The formatter must be configured in the same properties file.  If not specified, messages will not be logged for most handler types.
    • handler.<name>.properties=<property>[,<property>,...] - Specify a list of JavaBean-style properties to additionally configure.  A rudimentary type introspection is done to ascertain the appropriate conversion for the given property.
    • handler.<name>.<property>=<value> - Set the value of the named property.
  • Error manager options
    • errorManager.<name>=<className> - (Required) Specify the class name of the error manager to instantiate.
    • errorManager.<name>.properties=<property>[,<property>,...] - Specify a list of JavaBean-style properties to additionally configure.  A rudimentary type introspection is done to ascertain the appropriate conversion for the given property.
    • errorManager.<name>.<property>=<value> - Set the value of the named property.
  • Formatter options
    • formatter.<name>=<className> - (Required) Specify the class name of the formatter to instantiate.
    • formatter.<name>.properties=<property>[,<property>,...] - Specify a list of JavaBean-style properties to additionally configure.  A rudimentary type introspection is done to ascertain the appropriate conversion for the given property.
    • formatter.<name>.<property>=<value> - Set the value of the named property.
  • Filter options
    • filter.<name>=<className> - (Required) Specify the class name of the filter to instantiate.
    • filter.<name>.properties=<property>[,<property>,...] - Specify a list of JavaBean-style properties to additionally configure.  A rudimentary type introspection is done to ascertain the appropriate conversion for the given property.
    • filter.<name>.<property>=<value> - Set the value of the named property.

Example configuration

This is an example logging.properties that you can use to get started.

# Additional logger names to configure (root logger is always configured)
#loggers=org.foo.bar, org.foo.baz

# Root logger level
logger.level=DEBUG

# Declare handlers for the root logger
logger.handlers=CONSOLE, FILE

# Declare handlers for additional loggers
#logger.org.foo.bar.handlers=XXX, YYY

# Console handler configuration
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
handler.CONSOLE.properties=autoFlush
handler.CONSOLE.level=INFO
handler.CONSOLE.autoFlush=true
handler.CONSOLE.formatter=PATTERN

# File handler configuration
handler.FILE=org.jboss.logmanager.handlers.FileHandler
handler.FILE.level=DEBUG
handler.FILE.properties=autoFlush,fileName
handler.FILE.autoFlush=true
handler.FILE.fileName=your/log/directory/server.log
handler.FILE.formatter=PATTERN

# The log format pattern for both logs
formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
formatter.PATTERN.properties=pattern
formatter.PATTERN.pattern=%d{HH:mm:ss,SSS} %-5p [%c{1}] %m%n


Enter your email address to get our daily JOBS & INTERVIEW FAQ's Straight to your Inbox.

Make sure to activate your subscription by clicking on the activation link sent to your email