Tuesday, 29 April 2014

what is log4j

Log4j:
Generally, we use System.out.println (“”) statements to debug the application. We use System.out.println (““) statements frequently in a java applications weather it is a client side executing or server side executing code.
While developing Java/J2EE applications, for debugging an application that is to know the status of a java application at its execution time, in general we use System.out.println (“”) statements in the application right…
->With System.out.println (““) statements, the following problems are faced in real time applications…
Disadvantages:
         If there is more number of System.out.println (““) statements in an application then we can’t see all the statements on console, because of console are scrolled up.
         System.out.println (““) statements are temporary i.e., when a console is closed then all statements on console are erased/removed.
         Server side applications, if we put System.out.println (““) statements then they are displayed on server console. But, all may not have console.
Ex: - jboss server.

So, we may lose System.out.println (““) messages.

When an onsite developers wants to report a bug occurred and the status of a project execution at client to offshore developers then it is not possible with System.out.println (““) statements.

To Overcome All System.out.println (“”) problems:

To overcome all the above problems, a java developer has two options.

1).A developer can choose logging to like log4j.It is developed by Apache guys.
2).A developer can choose java logging API. It is belongs to java API.
         In order to overcome the problems of SOPL statements Log4j came into picture, with Log4j we can store the flow details of our Java/J2EE in a file or databases.
         This is a Open Source tool given by Apache, for only java projects, to record or write the status of an application at various places.
         Log4j is a common tool, used for small to large scale Java/J2EE projects
         In real time, after a project is released and it is installed in a client location then we call the location as on-site right, when executing the program at on-site location, if we got any problems occurred then these problems must report to the off showered engineers,  in this time we used to mail these Log files only so that they can check the problems easily.

Log4j is the best option for logging than java logging API. Because, the tool supports logging modifications by without touching source code of the project.
What is Log4j?

 It is an open source logging tool, given by apache to use as an alternative for System.out.println (““) statements in a java project.
It has 3 main components to work with Log4j

1) Logger Object
2) Appender Object
3) Layout Object

Logger:
Logger Object is responsible for capturing logging messages generated at execution time of an application.
         Logger is a class, in org.apache.log4j.*
         We need to create Logger object one per java class.
         Logger class methods are used to generate log statements in a java class instead of System.out.println(“”) statements;

static Logger logger=Logger.getLogger (String classname);
static Logger logger=Logger.getLogger (Class clazz);
getLogger () method is a static factory methods .its returns a class object.
Logger object has some methods; actually we used to print the status of our application by using these methods only
We have a method in Logger class
         debug()
         info()
         warn()
         error()
         fetal()
As a programmer it’s our responsibility to know where we need to use what method.

Appender:
Appender Object is responsible for storing(printing) the logging messages to a different destinations.
Ex:- Files, console and database.
If you are willing to add Appender object inside your program then you can use following method.
public void addAppender(Appender appender);

The addAppender(Appender appender) method adds an Appender to the Logger object. It is possible to add many Appender objects to a logger in a comma-seperated list, each printing logging information to seperate destinations.
         Logger classes generates some statements under different levels right, this Appender takes these log statements and stores in some files or database.
         Appender is an interface. It is implemented by some predefined classes.

We have so many Appender interface classes are..
         FileAppender                   (writing into a file )
         ConsoleAppender          (Writing into console )
      JDBCAppender                (For Databases )
         JMSAppender
         RollingFileAppender
         SocketAppender

           
Layout:
Layout Object is responsible for formatting logging messages.
Appender object uses the support of Layout object for formatting the messages.
Layout is an interface, implemented classes are..
         SimpleLayout
         PatternLayout
         HTMLLayout
         XMLLayout
         DataLayout   etc.........
The most frequently used Layout  is PatternLayout.Because, it has provided ConversionPattern through which we can make a logging statement as more info
rmative.
The most ConversionPattern are.....
%t
Add thread name
%-5p
Add a priority level with left justification
%d
Adds Date and Time. We use
%d{dd/mm/yyyy hh:mm:ss}-to add a time & date.
%c
Add fully qualified class name
%m
Adds message
%n
Adds new line (next line).
%L
Adds line number of the message in a program
%M
Adds method name from which the logging message in generated
%r
Adds the milliseconds of time completed from the construction of layout of current msg.



