Use an efficient log tool -log4j

xiaoxiao2021-03-06  48

Everyone is often inevitably to use some log operations, such as debugging information, runtime logging and auditing. The survey shows that the log code accounts for 4% of the total code. Usually everyone can simply use the system.out.println () statement to output log information, but there will be some judgment, such as:

IF (somecondition) {

System.out.println ("Some Information.");

}

These judgments have caused a large number of output statements in normal program logic. These judgments written under the development phase are only for debug statements, and they need to find and remove when development is completed. After deployment, especially in some enterprise applications, further debugging is often required, and even more troublesome. So, we need a complete set of flexible, configurable log tools. Log4j is an excellent choice. Log4j is a subproject under the Apache Software Foundation Jakarta project, which is an excellent log kit written in Java. By the log4j, it is convenient, flexible, and flexibly controls the opening or closing of the log information of any particle size, and then outputs the log information to one or more required places where the custom format is used. Also, log4j has a smooth learning curve that can learn its simple use within three minutes. With in-depth use, you will find that the Log4J function is powerful, almost all of the needs of the log.

Get started

First look at a code, see how easy to get the log4j, 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 ();

// Logging various methods

Cat.debug ("START of Main ()");

Cat.info ("Just Testing A Log Message with Priority Set to Info");

Cat.Warn ("Just Testing A Log Message with Priority Set To Warn");

Cat. Error ("Just Testing A Log Message with Prior Set to Error");

Cat.fatal ("Just Testing A Log Message with Priority Set To Fatal";

// Another inconvenient format

Cat.log (Priority.debug, "Testing a log message") and a alternate form

"" End of main (). ");

}

}

Save this code in a directory, compile operation (Note To put the log4j-1.2.7.jar into the path), the program output is as follows:

0 [main] debug testlog4j - start of main ()

10 [main] info testlog4j - Just Testing a log message with priority set to info

20 [main] WARN TESTLOG4J - JUST TESTING A LOG Message with priority set to warf4j - just testing a log message with prior set to error

30 [main] Fatal Testlog4j - Just Testing a log message with priority set to fatal

40 [Main] Debug Testlog4j - Testing a log message USE A Alternate Form

50 [main] debug testlog4j - end of main ().

First explain the significance of the output results above. The first number refers to the number of milliseconds experienced by the program to run to the log statement (to do a little running efficiency analysis is also good), "[main]" is a thread that occurred in the log event, and then "debug", " INFO "and other information is the priority of the corresponding log information," Testlog4 "is the instance name of the current Logger, and finally the log information. In this program, a basic configuration class BasicConfigurator provided by log4j is used to initialize Log4j. But don't do this when practical use, because this is a bit "hard" encoding. In the future, if you want to modify the log4j configuration, you need to modify, recompile the code, which is usually not hoped. Typically, we all provide a file called log4j.properties. When you call to log4j for the first time, Log4j will locate this file in the class path and read this file. This profile tells the log4j to do what kind of information, what kind of information, and where it is output. Let's take a look at an example of a simple log4j.properties profile, the code is as follows:

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 put it in the same directory with TestLog4j.class (of course, you can also put any other directory as long as the directory is included in the classpath). The meaning of each line in these configuration files, in the next chapter, there will be detailed descriptions, and now you can skip. Now you can comment out the "BasicConfigurator. Configure ();" statement in the above program, then use the log4j.properties attribute file to complete the log4j configuration, recompile, run, and get the same result as above. What is the benefit of this? Now I will prestimate some of the flexible and powerful functions of log4j. For example, the system is going online, wants to output some warnings and error messages, then only need to modify "log4j.rootcategory = debug, A1" in the log4j.properties file, and then set the lowest level of the log output is WARN, set to " Log4j.Root category = warn, a1 ". At this point, you don't need to modify any code, re-run the system, and the output is turned:

