Recent Posts

Thursday, 21 April 2016

Log4j Tutorial



What Is Log4j, Why Log4j Came Into Picture
      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. But we have some disadvantages while using SOPL (system.out.println) statements.

* Generally SOPL statements are printed on console, so there are temporary messages and whenever the console is closed then automatically the messages are removed from the console.

* It is not possible to store the SOPL messages in a permanent place and these are single threaded model, means these will prints only one by one message on the console screen.

* 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 an Open Source tool given by Apache, for only java projects, to record or write the status of an application at various places.

* Working with log4j is nothing but working with classes & interfaces given in org.apache.log4j.

* Log4j is a common tool, used for small to large scale Java/J2EE projects.

* In Log4j we use log statements rather SOPL statements in the code to know the status of a project while it is executing.

* 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.
    Main Components of Log4J
               We have mainly 3 components to work with Log4j …
    1. Logger
    2. Appender
    3. Layout
      1. Logger
      * Logger is a class, in org.apache.log4j.*

      * We need to create Logger object one per java class.

      * Responsible for capturing logging information.

      * This component enables Log4j in our java class.

      * Logger methods are used to generate log statements in a java class instead of SOPLS.

      * So in order to get an object of Logger class, we need to call a static factory method [ factory method will gives an object as return type ]

      * We must create Logger object right after our class name, it will show you

      * Getting Logger Object
      static Logger log = Logger.getLogger(YourClassName.class.getName())
      Note
           While creating a Logger object we need to pass either fully qualified class name or class object as a parameter, class means current class for which we are going to use Log4j.
      Example
      public class Client {
         static Logger l = Logger.getLogger(Client.class.getName());
         public static void main(String[] args) {
            // Our logic will goes here
         }
      }
      
               Logger object has some methods; actually we used to print the status of our application by using these methods only.
      We have totally 5 methods in Logger class
      debug()
      info()
      warn()
      error()
      fatal()
           As a programmer it’s our responsibility to know where we need to use what method, did you observe there? Method names are different right, but all are same.Priority Order
      debug < info < warn < error < fatal
               It means fatal is the highest error likes some database down/closed.

      Remember: Don’t confuse by seeing all these 5 methods all are same, for example if our application is about 100 lines and we have JDBC related code in some 45th line or somewhere there we used to write fatal() method. All it could be is just for human identification purpose names are different; else these 5 methods will print one text message only.


      2. Appender
      * Appender job is to write the messages into the external file or database or SMTP.

      * Responsible for publishing logging information to various preferred 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.
      In log4j we have different Appender implementation classes
      FileAppender [ writing into a file ]
      ConsoleAppender [ Writing into console ]
      JDBCAppender [ For Databases ]
      SMTPAppender [ Mails ]
      SocketAppender [ For remote storage ]
      SocketHubAppender
      SyslogAppendersends
      TelnetAppender
      Again in FileAppender we have 2 more
      RollingFileAppender
      DailyRollingFileAppender
      For now just remember, it will explain while executing the program

      3. Layout
      * This component specifies the format in which the log statements are written into the destination repository by the appender.

      * Responsible to format logging information in different styles.

      * We have different type of layout classes in log4j
      SimpleLayout
      PatternLayout
      HTMLLayout
      XMLLayout
      
      Example
            Let us see one simple program in Log4j. For working with log4j, we must set log4j.jar in our class path. Files Required
      MyLog4J.java myLog.log [We will let the appender to write into this file] MyLog4J.java
      package com.ashok.log4j;
      
      import org.apache.log4j.Appender;
      import org.apache.log4j.FileAppender;
      import org.apache.log4j.Layout;
      import org.apache.log4j.Logger;
      import org.apache.log4j.SimpleLayout;
      public class MyLog4J{
         static Logger log = Logger.getLogger(MyLog4J.class.getName());
         public static void main(String[] args){
            Layout layout = new SimpleLayout();
            Apender appender;
            try {
               appender = new FileAppender(layout,"myLog.log", false);
               // 3rd parameter is true by default
               // true = Appends the data into myLog.log
               // false = delete previous data and re-write log.addAppender(appender);
            }
            catch(Exception e) {}
      
            log.debug("Hello this is an debug message");
            log.info("Hello this is an info message"); 
            log.warn("Hello this is an warn message");
            log.error("Hello this is an error message");
            log.fatal("Hello this is an fatal message");
            System.out.println("Your logic executed successfully....");
         }
      }
      
      Once we run this client program, myLog.log will contains….
      myLog.log
      DEBUG - Hello this is an debug message
      INFO - Hello this is an info message
      WARN - Hello this is an warn message
      ERROR - Hello this is an error message
      FATAL - Hello this is an fatal message
      Explanation
      * First step is to create one Logger class object.

      * Second step is to create Layout object.

      * Once Layout is ready, our next step is to create Appender

      * In appender we have passed 3 parameters like. first parameter is object of layout because, appender will write the error messages based on the layout we selected, then 2nd parameter is file name with extension [in this file only appender will writes the messages], then 3rd parameter is by default true, means appender will appends the error messages, if we give false then appender will clears the previous data in myLog.log file and write newly.

      * Hey see, we have used FileAppender, but if it would like to change my appender choice to ConsoleAppender, then again we must open this java file then modifications and recompile bla bla…, so to avoid this we can use one .properties file.

        How to Create Log4j.properties File

                In previous program, we have used FileAppender. But if we would like to change my appender to JDBCAppender, we 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. We can include all the log4j related properties into this file.

        log4j.properties
        log4j.rootLogger=DEBUG, CONSOLE, LOGFILE
        log4j.appender.CONSOLE=
        log4j.appender.CONSOLE.layout=
        log4j.appender.CONSOLE.layout.ConversionPattern=
        log4j.appender.LOGFILE=
        log4j.appender.LOGFILE.File=
        log4j.appender.LOGFILE.MaxFileSize=
        log4j.appender.LOGFILE.layout=
        log4j.appender.LOGFILE.layout.ConversionPattern=
        
        Let us see how to use log4j.properties file
        Files Required
        MyLog4J.java
        log4J.properties
        myLog.log [We will let the appender to write into this file]

        MyLog4J.java
        package com.ashok.mylog4j;
        import org.apache.log4j.Logger;
        public class MyLog4J {
           static Logger log = Logger.getLogger(MyLog4J.class.getName());
           public static void main(String[] args) {
              log.debug("This is debug message");
              log.info("This is info message");
              log.warn("This is warn message");
              log.fatal("This is fatal message");
              log.error("This is error message");
              System.out.println("Your logic executed successfully....");
           }
        }
        

        log4j.properties
        log4j.rootLogger = DEBUG
        log4j.appender.DEBUG= org.apache.log4j.FileAppender
        log4j.appender.DEBUG.file = myLog.log
        log4j.appender.DEBUG.layout = org.apache.log4j.SimpleLayout

        Once we run this MyLog4J program, myLog.log will contains….

        myLog.log
        DEBUG – This is debug message
        INFO – This is info message
        WARN – This is warn message
        FATAL – This is fatal message
        ERROR – This is error message

        Execution Flow
        Run MyLog4J.java
            Log4j environment created, at line number 4. As our default properties file name is log4j.properties, we no need to import properties file explicitly into MyLog4J.java, by default our java class will verify for the properties file named log4j.properties. If we give the name other than log4j to the properties we have to import manually into our java class [will see this later, like how to manually] So once Logger object created at line number 4, our class will be able to know about the content in log4j.properties. In log4j.properties the content always will be in key, value pairs only

        Explanation
        * If we use .properties file, we no need to import any related classes into our java class.

        * log4j.rootLogger = DEBUG Here DEBUG means we are specifying the level from where log4j methods execution must start, see myLog.log file it showing all messages right. But if we wrote log4j.rootLogger = WARN then it will prints the messages in log.warn(), log.error(), log.fatal() and ignores log.debug(), log.info()

        * We have used FileAppender as my Appender, so if we want to change my appender to ConsoleAppender, we will open log4j.properties file and do the modifications, so no need to touch our java classes, this is the main advantage of .properties file.

        * So just change layout into HTMLLayout and check the output

        Log4j Example on Using FileAppender and ConsoleAppender Simultaneously
                 Let us see how to use FileAppender and ConsoleAppender at a time.
        Files Required
        MyLog4J.java
        log4j.properties
        myLog.log [We will let the appender to write into this file]

        MyLog4J.java
        package com.ashok.mylog4j;
        
        import org.apache.log4j.Logger;
        public class MyLog4J {
           static Logger log = Logger.getLogger(MyLog4J2.class.getName());
           public static void main(String[] args) {
              log.debug("This is debug message");
              log.info("This is info message");
              log.warn("This is warn message");
              log.fatal("This is fatal message");
              log.error("This is error message");
              System.out.println("Your logic executed successfully....");
           }
        }

        log4j.properties
        log4j.rootLogger=DEBUG,CONSOLE,LOGFILE
        log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
        log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
        log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x \u2013 %m%n
        log4j.appender.LOGFILE=org.apache.log4j.RollingFileAppender
        log4j.appender.LOGFILE.File=myLog.log
        log4j.appender.LOGFILE.MaxFileSize=1kb
        log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
        log4j.appender.LOGFILE.layout.ConversionPattern=[%t] %-5p %c %d{dd/MM/yyyy HH:mm:ss} \u2013 %m%n
        

        myLog.log
        [main] DEBUG MyLog4J 27/02/2012 21:39:15 – This is debug message
        [main] INFO MyLog4J 27/02/2012 21:39:15 – This is info message
        [main] WARN MyLog4J 27/02/2012 21:39:15 – This is warn message
        [main] FATAL MyLog4J 27/02/2012 21:39:15 – This is fatal message
        [main] ERROR MyLog4J 27/02/2012 21:39:15 – This is error message
        

             That's it guys. This is all about Log4j Tutorial. Let me know your comments and suggestions about this tutorial. Thank you.

        2 comments: