The difference between log4j and JDK logger

Source: Internet
Author: User
Tags print format log4j

Http://www.blogjava.net/kapok/archive/2005/07/10/7465.html

In programming, it is often unavoidable to use some log operations, such as the development phase of debugging information, Run-time logging and auditing. The survey showed that the log code accounted for 4% of the total code. Usually you can simply use the SYSTEM.OUT.PRINTLN () statement to output log information, but there are often some judgments, such as:

if (somecondition) {
SYSTEM.OUT.PRINTLN ("some information.");
}

These judgments result in a large number of output statements mixed in the normal program logic. These judgments written in the development phase are only for debugging statements and need to be found and removed when development is complete. After the deployment, especially in some enterprise application systems, and often need further debugging, this time encountered greater trouble. So, we need a complete, flexible, configurable logging tool. Log4j is an excellent choice.
Log4j is a subproject of the Apache Software Foundation Jakarta Project, a good log toolkit written in Java. By log4j, you can easily and flexibly control the opening or closing of any granularity of log information without modifying the code, and then use the custom format to output the log information to one or more places that you need. And, log4j also has a smooth learning curve, in three minutes to learn its simple use. As you go deeper, you will find that the log4j function is powerful enough to meet all the requirements of the log.
Quick Start
Look at a piece of code first and see how easy log4j is, and the code is as follows:

Package org.javaresearch.log4j;

Import org.apache.log4j.*;

public class Testlog4j {
static Logger log = Logger.getlogger (TestLog4J.class.getName ());

public static void Main (String args[]) {
Basicconfigurator.configure ();
The various methods of logging
Log.debug ("Start of Main ()");
Log.info ("Just Testing a log message with the priority set to info");
Log.warn ("Just Testing a log message with priority set to warn");
Log.error ("Just Testing a log message with the priority set to Error");
Log.fatal ("Just Testing a log message with priority set to fatal");
Another inconvenient format
Log.log (Priority.debug, "Testing a log message use a alternate form");
Log.debug ("End of Main ().");
}
}

Save this code in a directory, compile and run (note that you want to include Log4j-1.2.7.jar in the Classpath), and the program output is as follows:

0 [main] DEBUG Testlog4j-start of Main ()
Ten [main] INFO Testlog4j-just testing a log message with priority set to info
[main] WARN Testlog4j-just testing a log message with priority set to WARN
[main] ERROR Testlog4j-just testing a log message with priority set to error
[main] FATAL Testlog4j-just testing a log message with priority set to FATAL
[main] DEBUG testlog4j-testing a log message use a alternate form
[main] DEBUG testlog4j-end of Main ().