20 [main] WARN TESTLOG4J - JUST TESTING A LOG Message with priority set to warf4j - just testing a log message with prior set to error

30 [main] Fatal Testlog4j - Just Testing a log message with priority set to fatal

Principle analysis

Log4j has three major components that are loggers, an output source (Appenders) and Logouts. The logger writes the log information into one or more output sources according to the format specified in the layout. Output source can be a console, text file, XML file, or socket, or even write information to a Windows event log or send it via email, which requires the corresponding class to handle, these related classes are consolerappender, FileAppender, SocketAppender, NTEVENTLOGAPPENDER and JMSAPPENDER. The logger first let us see the logger class, the code is as follows:

Package org.apache.log4j;

Public class logger {

// Creating and recovering methods

Public static logger getrootlogger ();

Public Static Logger getLogger (String name);

Public Static Logger getLogger (Class Clazz);

// Print 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 print method

Public void log (level L, Object Message);

}

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

Logger logger = logger.getlogger (javaloggingexample.class.getname ());

With this Logger object, you can easily output log information in the needs. For these information, the format, the output, etc., can be easily configured by the configuration file without modifying the code, which is the convenience of log4j. The hierarchy of the recorder uses log4j's Logger.getLogger () method to get an instance of a Logger. If you contain thousands of classes in an app, then you can also need a thousand Logger instances. How to easily configure this thousand Logger instance is a very important issue. Log4j uses a tree inheritance level to solve this problem. Logger is a hierarchical relationship in log4j. It has a common root, located in the uppermost layer, other logger follows the hierarchy of similar packets, 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 above code, log1 is the father of log2, is the ancestors of log3, and root is all the ancestors of LOG1, LOG2, LOG3, which are inherited from root. Therefore, in general, only the rootlogger needs to be configured, and other subcrans will inherit the rootlogger configuration. If you modify the configuration of the rootlogger, all other subcunauts also inherit this change. This greatly facilitates the configuration. Now look back at the configuration file in "Quick Start", we only configure the rootlogger, you can control all Logger's behavior. One core concept in Level Log4j is the log level is in an orderly. Log4j has built-in 5 log levels:

Debug

