1.1 Introduction
It's embarrassing to say it. Recently, the company was sent to the client company to interview outsourced development positions. I originally prepared some related interview questions for redis, rabbitMQ, SSM frameworks, and some project reviews I had done. I went to the interview with confidence. As a result, someone asked what the log system used in the recent project was as soon as I came up? How is the log level configured? I was confused at that time. I usually took care of it by the project manager. I just searched the Internet and pasted it and it was OK. After I finished speaking, the interviewer gave me a deep look. At that time, I felt ashamed...
1.2 Tell me less about gossip and tell me the story of the development of the log (if you already know, you can skip it and just look at the 1.3 log configuration)
To have an in-depth understanding of the implementation of log technology, I personally recommend to read: logback + slf4j. As for log configuration, it is better to understand log4j, because most projects currently use log4j. Okay, let’s start with the development story of the log:
In 1999, the Apache open source community released log4j, which caused a sensation in the entire program world. Since then, it has become the standard for logging and has been widely used by Java programmers. Later, Sun also released the Logging mechanism (java.util.logging, hereinafter referred to as JUL) in the JDK version 1.4, but the mechanism has not been recognized by the public, which is really pitiful. Soon Apache launched the commons-logging log framework (which allows developers to abstract log implementation methods without paying attention to which log technology is used. In layman's terms, you want to call Didi on your mobile phone. If you are in Beijing, you will call Didi from Beijing, and in Hong Kong, you will call Didi from Hong Kong). This framework seems to be a contempt for Sun. It can automatically find and call log technology in the current environment for log output. The log framework can support log4j or JUL. commons-logging+log4j became a classic combination of Java logs for a long time after that. However, commons-logging has not been updated for a while. I wonder if the design of commons-logging was not good enough, and it is more difficult to optimize it. Why do you say that? Because the next excellent logging framework slf4j was born, the author (Ceki Gülcü) is one of the authors of log4j. His slf4j is more elegant in design, and he also implemented logback technology, which is also more cutting-edge than log4j. At this point, the situation where the log system is dominated by commons-logging+log4j has begun to be shaken, and various commons-logging+log4j? slf4j+log4j? slf4j+logback? The combination is really heartbreaking. What's even more terrifying is that Ceki Gülcü boss helped optimize log4j, and since then, there has been another logging technology in the world - log4j2. Is this going to learn from Tencent to do WeChat and QQ? It’s really 666. Therefore, if you want to have a deep understanding of logging technology, you can find relevant information about logback + slf4j. As for the configuration file, I think you can just understand the detailed explanation of the log4j configuration I wrote below. After all, many companies now use the log4j framework.
1.3 Go to the topic, basic log configuration
1. Create a new log4j.properties file under the classpath or resource package (maven project). The following parameters are enough for the initial project configuration. For more detailed configuration,
Continue to view the 1.4 log4j log-level configuration;
#Specify the log level and output source through the root logger #The priority of log output: debug < info < warn < error < fatal#Define the log level (info) of the root logger and the alias of the output source (console, myFile)#This definition allows the log to be output in the console and file, and only output logs above the info level log4j.rootLogger=info,console,myFile#####Configure the specific implementation of the output source console as console output##########Define the output source alias console (that is, the output source defined by the root logger)# The implementation class is ConsoleAppender (console output source) log4j.appender.console=org.apache.log4j.ConsoleAppender #The format converter for specifying the log output format is the PatternLayout implementation class log4j.appender.console.layout=org.apache.log4j.PatternLayout#Define the specific format of log output log4j.appender.console.layout.ConversionPattern=%d %-5p [%c.%M()] - %m%n #######Configure the output source myFile specific implementation as file output########## Define the output source alias myFile (that is, the output source defined by the root logger)# The implementation class is RollingFileAppender (file output source) log4j.appender.myFile=org.apache.log4j.RollingFileAppender#Define the storage path of the log file log4j.appender.myFile.File=src/log/logProperties/log4j.log#Define the size of the log file log4j.appender.myFile.M axFileSize=1024kb#Define a maximum of several log files (calculate 1 from 0, that is, up to 3 files here)#Absent this size, the file generated before will be overwritten log4j.appender.myFile.MaxBackupIndex=2#Specify the format of log output to the PatternLayout implementation class log4j.appender.myFile.layout=org.apache.log4j.PatternLayout#Define the specific format of log output log4j.appender.console.layout.ConversionPattern=%d %-5p [%c.%M()] - %m%n ######### Output format explanation######%d: The time point for log printing, the default format is ISO8601, and the format can also be specified. #Definition is as follows: %d{yyy year MM month dd day HH hour mm minute ss seconds SSS}, and the output will be: #January 6, 2018 14:47:45:590#%p: Output log level, that is, DEBUG, INFO, WARN, ERROR, FATAL #%-5p: means that the character is less than 5 bits, the character is on the left (if the "-" sign is on the right), you can learn from it one example #%c: The full name of the class where the log is located #%M: The name of the method where the log is located #%m: Log information #%n: Output a carriage return line break #%L: output line number in the code2. Call log to test configuration results.
import org.apache.log4j.LogManager;import org.apache.log4j.Logger;import org.apache.log4j.PropertyConfigurator;public class LogPropertiesTest { public static void main(String[] args) { /*Parse configuration files under non-classpath String log4jPath=System.getProperty("user.dir")+"//src//log//logProperties//log4j.properties"; PropertyConfigurator.configure(log4jPath);*/ Logger log = LogManager.getLogger(LogPropertiesTest.class); log.debug("Debug"); log.info("Information"); log.warn("Warning"); log.error("Error"); log.fatal("Fatal Error"); }}1.4 Log level configuration
Log level configuration can be divided into three categories. The above configuration is to configure the log level of the parent logger, the second category is to configure the log level of the sub-class logger, and the third category is to configure the log level of the output source (console, file, etc.). Their log-level parsing priority is arranged from low to high. I’m sorry for not explaining the specific statement clearly. I should be able to understand the case directly!
1. If the log level of the parent logger (rootLogger) (assuming it is the INFO level), the log level of the subclass logger is not configured, and the log level of the output source is not configured, the output source can only output INFO level or above;
2. If the log level of the parent logger (rootLogger) (assuming it is INFO level), the log level of the sub-class logger (assuming it is DEBUG level), and the log level of the output source is not configured, the output source output is above the DEBUG level;
3. If the log level of the parent logger (rootLogger) (assuming that it is the INFO level), the log level of the subclass logger (assuming that it is the DEBUG level), and the log level of the output source (assuming that it is the INFO level), the output source outputs an INFO level or above;
4. If the log level of the parent logger (rootLogger) (assuming it is the INFO level), the log level of the subclass logger is not configured, and the log level of the subclass logger is configured.
The log level of the output source (assuming it is the DEBUG level), then the output source outputs an INFO level or above;
Therefore, from the above case we can know that there are 2 logical relationships between the logger and the output source output log level:
1. If the output source does not define the log level, it will inherit the log level closest to its subclass logger; if the subclass logger does not define the log level, it will inherit the parent logger closest to its parent logger.
2. When printing the log, the output source will compare with the log level defined by the subclass logger that is closest to it. If the level defined by the output source is higher than the subclass logger, the log will be output according to the log level defined by the output source, and vice versa.
Therefore, in the project, you can configure the log level according to the daily configuration method:
#Control the log level of the parent logger is info. By default, only logs above the info level are output under all modules log4j.rootLogger=info, console#Console#Control the log level of a module separately to error, and logs are output only when an exception occurs log4j.logger.log.logProperties=error#Control the log level of a class separately to debug, convenient to output debug information log4j.logger.log.logProperties.LogPropertiesTest=debug######################################################################################################################################################################################################################################################################################################################################################################################## #Specify the log level of the current output source. With the previous configuration, you do not need to configure this item #log4j.appender.console.Threshold = info#Specify the format of log output: Flexible format log4j.appender.console.layout=org.apache.log4j.PatternLayout #Content of specific format log4j.appender.console.layout.ConversionPattern=%d %-2p [%c.%M()] - %m%n
1.5 Conclusion
At this point, I believe you have a basic understanding of log configuration. There are many things in the article that may be wrong, and all heroes are welcome to point them out. I wrote an article to summarize it in order to be able to deeply understand the configuration of this technology, so that I will have a deeper understanding of it.