Why log4j.properties file :
          I am using FileAppender now, but if i would like to change my appender to JDBCAppender, i have to open my java file and do the modifications and need to recompile.  We can avoid this by writing one .properties file.
By default the file name would be log4j.properties. This properties file stores data in the form of key, values pairs, in this file keys are fixed but values are our own (developer changed).

log4j.properties

log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.file=mylog.txt
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern= %m %n

         log4j.rootLogger = DEBUG,A1 — > Here DEBUG means we are specifying the level from where log4j methods execution must start,  see mylog.txt file it showing all messages right.  But if we wrote log4j.rootLogger = WARN,A1 then it will prints the messages in    l.warn(), l.error(), l.fatal() only  printed ,remaining logs ignore like  l.debug(), l.info() because of priority.
         I have used FileAppender as my Appender, so if we want to change my appender to ConsoleAppender, i will open log4j.properties file and do the modifications,  so no need to touch our java classes, this is the main advantage of log4j.properties file.

Obtaining a Logger object:
Logger is a class of org.apache.log4j package and its object is used to insert logging statements in a java class.
To obtain a Logger object we call a static factory method of the class getLogger () method.
Logger objects are created on “per class basis”. It means one Logger object is generated for one class to insert log statements.

Syntax: 
Logger logger=Logger.getLogger (String classname);
Logger logger=Logger.getLogger (Class clazz);
Example:
Logger logger=Logger.getLogger (“SampleLogger”);
Logger logger=Logger.getLogger (SampleLogger.class);

Note:- In a class, we create more than one Logger object then they became reference to one object only but not different objects.
For example:
Logger logger1=Logger.getLogger (SampleLogger.class);
Logger logger2=Logger.getLogger (SampleLogger.class);

Here, logger1 and logger2 are reference pointing to a Single Logger object.
If you want to know just compare logger1 and logger2 objects by using == (equal) operator.

Why we make a Logger object in class as static final?

Static final Logger logger=Logger.getLogger (Sample. class);
A class can have both static and instance methods. Logging statements are required in both methods.
 If we make Logger object as non-static then it can be used in only instance methods but not in static methods. So, we make Logger object as static. In order to use it in both static and instance methods of class.

We make a Logger object as final because, we definitely need one Logger object per one Class. And should not be changeable.so, we make it as final.

Priority Levels of Logging statements:

To insert logging statements in a java class we should assign some priority for those statements.
Log4j has given priority levels and respective methods but it is a programmer responsibility to apply an appropriate level for a statement.
The priority levels of a log4j are
1) ALL
2) TRACE
3) DEBUG
4) INFO
5) WARN
6) ERROR
7) FATAL
8) OFF
ALL<TRACE<DEBUG<INFO<WARN<ERROR<FATAL<OFF

->The standard priority levels used in a java application are…
     
1)DEBUG:
To indicate a control enter or exit from a method or class or module of a project
2)INFO:
To indicate some information like a server started or a connection is opened or an application is deployed or a connection is closed or server or services are closed
3)WARN:
To indicate some warning messages like a connection between client and server is lost or a socket is reached its limit etc.
4)ERROR:
To indicate some error message .Generally, we use this level in catch block of our code.
5)FATAL:
To indicate some un-recoverable error or problem. Generally, when a fatal error occurs then the application is aborted or terminated.
log4j.properties

log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.file=mylog.txt
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern= %m %n

         log4j.rootLogger = DEBUG,A1 — > Here DEBUG means we are specifying the level from where log4j methods execution must start,  see mylog.txt file it showing all messages right.  But if we wrote log4j.rootLogger = WARN,A1 then it will prints the messages in    l.warn(), l.error(), l.fatal() only  printed ,remaining logs ignore like  l.debug(), l.info() because of priority.
         I have used FileAppender as my Appender, so if we want to change my appender to ConsoleAppender, i will open log4j.properties file and do the modifications,  so no need to touch our java classes, this is the main advantage of log4j.properties file.