First, explain the meaning of the output above. The first number is the number of milliseconds that a program starts running to run the log statement (it's good to do a little running-efficiency analysis), "[main] is the thread where the log event occurs, and subsequent" DEBUG "," info "and other information are the priority of the corresponding log information," TESTLOG4 " is the instance name of the current logger, and the last is the log information.
In this program, the log4j is initialized with a basic configuration class Basicconfigurator provided by log4j. But it's not usually done when it's actually used, because it's a bit of a "hard" code. In the future, if you want to modify the configuration of the log4j, you need to modify, recompile code, which is usually not what everyone wants. Typically, we provide a file called Log4j.properties, which, when first invoked to log4j, log4j locates the file in the Classpath and reads the configuration that the file completes. This configuration file tells log4j what format, what kind of information, and where to go. Let's look at a simple example of a log4j.properties configuration file with the following code:

Log4j.rootlogger=debug, A1
Log4j.appender.a1=org.apache.log4j.consoleappender
Log4j.appender.a1.layout=org.apache.log4j.patternlayout
Log4j.appender.a1.layout.conversionpattern=%-4r [%t]%-5p%c%x-%m%n

Store the above content as log4j.properties and place it in the same directory as Testlog4j.class (or, of course, any other directory, as long as the directory is included in the Classpath). The meaning of each line in each of these configuration files is detailed in later chapters and can now be skipped. Now you can comment out the "Basicconfigurator" in the above program. Configure (); " statement, and then use the Log4j.properties property file to complete the log4j configuration, recompile, run, and get the same result as above.
What is the benefit of doing so? Now on the initial taste of some log4j flexible, powerful features. For example, the system to go online, want to output some warnings and error messages, then only need to modify the Log4j.properties file in the "Log4j.rootcategory=debug, A1" can, and then set the log output of the lowest level is warn, set to " Log4j.root Category=warn, A1 ". There is no need to modify any code at this time, the system is rerun, and the output becomes:

[main] WARN Testlog4j-just testing a log message with priority set to WARN
[main] ERROR Testlog4j-just testing a log message with priority set to error
[main] FATAL Testlog4j-just testing a log message with priority set to FATAL

Principle Analysis
The log4j has three main components, which are loggers (loggers), output sources (appenders), and layouts (logouts). The logger writes log information to one or more output sources according to the format specified in the layout. The output source can be a console, a text file, an XML file, or a socket, and even write information to the Windows event log or emailed, which requires the appropriate classes to handle, the related classes are Consoleappender, Fileappender, Socketappender, Nteventlogappender and Jmsappender.
Recorder (Logger)
First let's look at the logger class, the code is as follows:

Package org.apache.log4j;

public class Logger {
Create and Restore methods
public static Logger Getrootlogger ();
public static Logger GetLogger (String name);
public static Logger GetLogger (Class clazz);
Printing method
public void Debug (Object message);
public void info (Object message);
public void warn (Object message);
public void error (Object message);
public void fatal (Object message);
Common printing methods
public void log (level L, Object message);
}

From this code you can see the basic use of logger. First you need to get a logger object that gets the statement of the Logger object:

Logger Logger = Logger.getlogger (JavaLoggingExample.class.getName ());

With this logger object, you can easily output log information where you need it. For this information is output, output format, etc., can be easily configured through the configuration file, without the need to modify the code, which is log4j bring convenience.
The hierarchy of the logger
A logger instance is obtained when using the log4j Logger.getlogger () method. If you have thousands of classes in an application, you will need almost thousands of logger instances. How to conveniently configure these thousands of logger instances is a very important issue. LOG4J uses a tree-like hierarchy of inheritance to solve this problem skillfully. In log4j, logger is hierarchical. It has a common root, at the top, and other logger follow a similar level of package, such as:

static Logger root = Logger.getrootlogger ();
static Logger Log1 = Logger.getlogger ("org");
static Logger log2 = Logger.getlogger ("Org.javaresearch");
static Logger Log3 = Logger.getlogger ("Org.javaresearch.log4j.TestLog4J");

In the code above, Log1 is the father of Log2, the ancestor of Log3, and Root is the ancestor of all Log1, log2, and Log3, all of which inherit from Root. Therefore, in general, you only need to configure the Rootlogger, and the other child loggers will inherit the Rootlogger configuration from it. If you modify the configuration of the Rootlogger, all other child loggers will inherit this change as well. This makes it much easier to configure. Now looking back at the configuration file in QuickStart, we can control all logger behavior by configuring Rootlogger only.
Levels (Level)
One of the core concepts in log4j is that the logging level is orderly. LOG4J has 5 log levels built into the following categories:

DEBUG < INFO < WARN < ERROR < FATAL

The level on the right is higher than the left. Each logger instance has a log level, and the above 5 output methods correspond to 5 different levels of log requests. For example, if C is a logger instance, C.info ("Some information") is an info-level log request. Whether a log request will be output depends on the log level of the logger instance and the comparison of the log request level. The rules are as follows:
If a log request with a level Q occurs in a logger instance with a level of p, then the request will be enabled when Q >= p.

Let's take a look at the example 2 code as follows:

Get a logger instance "Com.foo"
Logger Logger = Logger.getlogger ("Com.foo")
Now set the level of logger, but the normal situation is not to deliberately set the lgger level, because it has been completed in the configuration file
Logger.setlevel (Level.info);
Logger Barlogger = Logger.getlogger ("Com.foo.Bar");
Because WARN >= INFO, this request is achievable.
Logger.warn ("Low fuel level.");
This request is not possible because of debug < INFO
Logger.debug ("Starting search for nearest gas station.");
The logger instance "Com.foo.Bar" inherits the level from "Com.foo", so that because info >=
INFO, so you can implement the following request
Barlogger.info ("located nearest gas station.");
This request is not possible because of debug < INFO
Barlogger.debug ("Exiting gas station search");


Layout (Layout)
LOG4J uses a print format similar to the printf function in c to format the log information, which is shown in table 1 below:
%M the message specified in the output code
%p output priority, i.e. Debug,info,warn,error,fatal
%r output the number of milliseconds it takes to boot to output the log information
The class to which the%c output belongs, usually the full name of the class in which it is located
%t output The name of the thread that generated the log event
%n output a carriage return line break, the Windows platform is "/r/n", and the UNIX platform is "/n"
%d output log point-in-time date or time, the default format is ISO8601, you can also specify the format after, such as:%d{yyy MMM dd hh:mm:ss,sss}, output similar: October 18, 2002 22:10:28,921
%l the location where the output log event occurs, including the class name, the thread that occurred, and the number of lines in the code. Example: Testlog4.main (testlog4.java:10)
Basic Application
Configuration of log4j
Now look at the meaning of the log4j.properties configuration file. The first line specifies that the level of the root logger is debug and outputs the specified to A1. The A1 is the Org.apache.log4j.ConsoleAppender defined in the second row, which indicates that the A1 is exported to the console. The third line stipulates that the output to the A1 format is org.apache.log4j.PatternLayout. The four lines specify that the conversion mode of output to A1 format is Org.javaresearch.log4j.TestLog4J.
Many mature server classes of software log information will be exported to the console, while output to log files for reference. With log4j, you can easily do this by modifying the configuration file without changing any code. The related configuration files are as follows:

# use two appenders, one to log to console, another to log to a file
Log4j.rootcategory=debug, stdout, R

# Print only messages of priority WARN or higher for your category
Log4j.category.your.category.name=warn

# Appender writes to console
Log4j.appender.stdout=org.apache.log4j.consoleappender
Log4j.appender.stdout.layout=org.apache.log4j.patternlayout

# to output the caller ' s file name and line number.
log4j.appender.stdout.layout.conversionpattern=%5p [%t] (%f:%l)-%m%n

# Second Appender writes to a file
Log4j.appender.r=org.apache.log4j.rollingfileappender
Log4j.appender.r.file=example.log

# Control the maximum log file size
log4j.appender.r.maxfilesize=100kb
# Archive log files (one backup file here)
Log4j.appender.r.maxbackupindex=1

Log4j.appender.r.layout=org.apache.log4j.patternlayout
log4j.appender.r.layout.conversionpattern=%p%t%c-%m%n

This configuration file specifies two output sources stdout and R. The former output log information to the console, the latter is a rotary log file. The largest file is 100KB, when a log file reaches the maximum size, log4j will automatically rename Example.log to Example.log.1, and then rebuild a new Example.log file, turn the rotation.
Using in Web applications
Where should the log4j be configured in a Web application? First, make it clear that log4j must complete initialization before other code that is applied is executed. Because the servlet is mounted immediately when the Web server is started, a dedicated servlet is typically used in Web applications to complete the log4j configuration, and the servlet is guaranteed to be in the Web.xml configuration before the other servlet. Here is an example of the following code:

Package org.javaresearch.log4j;

Import java.io.*;
Import javax.servlet.*;
Import org.apache.log4j.*;

public class Log4jinit extends HttpServlet {
public void Init () throws Servletexception {
String prefix = Getservletcontext (). Getrealpath ("/");
String file = Getservletconfig (). Getinitparameter ("Log4j-config-file");
Reading log4j configuration files from the servlet parameter
if (file!= null) {
Propertyconfigurator.configure (prefix + file);
}
}
public void doget (httpservletrequest request,httpservletresponse response)
Throws IOException, Servletexception {}
public void DoPost (httpservletrequest request,httpservletresponse response)
Throws IOException, Servletexception {}
}

<servlet>
<servlet-name>log4jinit</servlet-name>
<servlet-class>org.javaresearch.log4j.Log4JInit</servlet-class>
<init-param>
<param-name>log4j-config-file </param-name>
<param-value>/properties/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

Note: The above load-on-startup should be set to 1 so that the servlet is loaded when the Web container is started. The log4j.properties file is placed in the properties subdirectory of the root, or it can be placed in a different directory. The. properties file should be stored centrally so that it is easy to manage.
Top Topics
Performance
When logging some log information, it will affect the efficiency of the system to a certain extent, the efficiency of the log tool is a key. LOG4J's primary design goal is to be efficient, and some key components have been rewritten many times to continuously improve performance. According to the report of the LOG4J project team, in an AMD Duron 800MHz + JDK1.3.1 environment, it takes only 5 nanoseconds for the log4j to determine whether a log statement requires output. The actual log statement is also very fast, ranging from using Simplelayout 21 microseconds (almost as fast as SYSTEM.OUT.PRINTLN) to 37 microseconds using Ttcclayout.
Nested Diagnostic Environment NDC
In a multiuser concurrency environment, it is common for different threads to handle different client requests separately. To separate clients in the Log Information section, you can mechanical engineer each line into a logger that distinguishes which threads from a pile of log information, but this is not efficient. Log4j cleverly used the "NDC (nested diagnostic environment)" mechanism proposed by Neil Harrison to solve this problem. Log4j for the same category of lines mechanical engineer into a logger that multiple threads share, and it only adds information in the log information that can differentiate between threads. What NDC is. For example, if a servlet receives concurrent requests, create a new thread for each client, and then assign a NDC stack to hold the request context. The context might be the host name that made the request, the IP address, or any other information that could be used to identify the request. Thus, because different client processing threads have different NDC stacks, even if the servlet generates multiple threads to handle different requests at the same time, the log information can be distinguished, as if log4j for each line Cheng Tu generates a separate Logger

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.