9 JavaWeb into the world of technology: the birth and development of Java logging system

> Public micro-channel number [yellow] small ramp programmer manufacturers, the Internet industry new knowledge, lifelong learning practitioner. After concerns reply "Java", "Python", "C ++", "big data", "machine learning", "algorithm", "AI", "Android", "front-end", "iOS", "PubMed", " BAT "," school trick "," written "," interview "," surface can be obtained via the corresponding free learning materials "," computer Basics "," LeetCode "and other keyword.

                     ! [] (Https://imgconvert.csdnimg.cn/aHR0cHM6Ly9waWMzLnpoaW1nLmNvbS84MC92Mi1jNDUyYWVjNWNmOWRlM2MzNjljMjA4NjRkOTMwMzhkMF9oZC5qcGc) [] (data: image / gif; base64, R0lGODlhAQABAPABAP /// wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw == "click and drag to move")!

## A well-known logging system is how design out?

# 1 Introduction

Java Empire in the beginning of the birth provides a collection of threads, IO, network and other common functions, from C and C ++ programmers territory drew many come to join, but intentionally or unintentionally ignored an important feature: output log.

For this, IO minister is actually very clear, the log is a very important thing, because after the program up and running, basically a black box, if the behavior of the program and expected inconsistencies that Bug appeared, how to locate the Bug it?   

Subjects were usable tool has two, the first is a single-step debugging, tracing step by step, to see the values ​​of variables in the code, this approach is time-consuming, and can only be used on the machine programmer. 

The second is to print the log in a particular place, the output log to help quickly locate. Especially when the code after the run up in the production environment, the log information is essential, or else out of the situation two of a smear, where to find the problem go? Can not let his subjects to transform itself into a thread into the system to execute it?

But IO ministers also have their own small thinking: log Well, with my System.out.println (.....) can not it? ! I have also provided System.err.println not?  

In obstruct IO minister, the king of the empire from the first generation to the third generation of the king, do not provide the relevant log kit in the JDK, subjects who had to put up with to use System.out.println to output log, all the the information output to the console, so there into a pile of garbage.

2 Zhangjiacun

 Zhangjiacun e-commerce systems are not immune, naturally encountered problems logging. Experienced old village has tired of a lot of useless information difficult to understand System.out.println output by the village people watching all day long and hard to force them to System.out fight, he got Xiao Zhang, the command he designed a universal log processing system.

Xiao Zhang in the JMS message queue and design took a lot of effort, has accumulated a wealth of experience, and since then has been to achieve business code, it has been CRUD, Zhang Erni day joke that he is fill in the blank HTML personnel, this time be sure to let her look at his design skill!

(Portal: "[Java Message Queue Empire] (https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513507&idx=1&sn=d6db79c1ae03ba9260fb0fb77727bb54&chksm=80d67a60b7a1f376e7ad1e2c3276e8b565f045b1c7e21ef90926f69d99f969557737eb5d8128&scene=21#wechat_redirect)", "[ birth] JMS the Java Empire (https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513515&idx=1&sn=380bb1cb56d4151fd3acc5aa86f1da9a&chksm=80d67a68b7a1f37e3d98fe4495eab4db097eedd695c99fbd8704cc0464595842c4da598b99e3&scene=21#wechat_redirect) ")

![](https://img-blog.csdn.net/20171023220049639?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd6aGV4aQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

Zhang issued to the old village needs is this:

1. In addition to the print log message to the console, can also be output to a file, or even sent out (e.g. error messages generated environment) by mail

2 \. Log content should be able to do the formatting, for example, it becomes plain text, XML, HTML formats, etc.

3 \. For different Java class, different package, there are different levels of logging, you should have the flexibility to output to different files.

For example, com.foo this package, all log files are output to the foo.log

For com.bar this package, all files are output to the bar. Log file

For all ERROR level logs all output to a file errors.log

4 \. Can be graded on a log, log some purely debug, test environment in the unit or use programmers to debug, production environment completely without. Some descriptive error log (error), the error in a production environment, then must be recorded to help the subsequent analysis.

Zhang looked at carefully, boldly he said to the old village:. "No problem, tomorrow will allow you to see the results of the old"

3 Sally's design

The old village was gone, Zhang began to analyze the needs, resorted to "object-oriented design Dafa," trying to demand from a little village in abstract concepts.

We must first log, definitely need a class to express the concept of the log, this category should have at least two properties, a timestamp, a is the message itself, called it LoggingEvent it, log records an event like thing.

Second logs can be exported to different places, console, file, mail, etc., this may look abstract, is not written to a different destination? It can be called LogDestination? 

Ah, or simply, it is called Appender, implies can continue to log additional meaning.

![](https://img-blog.csdn.net/20171023220049639?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd6aGV4aQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

As a second log of article can be formatted, than fully painted gourd dipper, the interface to define a Formatter formatted message.

![](https://img-blog.csdn.net/20171023220551618?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd6aGV4aQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

By the way, Appender should refer to Formatter, so since you can then send to LoggingEvent record after formatting. 

Article needs to Zhang stumped, different destinations different class, package output? "Destination" concept is expressed by the Appender, do not let different class, package and Appender association? No, no, not so! 

Also need a new concept, this concept is what? 

From the user perspective to think about, the villagers want to get logs have to first get a something, this thing is not to be called Logger ah? The spark of inspiration to flash so what was caught Zhang: the acquisition Logger's time to pass the class name or package name! 

![](https://img-blog.csdn.net/20171023220701264)

As a result, different class, package to distinguish, and then let the Logger and Appender association, the flexibility to set the destination log, and a Logger can have multiple Appender, you can output the same log messages to more than one place, perfect !

![](https://img-blog.csdn.net/20171023220811002)

Zhang rapidly class diagram depicts the core class! [] (Https://img-blog.csdn.net/20171023221105015)

![](https://img-blog.csdn.net/20171023220918480)

Pretty pretty, Zhang intoxicated with self-appreciation a bit. 

Make persistent efforts, the fourth demand is also designed it, to log grading, this simple definition of a Priority class is defined inside five constants DEBUG, INFO, WARN, ERROR, FATAL, represent five different levels on OK. Of course this is my five levels high and low points, DEBUG lowest level, the highest level FATAL.

You can also add some auxiliary programming for Logger methods, such as Logger.debug (....), Logger.info (...), Logger.warn (...) and so on, so that the villagers can easily future various levels of the output log.

Wait a minute, the old village head also said, "For all ERROR level logs all output to a file errors.log" demand like this, it seems to ignore.

It is also easy to handle Well, as long as the increase in a property on Appender, called Priority, if the user wants to log output is DEBUG level, but there is FileAppender of Priority ERROR level, then this would not log the output in this FileAppender in because DEBUG ERROR level higher than the level thing.

Similarly, in the Logger class can also add a Priority property, the user can go to the set, if a Logger's Priority is ERROR, the user calls the debug method Logger, and that this message will not debug output.

Zhang wholeheartedly into the designs, a look at the time, was close to midnight, and quickly rest, tomorrow to report to the mayor. 

4 orthogonality

The next day, Zhang old village to show their design LoggerEvent, Logger, Appender, Formatter, Priority and other classes and interfaces, the old village Nianzhao beard nodded with satisfaction: "Yes, Yes, there is huge compared with the previous progress. Do you know I actually gave you guidance in demand? "

"Boot? What guide?"

"It is to allow you to work toward a direction perpendicular ah"

"Orthogonal?"

'' If you put Logger, Appender, Formatter as X-axis coordinate system, Y-axis, Z-axis, you see, these three are not can vary independently without affecting each other ah? "

![](https://img-blog.csdn.net/20171023221105015)

"My game is really the case, I can interface to any extension Appender affect less than Logger and Formatter, no matter how many Logger can not affect Appender and Formatter, which is orthogonal up?"

"Yes ah, when you extract from the system the orthogonal concepts, it would be very powerful, because the change is encapsulated in one dimension, you can put any combination of these concepts, but will not become like spaghetti code. "

I heard the mayor made the theory of sublimation, Zhang excitement hand-wringing. 

"Well, you put this design implements it, yes, are you going to name?" The mayor asked.

"I'm going to call him Log4j, which means Log for Java"

"Yes, it's settled."

5Log4j

Zhang took another two months to Log4j developed out due Log4j have a good design, excellent performance, not just Zhangjiacun people with a lot of Java imperial towns, tribes fell in love with it.

Later Zhangjiacun put in Log4j open source Apache tribe, which erupted attracted many people to test it free of charge to help expand it, improve it, and soon became the most popular Empire logging facility.

Zhangjiacun recommend Empire to Log4j into the JDK, the low efficiency of the bureaucratic empire that turned out to be refused. When the news reached the ears of the IO minister, he could not help sighed with regret: Oh, lost an excellent opportunity amnesty ah. The only way is to quickly memorialized the emperor, but also provide a set of official, fight for subjects who use the official version.

In the fourth generation King (JDK1.4), subjects were finally saw the java.util.logging package provides the Empire, but also for logging, and wherein the core concepts Logger, Formatter, Handler and Log4j is very similar, except for the when the late, Log4j has long been popular, and can not shake.  

6 end

After the open-source Apache Log4j, Zhang also gradually a little lonely, restless he wrote a tool called logback, with prior experience, this logback faster than log4j. 

Today's log of the world have a lot of choice, in addition to java.util.logging, log4j, there logback, tinylog and other tools.

Zhang thought, so much logging tool, if users want to switch up how to do? Log4j not want to use, and can change to logback it? 

I provide a layer of abstraction it, users use this API abstraction layer to write the log, the underlying concrete tools do not care what the log, so that you can transplant. 

Zhang this abstraction layer is called the Simple Logging Facade for Java, referred to as SLF4J.  

![](https://img-blog.csdn.net/20171023221238826)

For Log4j, JDK logging, tinylog other tools, require an adaptation layer to SLF4J the API call interface to the conversion of specific tools. 

Because this tool is also from Zhang Logback hand, directly implements SLF4J's API, so do not even need an adaptation layer, with up fast, most efficient, SLFJ4 + Logback become a favorite of many people, much beyond Apache Common Logging + Log4j potential. 

Postscript: This article would like to talk about the history and current status of logging tools, especially Log4j core design philosophy.

Zhang Wen in fact, Ceki Gülcü, he developed Log4j, logback, and slfj4, made outstanding contributions to the Java logging business.

# Log? Chat it slf4j

Transfer from https://juejin.im/post/5ad1ccc86fb9a028c14ae528

As a Java programmer, Ken https://juejin.im/post/5ad1ccc86fb9a028c14ae528 scheduled for logging will not be unfamiliar, regardless of project size, the log records are necessary; because good log can easily help us locate some of the production problem.

> I miss is then do not say System.out.println ( "This is important log");

> I miss is the dream together System.err.println ( "This is the error log");

For daily development, in fact System.out.println very good use, but why not use this to output log it in the actual development application?

> System.out.println () In addition to the ease of use that no other feeling really much use. Where is it easy? In Eclipse, you only need to enter syso [IDEA] output to sout and press the key code hints, this method will automatically come out, I believe this is the reason a lot of Java novice love it, because I started so also dry until ... [tears omitted here]. Where it has the disadvantage of it? This too much, such as uncontrolled logging print, print time can not be determined, you can not add filters, logs are no tiers ......

I remember I came into contact with that log4j, log4j as an Apache open source projects, by using log4j, we can control the destination log information delivery is the console, files, etc. we expect output to where it is; we can control the output format of each log; each defined by a level of log information, we were able to more carefully control the log generation process. Importantly, these can be flexibly configured via a configuration file, without modifying the application code.

Indeed, log4j as the first of the more popular logging frameworks, to us in application development and maintenance has brought great convenience, so why such a good framework finally slowly down the "altar" mean? Gradually being replaced by logback it? The following is an excerpt from an online Gangster explanation to this question:

> In terms of design or the realization, Logback log4j relative terms have relatively more improvements. But despite the difficult gave an account, it was still part of the reason why the selection list logback instead of log4j. Keep in mind logback with log4j in the above concept is very similar in that they all have the same group of developers to build.

* Faster execution speed

Based on our previous work on the log4j, logback rewrite the internal implementation, in certain scenarios above, or even 10 times faster than the previous speed. Ensuring logback components more quickly, while at the same time more and less memory required.

* Fully tested

Logback After a few years, the number of countless hours of testing. Although log4j also tested, but Logback test more fully, not in the same level with log4j. We believe that this is the most important Logback people choose instead of log4j reasons. People want even under harsh conditions, your diary framework remains stable and reliable.

## slf4j log4j logback

slf4j: The Simple Logging Facade for Java that is simple java log facade

The short answer is a series of talk is slf4j log interfaces, slf4j as abstract behavior of a log exists, but does not provide a true realization.

slf4j provides a unified interface for various logging framework that allows users with a unified interface to logging, but dynamically determine the true implementation framework. logback, log4j, common-logging and other frameworks implement these interfaces.

## slf4j source code analysis

Would like to write for a long time do not know from the beginning where appropriate, slf4j package a total of 29 classes [version 1.7.21], it is impossible to enumerate. So we know it from this statement is.

```
private static final Logger logger =
LoggerFactory.getLogger(DemoTest.class);

```

In fact, the above code in the code which is what we usually declare a common way to log objects.

Logger interface provides methods to look at;

```
package org.slf4j;

interface Logger {public
// root Logger
String ROOT_LOGGER_NAME = "the ROOT";
String getName ();
// determines whether to activate a recorder trace Trace; Trace trace activation after printing generally more detailed information.
isTraceEnabled boolean ();
// the trace level
void the trace (String var1);
void the trace (String var1, var2 Object);
void the trace (String var1, var2 Object, Object var3);
void the trace (String var1, var2 Object ... );
void the trace (String var1, the Throwable var2);
Boolean isTraceEnabled (Marker var1);
void the trace (Marker var1, String var2);
void the trace (Marker var1, String var2, Object var3);
void the trace (Marker var1, String var2 , var3 Object, Object var4);
void the trace (Marker var1, var2 String, Object ... var3);
void trace(Marker var1, String var2, Throwable var3);
//进行预先判断,提升系统性能
boolean isDebugEnabled();
void debug(String var1);
void debug(String var1, Object var2);
void debug(String var1, Object var2, Object var3);
void debug(String var1, Object... var2);
void debug(String var1, Throwable var2);
boolean isDebugEnabled(Marker var1);
void debug(Marker var1, String var2);
void debug(Marker var1, String var2, Object var3);
void debug(Marker var1, String var2, Object var3, Object var4);
void debug(Marker var1, String var2, Object... var3);
void debug(Marker var1, String var2, Throwable var3);
//info级别
boolean isInfoEnabled();
void info(String var1);
void info(String var1, Object var2);
void info(String var1, Object var2, Object var3);
void info(String var1, Object... var2);
void info(String var1, Throwable var2);
boolean isInfoEnabled(Marker var1);
void info(Marker var1, String var2);
void info(Marker var1, String var2, Object var3);
void info(Marker var1, String var2, Object var3, Object var4);
void info(Marker var1, String var2, Object... var3);
void info(Marker var1, String var2, Throwable var3);
//warn级别
boolean isWarnEnabled();
void warn(String var1);
void warn(String var1, Object var2);
void warn(String var1, Object... var2);
void warn(String var1, Object var2, Object var3);
void warn(String var1, Throwable var2);
boolean isWarnEnabled(Marker var1);
void warn(Marker var1, String var2);
void warn(Marker var1, String var2, Object var3);
void warn(Marker var1, String var2, Object var3, Object var4);
void warn(Marker var1, String var2, Object... var3);
void warn(Marker var1, String var2, Throwable var3);
//error级别
boolean isErrorEnabled();
void error(String var1);
void error(String var1, Object var2);
void error(String var1, Object var2, Object var3);
void error(String var1, Object... var2);
void error(String var1, Throwable var2);
boolean isErrorEnabled(Marker var1);
void error(Marker var1, String var2);
void error(Marker var1, String var2, Object var3);
void error(Marker var1, String var2, Object var3, Object var4);
void error(Marker var1, String var2, Object... var3);
void error(Marker var1, String var2, Throwable var3);
}

```

## isXXXXEnabled

In the role of this will be explained isDebugEnabled isXXXXEnabled method.

> logger.debug("the debug msg is " +doMethod());

> We assume that the log level is set to info, that this sentence does not output the log, but this method is invoked (pre-judgment action). To call this method, you must provide parameters. doMethod method returns a result () is part of the argument. doMethod () to be performed for n seconds after n seconds, proceeds to debug () method in;

> But the log level is info. As a result, although there is no log output, but spent n seconds of configuration parameters. Obviously here worth the candle. Although the practice is almost impossible to have this case n seconds spent to construct such an argument, but if the number of concurrent large, write or affect the performance of the system. This time, it should be written:

```
if(logger.isDebugEnabled()){
logger.debug("the debug msg is " + doMethod());
}

```

Next LoggerFactory said class; start getLogger look at the entrance to this method:

```
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}

public static Logger getLogger(Class<?> clazz) {
Logger logger = getLogger(clazz.getName());
if (DETECT_LOGGER_NAME_MISMATCH) {
Class<?> autoComputedCallingClass = Util.getCallingClass();
if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));
Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
}
}

return logger;
}

```

getLogger method provides two overloaded methods for a pass in a name, the name used to label the current log. Another is to provide a Class object, in fact, which is by clazz.getName () as the name of the log.

From the above code can be compared clearly see ILoggerFactory this interface.

```
package org.slf4j;

public interface ILoggerFactory {
Logger getLogger(String var1);
}

```

ILoggerFactory this interface actually provides a unified top-level type is a log of access different realization; every logging framework needs to implement ILoggerFactory interfaces, to explain how he is to provide the Logger. Like log4j, logback Logger provides a hierarchical relationship of father and son, is implemented in ILoggerFactory implementation class. At the same time, they also need to implement Logger interface to complete the log.

Realization of ## logback

```
public class LoggerContext extends ContextBase implements
ILoggerFactory, LifeCycle

```

Mentioned above, for achieving different logging framework have achieved ILoggerFactory interface.

```
@Override
public final Logger getLogger(final String name) {

if (name == null) {
throw new IllegalArgumentException("name argument cannot be null");
}

// if we are asking for the root logger, then let us return it without
// wasting time
if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
return root;
}

int i = 0;
Logger logger = root;

// check if the desired logger exists, if it does, return it
// without further ado.
Logger childLogger = (Logger) loggerCache.get(name);
// if we have the child, then let us return it without wasting time
if (childLogger != null) {
return childLogger;
}

// if the desired logger does not exist, them create all the loggers
// in between as well (if they don't already exist)
String childName;
while (true) {
int h = LoggerNameUtil.getSeparatorIndexOf(name, i);
if (h == -1) {
childName = name;
} else {
childName = name.substring(0, h);
}
// move i left of the last point
i = h + 1;
synchronized (logger) {
childLogger = logger.getChildByName(childName);
if (childLogger == null) {
childLogger = logger.createChildByName(childName);
loggerCache.put(childName, childLogger);
incSize();
}
}
logger = childLogger;
if (h == -1) {
return childLogger;
}
}
}

```

About logback source code can refer to this series of articles: [logback source series] (https://link.juejin.im/?target=http%3A%2F%2Fkyfxbl.iteye.com%2Fblog%2F1160028)

# Java logging framework carding -SLF4J + log4j

Transfer from https://blog.csdn.net/xktxoo/article/details/76359366

  log4j configuration file is used to set the level of the recorder, storage location and layout, or may be provided in XML format provided by Java properties file (key = value) format. log4j configuration file element Description:

### Logger

  Logger is a log record to allow application objects, developers do not have to consider the output location. Application information may be transmitted through the specific needs of a printed Object. Logger is named entities, each Logger independent of each other, their names are case-sensitive and follow the hierarchical naming rule:

> If the name of the band of a dot logger is another logger prefix name, the former is referred to the latter ancestor. If there are no ancestors between the logger and its offspring logger, then the former was known as the father of the child logger.

  Root logger (rootLogger) located at the top of the logger level, it is the common ancestor of every grade level. Gets the root logger ways:

`` `
Logger rootLogger = LoggerFactory.getLogger (org.slf4j.Logger.ROOT_LOGGER_NAME);
`` `

* 1

  logger can be assigned level, if the logger is not assigned level, that it inherited from ancestors level has not been assigned a recent level until the root logger, by default, the root logger level DEBUG.

  logger may be provided by a superposition of their Appender additivity identification, is defined as follows:

> A Logger sends output to record all the Appender A statement and its ancestors, if an ancestor B logger A superimposition of identification provided is false, the output will be sent to A A and B (containing B) between All Appender, but not sent to any of the ancestors Appender B

### Appender

  Each log record Appender independently configurable devices can be: console, files, databases, messaging systems. Specific Appender log4j provided the following categories:

| Type | Description |
| --- | --- |
| org.apache.log4j.ConsoleAppender | console |
| org.apache.log4j.FileAppender | file |
| org.apache.log4j.DailyRollingFileAppender | produce a daily log file |
| org.apache.log4j.RollingFileAppender | file size reaches the specified size to generate a new file |
| org.apache.log4j.WriterAppender | log information is sent to the stream format to any designated place |

### Layout

  Layout also referred Formatters, is responsible for the time log data and format conversion is performed, determines the final form Layout data in a log record. Layout log4j provided are the following:

| Type | Description |
| --- | --- |
| org.apache.log4j.HTMLLayout | HTML table format layout |
| org.apache.log4j.PatternLayout | flexibility to specify the layout mode |
| org.apache. log4j.SimpleLayout | log contains information about the level of information and strings |
| org.apache.log4j.TTCCLayout | log contains time generated, thread, category, etc. information |

log4j similar C language printf formatted print log information, the print parameters are as follows

| Type | Description |
| --- | --- |
|% m | established code output message |
|% P | log level output |
| R & lt% | output from the application to the source of the number of milliseconds spent logging |
|% C | outputs the trigger of the log event class |
|% T | thread outputs the trigger of the log event |
|% D | time output log events, such as:% - d {yyyy-mM -dd HH: mm : SS} |
|% L | position the output log, which includes the class information, threads, the number of lines |

### Level

Each printing log can specify individual log level, the output level is controlled by the configuration file. Log4j log levels are as follows:

| Type | Description |
| --- | --- |
| ALL | lowest level, to open all logging |
| the TRACE | specify more granular than DEBUG events |
| DEBUG | specify fine-grained information about the event, debug applications helpful |
| iNFO | designated coarse-grained information about the event, highlighting the running process |
| WARN | specified circumstances potentially harmful |
| eRROR | specify the error event, the program is still allowed to run |
| FATAL | specify very serious mistake events that may cause the application to terminate |
| OFF | highest level for turn off logging |

* * *

### SLF4J + log4j practice

  log4j adapter binding may be added as dependent pom, after adding configure automatically pulled down two dependencies, are slf4j-api-1.7.25 and log4j-1.2.17.

```
<dependency>
<groupId>org.slf4j</groupId>
slf4j-log4j12
<version>1.7.25</version>
</dependency>
```

  log4j configuration file must be specified or default configuration. If the program was introduced more than a bag, in the absence of written profile, and do not set the default print log configurator, log4j will report the following error: 

```
public class Test {

public static void main(String [] args) {
//BasicConfigurator.configure();
Logger logger = LoggerFactory.getLogger(Test.class);
logger.debug( " this is {} debug log", Test.class.getName() );
logger.error( " this is {} error log", Test.class.getName());
}
}

结果:
log4j:WARN No appenders could be found for logger (com.xiaofan.test.Test).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
```

  By the BasicConfigurator.configure () may specify a default log4j configuration, a default configuration which generates rootLogger, and add the Appender a console, the following source code:

```
static public void configure() {
Logger root = Logger.getRootLogger();
root.addAppender(new ConsoleAppender(
new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN)));
}
```

  Print log results are as follows:

```
0 [main] DEBUG com.xiaofan.test.Test - this is com.xiaofan.test.Test debug log
2 [main] ERROR com.xiaofan.test.Test - this is com.xiaofan.test.Test error log
```

  Write log4j configuration files in two ways: Java properties file (key = value) and XML.

* log4j.properties 

Properties profile example is as follows:

```
### set log levels ###
log4j.rootLogger = debug,stdout,D,E

### 输出到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %p [%c] %m%n

### 输出到日志文件 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

### 保存异常信息到单独文件 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

### logger ###
After log in Set # com.xiaofan ERROR output path will only log
# log4j.logger.com.xiaofan ERROR =
`` `

  Under the log4j.properties file into the project's resources folder, if the program does not appear to specify other configuration files, log4j will load the log4j.properties file as the default configuration file. By PropertyConfigurator.configure () Displays the external profile. 

  Test code is as follows:

```
package com.xiaofan.test;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Created by Jerry on 17/7/24.
*/
public class Test {

public static void main(String [] args) {
PropertyConfigurator.configure(Test.class.getResource("/log4j.properties"));
Logger logger = LoggerFactory.getLogger(Test.class);
logger.debug( " this is {} debug log", Test.class.getName() );
logger.error( " this is {} error log", Test.class.getName());
}
}

结果:
console:
2017-07-27 09:44:50 DEBUG [com.xiaofan.test.Test] this is com.xiaofan.test.Test debug log
2017-07-27 09:44:50 ERROR [com.xiaofan.test.Test] this is com.xiaofan.test.Test error log
/logs/error.log:
2017-07-27 09:48:27 [ main:1 ] - [ ERROR ] this is com.xiaofan.test.Test error log
/logs/log.log:
2017-07-27 09:48:27 [ main:0 ] - [ DEBUG ] this is com.xiaofan.test.Test debug log
2017-07-27 09:48:27 [ main:1 ] - [ ERROR ] this is com.xiaofan.test.Test error log
```

* log4j.xml

  XML configuration file as follows:

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' >


<layout >
<param name="ConversionPattern"
value="[%d{yyyy-MM-dd HH:mm:ss,SSS\} %-5p] %c{2\} [%t] - %m%n" />
</layout>
<filter >
<param name="levelMin" value="debug" />
<param name="levelMax" value="error" />
<param name="AcceptOnMatch" value="true" />
</filter>


<param name="File" value="logs/error.log" />
<param name="Append" value="true" />
<param name="threshold" value="error" />
<param name="MaxBackupIndex" value="10" />
<layout >
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
</layout>


<param name="File" value="logs/log.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />
<layout >
<param name="ConversionPattern"
value="[%d{MMdd HH:mm:ss SSS\} %-5p] [%t] %c{3\} - %m%n" />
</layout>

<logger name="mylogger" additivity="true">
<level value="debug" />

</logger>

<root>
<priority value ="debug"/>



</root>

</log4j:configuration>
```

 Under the project resources log4j.xml file into the folder, if the program does not appear to specify other configuration files, log4j will be loaded by default log4j.xml file as a configuration file. By DOMConfigurator.configure () to display the development of an external configuration file. 

Test code is as follows:

```
public class Test {

public static void main(String [] args) {
DOMConfigurator.configure(Test.class.getResource("/log4j.xml"));
Logger logger = LoggerFactory.getLogger(Test.class);
logger.debug( " this is {} debug log", Test.class.getName() );
logger.error( " this is {} error log", Test.class.getName());
}
}

结果:
控制台:
[2017-07-27 12:43:20,474 DEBUG] test.Test [main] - this is com.xiaofan.test.Test debug log
[2017-07-27 12:43:20,484 ERROR] test.Test [main] - this is com.xiaofan.test.Test error log
/logs/error.log
ERROR (com.xiaofan.test.Test:18)- this is com.xiaofan.test.Test error log
/logs/log.log
[0727 12:50:04 829 DEBUG] [main] xiaofan.test.Test - this is com.xiaofan.test.Test debug log
[0727 12:50:04 830 ERROR] [main] xiaofan.test.Test - this is com.xiaofan.test.Test error log
```

 A technical station Ali Java engineers. Author Huang oblique, focused Java related technologies: SSM, SpringBoot, MySQL, distributed, middleware, cluster, Linux, network, multi-threaded, occasionally speaking point Docker, ELK, as well as dry goods and technology to share the learning experience, committed to Java full stack development! (No reply after public concern "Java" Java can receive basic, advanced, and the project architect and other free learning materials, more databases, distributed, service and other popular micro learning video technology, rich content, both theory and practice, also presented will be the original author of the study guide Java, Java programmer interview guide and other dry goods resources)

Guess you like

Origin www.cnblogs.com/xll1025/p/11366387.html