Steps for  compile and run log4j program :
To compile and run applications, we need to set log4j-1.2.17.jar in classpath.
To compile and run application, we need to set log4j-1.2.17.jar file.
step1: set the classpath
              ->set CLASSPATH=log4j-1.2.17.jar;.;

step2: develop a java application with log messages.

                        package com.dustbin.test;

                        import org.apache.log4j.Logger;

                        public class Sample {

                        static Logger logger=Logger.getLogger(Sample.class);

                        public static void main(String[] args) {

                   BasicConfigurator.configure();

                   logger.info("info message");
                   logger.warn("warn message");
                   logger.error("error message");
                   logger.fatal("fatal message");
                   logger.debug("debug msg");

                                      }

                             }
step3: print a log messages on console
Output:

                   0 [main] INFO com.dustbin.test.Sample  - info message
                   0 [main] WARN com.dustbin.test.Sample  - warn message
                   0 [main] ERROR com.dustbin.test.Sample  - error message
                   0 [main] FATAL com.dustbin.test.Sample  - fatal message
                   0 [main] DEBUG com.dustbin.test.Sample  - debug msg


Log4j Configuration:
          Configuring log4j involves assigning the LEVEL,defining Appender, and specifying Layout objects in a configuration file.

1)BasicConfigurator
2)PropertyConfigurator
3)DomConfigurator

BasicConfigurator:
If are do not create a property file or xml file for log4j properties then we use BasicConfigurator class.
The BasicConfigurator.configure() method by default it uses the  Console Appender and Pattern Layout for log statements.
Program:

package com.dustbin.test;

import org.apache.log4j.Logger;

public class Sample {
static Logger logger=Logger.getLogger(Sample.class);
public static void main(String[] args) {

logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
logger.debug("debug msg");

}

}

Output:
We got an exception like…

log4j:WARN No appenders could be found for logger (com.dustbin.test.Sample).
log4j:WARN Please initialize the log4j system properly.

Soluation:
package com.dustbin.test;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

public class Sample {
static Logger logger=Logger.getLogger(Sample.class);
public static void main(String[] args) {
BasicConfigurator.configure();

logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
logger.debug("debug msg");

}

}

Output:

0 [main] INFO com.dustbin.test.Sample  - info message
0 [main] WARN com.dustbin.test.Sample  - warn message
0 [main] ERROR com.dustbin.test.Sample  - error message
0 [main] FATAL com.dustbin.test.Sample  - fatal message
0 [main] DEBUG com.dustbin.test.Sample  - debug msg

Explanation:
Milliseconds   thread    level     fully qualified name - message
%r         %t          %               %c                         %m

PropertyConfigurator:
If we create a properties file (.properties), then we should use Property Configurator class for loading that file.
You need to use the PropertyConfigurator.configure() method to configure log4j using a properties file.Log4j should be configured only once for the entire application.
Note:-  properties file contains only key and value.

Example:-
Program for using ConsoleAppender and SimpleLayout from DEBUG level.
log4j.properties

log4j.rootLogger=DEBUG,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.SimpleLayout

Sample.java
package com.dustbin.test;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class Sample {
static Logger logger=Logger.getLogger(Sample.class);
public static void main(String[] args) {
PropertyConfigurator.configure("c:/logs/log4j.properties");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
logger.debug("debug msg");
}
}ss
Output:
INFO - info message
WARN - warn message
ERROR - error message
FATAL - fatal message
DEBUG - debug msg

Some times we get below type exception ....
log4j:ERROR Could not read configuration file [C:/log/log4j.properties].
java.io.FileNotFoundException: C:\log\log4j.properties (The system cannot find the path specified)

Note:-specify absolute path of the log4j.properties file