The level on the right is higher than the left. Each Logger instance has a log level. The above five output methods are corresponding to five different levels of log requests. For example, if c is a logger instance, C.info ("Some Information) is an INFO level log request. A log request will not be output, depending 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 of a level Q is occurred in a Logger instance of the P level, the request is enabled when Q> = P. Let's first see example 2 code as follows:

// Get a Logger instance "com.foo"

Logger logger = logger.getlogger ("com.foo")

// Now set the Logger level, but normal situation is not necessary 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.");

// Because Debug

Logger.debug ("Starting Search for NEAREST GAS Station);

// Logger instance "com.foo.bar" will inherit the level from "com.foo", so because INFO> =

INFO, so you can implement the following request

Barlogger.info ("Located Nearest Gas Station);

// Because Debug

Barlogger.debug ("EXITING GAS STATION SECH");

Layout log4j formatted log information in a printing format of the Printf function in the C language, and the print parameters are shown in Table 1 as follows:

The message% P output priority specified in the% M output code, namely Debug, INFO, WARN, ERROR, FATAL% R Output self-application start to output the LOG information consuming millisecond% C output belongs, usually The full name% T output of the class is generated to generate the log event, the Windows platform is "/ r / n", the Unix platform is "/ n"% D output log time point or time The default format is ISO8601, or it can be specified in the format, such as:% D {YYY MMM DD HH: MM: SS, SSS}, Output: October 18, 2002 22: 10: 28, 921% l Output The occurrence position of the log event, including the category name, the thread that occurs, and the number of rows in the code. Example: Testlog4.main (Testlog4.java:10) Log4j's Configuration Now look at the meaning of the log4j.properties configuration file. The first line specifies the level of the root Logger is Debug and outputs this specified to A1. A1 is the second line defined org.apache.log4j.consoleAppender, which indicates that the A1 is output to the console. The third line specifies the format of the output to the A1 to org.apache.log4j.patternlayout. The fourth line specifies the conversion mode output to the A1 format to org.javaresearch.log4j.testlog4j. Many mature server class software log information will be output to the console while outputting to log file check. This feature can be easily accomplished by modifying the profile without changing any code without changing any code. The relevant 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

#### First appender Writes To Console

Log4j.appender.stdout = org.apache.log4j.consoleAppender

Log4j.Appender.stdout.Layout = Org.apache.log4j.patternlayout

# Pattern 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 profile specifies two output sources Stdout and R. The former outputs the log information to the console, and the latter is a rotation log file. The biggest 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 and rotate sequentially. In web applications, where should I configure the log4j? First of all, the log4j must complete the initialization before performing other code executions. Because servlet is immediately loaded immediately, in a web application, a special Servlet is usually used to complete the log4j configuration and ensure that this servlet is in other servlets in the Web.xml configuration. Here is an example, the code is as follows:

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");

/ / Read the log4j profile 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 {}

}

log4jinit

org.javaresearch. log4j.log4jinit

Log4j-config-file

/properties/log4j.properties

1

Note: The above Load-on-Startup should be set to 1 to load the servlet when the web container is started. Log4j.properties files are placed in the rorties subdirectory of the root or in other directories. It should be stored in the .properties file, so convenient management.

Advanced topic

Performance When recording some log information, it will certainly affect the operating efficiency of the system, and if the log tool is efficient, it is a key. Log4j's primary design goals are efficient, and some key components have renovated many times to continuously improve performance. According to the report of the log4j project team, in the environment of AMD DURON 800MHz JDK1.3.1, log4j judges whether a log statement needs to output only 5 nanoseconds. The actual log statement is also very fast, from 21 microseconds using SimpleLayout (almost as fast as System.out.println), 37 microseconds using TTCCLAYOUT. Nested Diagnostic Environment NDC is usually different from different client requests by different threads in a multi-user concurrent environment. At this point, you should have different clients in the log information, you can generate a logger for each thread, thus distinguishing which information is part of the information, but this method is not efficient. Log4J has cleverly uses the "NDC (Nest Diagnostic Environment) mechanism proposed by Neil Harrison to solve this problem. Log4j generates a logger for the same category, multiple thread sharing, and it adds information that can distinguish between different threads only in log information. What is NDC? For example, if a servlet receives a concurrent request, create a new thread for each client and assign a NDC stack for saving the request context. This context may be a request for host name, an IP address, or any other information that can be used to identify the request. Thus, since different client processing threads have different NDC stacks, even if this servlet generates multiple thread processing different requests, these log information can still distinguish, as if log4j generates a logger instance for each thread. same. This mechanism is achieved through org.apache.log4j.ndc in log4j. The method of using NDC is also very simple, the steps are as follows: 1. Call ndc.push (string) when entering an environment, then create an NDC; 2. The log operation output includes NDC information; 3. Leaving The NDC.POP method is called when the environment is called; 4. Call the NDC.Remove method when exiting from a thread to release resources. Here is an example of analog records from different client requesting events, the code is as follows: import org.apache.log4j.logger;

Import org.apache.log4j.ndc;

Public class testndc {

Static logger log = logger.getlogger (testndc.class.getname ());

Public static void main (String [] args) {

LOG.INFO ("Make Sure% X IS in Your Layout Pattern!");

/ / An example of obtaining an IP address from the client

String [] IPS = {"192.168.0.10", "192.168.0.27"};

For (int i = 0; i

{

// put the IP in NDC

NDC.PUSH (IPS [I]);

Log.info ("A New Client Connected, WHO'S IP Should APPEAR in this log message.");

NDC.POP ();

}

Ndc.remove ();

Log.info ("Finished.");

}

}

Note that you must add% x in the layout format in the configuration file. The system output is as follows: info - make Sure% x is in your layout pattern!

Info 192.168.0.10 - a New Client Connected, WHO's IP SHOULD APPEAR in this log

Message.

INFO 192.168.0.27 - a New Client Connected, WHO's IP SHOULD APPEAR in this log

Message.

INFO - Finished.

Use log4j or JDK Logging API from JDK 1.4.0, introduced a java.util.logging package. Although the Log4j team worked as a "Java Community Process) using Log4J as a" standard "log API of JDK 1.4, although the final stage of Merlin's development has reached the final stage due to Sun's log API specification," Merlin's development has reached the final stage, The main API is not allowed to make changes to the main API, but log4j has an important impact on new log APIs. So, should we use LOG4J or a java.util.logging package? The following is only a simple comparison to both. 1. LOG4J is more mature, from October 1999, has been 3 years since October 1999, and has been mature in many projects. The Logging package in JDK is introduced after 1.4 and cannot run in the JDK 1.3. Log4j can be well running all versions after JDK 1.1. 2. LOG4J has been ported to a variety of environments, including LOG4C (C), LOG4CPP (C ), Log4Perl (Perl), Log4Net (.NET), etc. In these environments, you can feel almost consistent configurations and ways. This is the Logging API in the JDK can't match. 3. LOG4J also has a more powerful format system that enables a simple mode when the record is output. However, it does not increase the class and leads to the expansion of the formatting tool. Numerous additional procedures and processors make the log4j packets into a great choice, all you need can be implemented. 4. Log4j has made the greatest optimization in performance. Logging API is sufficient for simple use, but it lacks a number of log4js. So, if you need a powerful logging mechanism, you should use the log4j; if you just need some simple control or file log, you can use the Logging API already built in JDK. Although log4j and JDK Logging APIs are a competitive relationship, when the Logging API is also discussed in JCP (JSR47), the two have begun to affect each other. FAQ 1. How to make log4j implant the system properties when you start your application using the specified profile. For example, you can put the above log4j.properties file in the relative path of / Properties, and renamed Log.properties, if log4j can find this configuration file and initialize properly, you need this program:

D: /../ java -dlog4j.configuration =. /Properties/log.properties YourAppname

Why do you have to use the system properties, not specified in the configuration file? Obviously, if it writes it to the configuration file, the log4j is late when it is read. 2. How to check that the configuration process of the log4j can be similar to 1, set the system properties log4j.debug = true, thereby opening the log4j's Verbose mode, which outputs the LOG4J initialization process, which will have a startup of log4j More detailed understanding. Below is an example of log4J startup information: log4j: trying to find [log4j.xml] Using Context ClassLoader

Sun.misc.launcher $AppClassLoader@92e78c.

Log4j: Trying to find [log4j.xml] Using sun.misc.launcher $ExtClassLoader@9fbe93class

Loader.

Log4J: Trying to find [log4j.xml] using classloader.getsystemResource ().

Log4j: Trying to find [log4j.properties] Using Context ClassLoader

Sun.misc.launcher $AppClassLoader@92e78c.

Log4j: using url [file: / d: /java/logging/src/log4j.properties] for automatic log4j

CONFIGURATION.

Log4J: Reading Configuration from Url file: / e: /java/logging/src/log4j.properties

Log4j: Parsing for [root] with value = [debug, a1].

Log4j: Level token is [debug].

Log4j: category root set to debug

Log4j: Parsing appender named "a1".

Log4J: Parsing Layout Options for "A1".

Log4j: setting property [conversionPattern] To [% D% L%-5P% C [% T] -% m% n].

Log4j: End of paarsing for "a1".

Log4j: parse "a1" options.

Log4j: finished configuring.

... // The following is the application log information, omitted.

转载请注明原文地址:https://www.9cbs.com/read-70748.html

New Post(0)