log4jthree main components
Loggers: A tool for logging logs, which is used to record the log information we want.
Appenders (output source): Where the log output can be, console, file, stream location, database, and so on.
Layouts (layout mode): The log needs to record which basic information, in what format to record the display of this information.
A Logger must have at least one Appender, and a Appender has a Layout.
Loggers
The logger is an instance object of the Logger class in log4j, and here are some of the main methods defined in the class, which are often used in programs:
Packageorg.apache.log4j; Public classLogger {//Creation & Retrieval methods: Public StaticLogger Getrootlogger (); Public StaticLogger GetLogger (String name); //Printing methods: Public voidTrace (Object message); Public voidDebug (Object message); Public voidinfo (Object message); Public voidwarn (Object message); Public voiderror (Object message); Public voidFatal (Object message); //Generic Printing method: Public voidlog (level L, Object message);}
It is also very simple to use in a program, which is to get a logger instance and then call different methods to get different types of log information:
Public classMain {//get the Rootlogger method Public StaticLogger Rootlogger =Logger.getrootlogger (); //Get the Custom logger method Public StaticLogger Logger = Logger.getlogger (Main.class); Public Static voidMain (string[] args) {Logger.debug ("Debug Log");//log information for a debug levelLogger.log (level.debug, "DEBUG log");//Another way of writing//Trace Info warn error fatal is a similar usage }}
It can be said that the only thing we do with log4j in the program is to tell log4j what kind of log I want to record and what log information I want to log.
As for other things: What are these log messages recorded as? Where was it sent to? You need to define the configuration in advance, you can encode the definition in the Java source file, or you can configure it in the Log4j.properties file. The most common is the configuration file, here just say log4j.properties configuration.
The following is the most basic log4j.properties file that can be worked on, which outputs the log information to the standard output (console). Based on this example, the following parsing is carried out:
# Rootloggerlog4j.rootlogger=debug, stdout# stdout Appenderlog4j.appender.stdout=org.apache.log4j.consoleappender
# stdout Appender layoutlog4j.appender.stdout.layout= org.apache.log4j.patternlayoutlog4j.appender.stdout.layout.conversionpattern=%-4r [%t]%-5p%c%x-%m%n
Log4j is a configuration prefix, each line of valid configuration can not be less, marking this is a configuration belonging to log4j:
Rootlogger represents the root Logger recorder, which is also a direct or indirect ancestor of all other loggers, the equivalent of Java.lang.Object in the Java class, the basic configuration format:
Log4j.rootlogger = [level], appenderName1, appenderName2, ...
[level] is defined by the log levels, that is, the level at which the Logger should start logging, the log itself from high to low total eight levels: OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, all, which are defined in the The Org.apache.log4j.Level class. When the log level is defined, the Logger records only log information that is above or equal to that level, and log information below that level is not logged. There are four log levels commonly used: ERROR, WARN, INFO, DEBUG.
AppenderName1, AppenderName2, ... Refers to the name of the appenders (output source).
The phrase "log4j.rootlogger=debug, stdout" means "root Logger records the log on the DEBUG level (including) and outputs those logs to the STDOUT output source."
appenders
In log4j, the output source type is the implementation class of the "Org.apache.log4j.Appender" interface, and the format for defining a Appender (output source) is:
Log4j.appender.appendername=classname
Appendername is Appender's nickname, custom, can be arbitrarily taken, Logger refers to this name. In the example above, the output source name is stdout.
ClassName is Appender's full path class name, LOG4J has defined a number of Appender types and lists several commonly used Appender types:
Org.apache.log4j.ConsoleAppender (standard output, console) Org.apache.log4j.FileAppender (file) org.apache.log4j.DailyRollingFileAppender (file, per Days a) Org.apache.log4j.RollingFileAppender (file, another file beyond the maximum capacity limit) Org.apache.log4j.WriterAppender (send log information in stream format to the specified place)
In the above example, the "Org.apache.log4j.ConsoleAppender" output source is used.
So far, the definition of the root Logger can collect logs, defining the Appender can store the collected logs to the specified place, but the same is the format of the log, that is, the definition of layout layouts.
Make a metaphor:
Is that I grabbed a perch from the river (log), take home (output source), Cook (layout mode), the key is what to cook?
Braised fish? Steamed fish? Boiled fish? Hot and sour fish? (Different layout modes)
Do you use this clean fish to make the original? Or is it more palatable to add some other seasoning? (more specific format in layout mode)
Layouts
In log4j, the Layout type is a subclass of the "Org.apache.log4j.Layout" abstract class
Layout mode layouts are a property used to match the output source Appender, which means that each output source must match a layout pattern to make a complete "dish".
Layout configuration format:
Log4j.appender.appendername.layout=classname
Appendername is the name of Appender, corresponding to an already defined Appender.
ClassName is the full path class name for layout, similarly, in log4j, a lot of layout types are defined, commonly used are:
Org.apache.log4j.HTMLLayout (HTML table layout) Org.apache.log4j.PatternLayout (similar to regular, formatted output, very flexible, most commonly used layout mode) org.apache.log4j.SimpleLayou T (simple layout with log level and log information string only) Org.apache.log4j.TTCCLayout (this layout contains content such as thread generation, log level, generation class, log information string, etc.)
Example is used in the Patternlayout layout mode, the actual project of the layout is also used frequently, so focus on the use of the layout mode, other layout principle similar, use can refer to log4j source code and API.
Patternlayout is only a layout mode, defining the use of patternlayout is like saying that I decided to make the bass into a "braised fish", but the braised fish can also have different "color fragrance" Ah. Therefore, you need to further specify the format of the log in this layout mode, configured as follows:
Log4j.appender.appendername.layout.conversionpattern=format
The Appendername:appender name, corresponding to a defined Appender.
Conversionpattern=format: is the specific format in patternlayout layout mode. Format can be selected as:
%p: Log priority, or debug,info,warn,error,fatal. %d: the date or time the log was generated, the default format is ISO8601, or the format can be specified later, such as:%d{yyyy/mm/dd hh:mm:ss,sss}. %r: The number of milliseconds that the log information has been consumed since the application started to output. %t: The name of the thread that generated the log. %l: The location of the output log event, equivalent to the%c.%m (%f:%l) combination, including the full path class name, method, file name, and number of rows in the code. For example: Test. Testlog4j.main (testlog4j.java:10). %c: The log information belongs to the class, which is usually the full path name of the class. %M: The method name that generates the log information. %F: The name of the file that generated the log. %L:: Generates the line number of the log in the code. %m:: The specific log information string that is customized in the code. %n: Outputs a carriage return newline character, the Windows platform is "RN", and the UNIX platform is "n". %x: The output is associated with the current line threads NDC (nested diagnostic environment), which is used in multi-client multithreaded applications like Java servlet. Percent: Outputs a "%" character. You can also specify text length and alignment between% and format characters:%20m: Text takes up to 20 characters and is right-aligned by default. %-20m: Text is 20 characters minimum, left justified. %.20m: The text is up to 20 characters long, and the partial character is truncated from the left.
Here, we can completely define the Log4j.properties configuration file (which is written again) as an example above.
# Rootloggerlog4j.rootlogger=debug, stdout# stdout Appenderlog4j.appender.stdout=org.apache.log4j.consoleappender
# stdout Appender layoutlog4j.appender.stdout.layout= org.apache.log4j.patternlayoutlog4j.appender.stdout.layout.conversionpattern=%-4r [%t]%-5p%c%x-%m%n
Looking closely at this example, log4j defines "attribute keys" to be regular:
Log4j.appender.stdout is a appender;
Log4j.appender.stdout.layout is a property of log4j.appender.stdout;
Log4j.appender.stdout.layout.ConversionPattern is a property of log4j.appender.stdout.layout;
corresponding to the specific "attribute value", you can see:
Org.apache.log4j.ConsoleAppender is a Appender;
Org.apache.log4j.PatternLayout is a property of Org.apache.log4j.ConsoleAppender;
%-4r [%t]%-5p%c%x-%m%n is the specific value of org.apache.log4j.PatternLayout;
Viewing the source code can be found that this configuration definition and log4j design is closely connected. Through the source in turn to understand the Log4j.properties file, it will be a new feeling.
Loggers Parent-child relationship
It's all about the root recorder rootlogger, and then the other Logger.
The new definition is a logger, whose name is "com", in the following format:
Log4j.logger.com=warn
Get the logger in the program:
Public Static Logger Logger = Logger.getlogger ("com");
Then define a logger, whose name is "Com.foo", in the following format:
Log4j.logger.com.foo=warn
Get the logger in the program:
Public Static Logger Logger = Logger.getlogger ("Com.foo");
Such two Logger have nested inclusion relationships on their names, like the package name definitions in Java. We call this two Logger a parent-child relationship.
"com" is the father of "Com.foo", "Com.foo" is the son of "com". The son defaults to inherit Appender from the father, the parent-child relationship is deterministic, immutable, but the inheritance attribute is only the default, that is, can change, the son can choose not to inherit the father's Appender, define the new use. There is a parent-child relationship. Do not neglect: Rootlogger is the father of "com".
Modify the initial log4j.properties configuration:
# Rootloggerlog4j.rootlogger=debug, stdout# stdout Appenderlog4j.appender.stdout=org.apache.log4j.consoleappender
# stdout Appender layoutlog4j.appender.stdout.layout= org.apache.log4j.patternlayoutlog4j.appender.stdout.layout.conversionpattern=%-4r [%t]%-5p%c%x-%m%n
# Comloggerlog4j.logger.com=debug
# Foologgerlog4j.logger.com.foo=debug
The test program (which will always be used later):
Public classMain { Public StaticLogger Rootlogger =Logger.getrootlogger (); Public StaticLogger Comlogger = Logger.getlogger ("com"); Public StaticLogger Foologger = Logger.getlogger ("Com.foo"); Public Static voidMain (string[] args) {Rootlogger.debug ("Root Debug"); Comlogger.debug ("COM Debug"); Foologger.debug ("Com.foo Debug"); } }
As a result, three log statements are output to the console:
0 [main] Debug root -root debug1 [main] debug COM -com debug1 [main] Debug Com.foo -Com.foo Deb Ug
In this example, define three Logger, define only one output source stdout, let Rootlogger use stdout, and do not let Comlogger and Foologger use stdout, but through the result can see three Logger are used Output source stdout.
It can be concluded that Rootlogger used the output source Stdout,comlogger inherited Stdout,foologger from Rootlogger and inherited Comlogger from stdout.
This is the inheritance attribute by default, and the inheritance attribute can be canceled:
The inheritance attribute is actually controlled by an identity field additivity of Logger, whose default value is true, representing inheritance, and changing it to false means no inheritance. See Example:
# Rootloggerlog4j.rootlogger=debug, stdout# stdout appenderlog4j.appender.stdout= org.apache.log4j.consoleappenderlog4j.appender.stdout.layout= org.apache.log4j.patternlayoutlog4j.appender.stdout.layout.conversionpattern=%-4r [%t]%-5p%c%x-%m%n# Comloggerlog4j.logger.com=debug, stdout2log4j.additivity.com=false# stdout2 appenderlog4j.appender.stdout2= org.apache.log4j.consoleappenderlog4j.appender.stdout2.layout= org.apache.log4j.patternlayoutlog4j.appender.stdout2.layout.conversionpattern=%m%n# Foologgerlog4j.logger.com.foo=debug
Configure a new output source for the Comlogger separately Stdout2, also to the console output, but the specific layout of the log is more simple.
Or just the test procedure, the result is as follows:
0 [main] Debug root -root debugcom debugcom.foo Debug
The output source used by Rootlogger is Stdout,comlogger uses the new data source Stdout2 and sets the Additivity=false,foologger not set Additivity=false, so from Comlogger inherits the Stdout2 and outputs log information in the same format as Comlogger.
It is worth noting that:
- If you set the Additivity=false for a Logger, you should specify at least one Appender for it, or the logger,log4j will be an error once the program is used, because the Logger has no Appender and the log information cannot be exported.
- If possible, Logger will only inherit Appender from his immediate father, and will not inherit indirectly from his grandfather. So in the above example, Foologger only inherited the Comlogger Appender, and did not inherit Rootlogger's Appender.
Level Inheritance
Level represents the log levels and is defined in "Org.apache.log4j.Level". When defining a Logger, specify the log level of the record, and if not explicitly specified, the Rootlogger default record level is DEBUG, and the other Logger inherit the levels of the parent Logger.
Then look at the modified example:
# rootloggerlog4j.rootlogger=, stdout# stdout Appenderlog4j.appender.stdout=org.apache.log4j.consoleappender
# stdout Appender layoutlog4j.appender.stdout.layout= org.apache.log4j.patternlayoutlog4j.appender.stdout.layout.conversionpattern=%-4r [%t]%-5p%c%x-%m%n# comloggerlog4j.logger.com=info# foologgerlog4j.logger.com.foo=
The test program is still just that, the output:
0 [main] Debug root -Root debug
As you can see, only the DEBUG log output of Rootlogger.
It can be explained that the default log level for Rootlogger is DEBUG. Comlogger defines the info level, the debug log is recorded in the test program, so there is no output, Foologger does not define the log level, so it inherits the info level from Comlogger, so there is no output.
Chat
Rootlogger is actually log4j specifies a Logger for the name, and log4j.properties can be undefined in Rootlogger if Rootlogger is not used in the program.
If Rootlogger is defined and other Logger are defined, and the other Logger is not set Additivity=false, then because of the inheritance attribute, the sub-Logger will also be configured Rootlogger output to Appender, which exists The possibility to output duplicate logs. This is not only the problem of Rootlogger, but also the problem of all Logger that have father-son relationship.
Logger can specify the level of logging, Appender can also specify the log level of the output, via the Threshold property:
# stdout Appenderlog4j.appender.stdout=org.apache.log4j.consoleappenderlog4j.appender.stdout.threshold=info
Logger and Appender can specify log level, make good use of this point, perhaps can get unexpected effect.
Logger, Appender, Layout is the three basic elements of log4j, each has a lot of properties can be configured. Understand the relationship between the three and working principle is the most important, more specific use or reference API, source code and other better information.
Log4j:log4j.properties Configuration Resolution