Example2:(log msgs are printed on console using ConsoleAppender class)
 Write a sample program for using ConsoleAppender and PatternLayout follow conversion pattern format.
log4j.properties
log4j.rootLogger=INFO,CA
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=%-4r %d [%t] %C %-5p %m %n

Sample.java
package com.dustbin.test;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class Sample {
static Logger logger=Logger.getLogger(Sample.class);
public static void main(String[] args) {
PropertyConfigurator.configure("C:/logs/log4j.properties");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
logger.debug("debug msg");
}
}

output:
0    2014-02-14 15:09:10,020 [main] com.dustbin.test.Sample INFO  info message
16   2014-02-14 15:09:10,036 [main] com.dustbin.test.Sample WARN  warn message
16   2014-02-14 15:09:10,036 [main] com.dustbin.test.Sample ERROR error message
16   2014-02-14 15:09:10,036 [main] com.dustbin.test.Sample FATAL fatal message

log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: c:\logs.log (A required privilege is not held by the client)

Example3:( printed log messages using FileAppender class into file)
Approach1:  
develop a log messages properties file by using FileAppender class
step 1: develop a .properties file like
using property file externally.
log4j.properties
log4j.rootLogger=INFO,CA
log4j.appender.CA=org.apache.log4j.FileAppender
log4j.appender.CA=d:\logs.txt
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=%-4r %d [%t] %C %-5p %m %n


step2: develop a java class
package com.dustbin.test;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class Sample {
static Logger logger=Logger.getLogger(Sample.class);
public static void main(String[] args) {
PropertyConfigurator.configure("C:/logs/log4j.properties");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
logger.debug("debug msg");
}
}
output:
logging messages are printed on file location d:\logs.txt
0    2014-02-14 15:23:54,208 [main] com.dustbin.test.Sample INFO  info message
0    2014-02-14 15:23:54,208 [main] com.dustbin.test.Sample WARN  warn message
0    2014-02-14 15:23:54,208 [main] com.dustbin.test.Sample ERROR error message
0    2014-02-14 15:23:54,208 [main] com.dustbin.test.Sample FATAL fatal message

Approach 2 :  (log msgs into file)
printed log messages  in Program level.
Here we are developing a java class for creating log messages file under program level.
Example:
package com.dustbin.test;
import java.io.IOException;
import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.PropertyConfigurator;
public class Sample {
static Logger logger=Logger.getLogger(Sample.class);
public static void main(String[] args)throws IOException {
Layout layout=new PatternLayout();
Appender appender=new FileAppender(layout,"d:/vijay.txt");
logger.addAppender(appender);
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
logger.debug("debug msg");
}
}
output:
log messages are printed into file by creating file using java program

Example4: (log msgs into Database file)
Develop a application for storing logging msgs using Database using JDBCAppender class.
the following steps are ...
step1:
create table logs(thread varchar2(20),classname varchar2(20),logmsg varchar2(20));
step2: develop a property file
log4j.properties
log4j.rootLogger=DEBUG,DB
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.driver=oracle.jdbc.driver.OracleDriver
log4j.appender.DB.URL=jdbc:oracle:thin:@localhost:1521:xe
log4j.appender.DB.user=praveen
log4j.appender.DB.password=praveen
log4j.appender.DB.sql=insert into logs values('%t','%c','%m')
log4j.appender.DB.layout=org.apache.log4j.PatternLayout

program for JDBCAppender:

package com.dustbin.test;
import java.io.IOException;
import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.PropertyConfigurator;
public class Sample {
static Logger logger=Logger.getLogger(Sample.class);
public static void main(String[] args)throws IOException {
PropertyConfigurator.configure("C:/logs/log4j.properties");
logger.debug("debug msg");
logger.info("info message");
logger.warn("warn message");
logger.error("error message");
logger.fatal("fatal message");
}
}
Output:
-> select * from logs;
log messages are printed in table.





Share This Post →

No comments:

Post a Comment

Powered By Blogger |   Design By Srikanth Ganji
Join Our Community
×
blogger tipsblogger templatesFOLLOW