Existing log framework:
- Log facade: JCL (Jakarta Common Logging), SLF
- Log implementation: JUL (Java Util Logging), log4j, logback, log4j2
1. JUL learning
1.1 JUL introduction
JUL: the full name is Jakarta Common Logging. It is a Java Native logging framework. It does not need to introduce a third-party class library. Compared with other logging frameworks, it is easy to use and learn, and can be used flexibly in small applications.
framework:
- Loggers: loggers. The application obtains the Logger object and calls its API to publish log information. The Logger object is usually the entry program for the application to access the logging system;
- Appenders: also known as handlers. Each Logger is associated with a set of handlers. The Logger will hand over the log to the associated handlers, who are responsible for recording the log. Handlers are abstract here. Its specific implementation determines that the location of logging can be console, file, etc;
- Layouts: also known as Formatters. It is responsible for converting and formatting the data in log events. Layouts determines the final form of data in a log record;
- Level: each log message has an associated log level. This level provides a rough guide to the importance and urgency of log messages. Level can be associated with Loggers and Appenders to facilitate us to filter messages;
- Filters: filters. Customize which messages will be recorded and which messages will be let go as needed.
[summary]: the user uses the Logger to record logs. The Logger holds multiple Handlers, and the log output operation is completed by the Handler. Before the Handler outputs logs, it will be filtered by Filters to determine which log levels are released and which log levels are intercepted. The Handler will output the log contents to the specified location (console / file). When outputting logs, the Handler will use Layout to typeset the output content.
1.2 quick start
Create a new SpringBoot project and introduce a junit dependency. POM file:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
Introductory case:
public class JulTest { public static final String CALSS_NAME = "com.zzc.sbexp.log.jul.JulTest"; @Test public void testQuick() { Logger logger = Logger.getLogger(CALSS_NAME); // Output log level: info logger.info("hello jul"); // Output by method logger.log(Level.INFO, "hello jul"); // Output variable values through placeholders String name = "zzc"; Integer age = 24; logger.log(Level.INFO, "User information:{0}, {1}", new Object[]{name, age}); } }
1.3 log level
Log level from high to low: off, server, warning, info, config, fine, finer, finest, all
If yes: off, the log level output is turned off;
If it is: all, then log level output is enabled.
The default level of Jul is info. As long as the log level is higher than info, it will be output.
Custom log level:
Steps:
- Turn off system default configuration
- Create a Handler. Here I output to the console and disk, so it is ConsoleHandler and FileHandler;
- Create a Formatter;
- Associate the Handler with the Formatter;
- Add the Handler to the Logger.
@Test public void testLogConfig() throws IOException { Logger logger = Logger.getLogger(CALSS_NAME); // Turn off system default configuration logger.setUseParentHandlers(false); // Create console output Handler ConsoleHandler consoleHandler = new ConsoleHandler(); SimpleFormatter simpleFormatter = new SimpleFormatter(); // relation consoleHandler.setFormatter(simpleFormatter); // Create file output Handler FileHandler fileHandler = new FileHandler("logs.log"); fileHandler.setFormatter(simpleFormatter); logger.addHandler(consoleHandler); logger.addHandler(fileHandler); // Configure log level logger.setLevel(Level.ALL); consoleHandler.setLevel(Level.ALL); fileHandler.setLevel(Level.WARNING); logger.severe("server"); logger.warning("warning"); logger.info("info"); }
[note]: the parent path of logs.log must exist, otherwise an error will be reported.
To modify the default configuration of RootLogger from a custom configuration file:
Add a configuration file logging.properties under the resource path, which contains:
#RootLogger is the default processor. You can configure multiple processors. All child logs that do not manually release the parent log will use these processors handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler #The log level of RootLogger (default INFO). All handlers are limited to this log level. The log level of Handler can be higher than that of RootLogger .level = INFO java.util.logging.FileHandler.pattern = E:/logs/java%u.log #The size of a single log file, in bits, 1024bit is 1kb java.util.logging.FileHandler.limit = 1024 * 1024 * 10 #Number of log files java.util.logging.FileHandler.count = 1 #Whether to add log content by appending java.util.logging.FileHandler.append = true java.util.logging.FileHandler.encoding = UTF-8 java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.encoding = UTF-8 java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
code:
@Test public void testLogProperties() throws IOException { // Loading configuration files through classes InputStream in = JulTest.class.getClassLoader().getResourceAsStream("logging.properties"); // Create LogManger load profile LogManager logManager = LogManager.getLogManager(); logManager.readConfiguration(in); Logger logger = Logger.getLogger(CALSS_NAME); logger.severe("server"); logger.warning("warning"); logger.info("info"); logger.finest("finest"); }
To add a custom Logger to a custom profile:
Add a configuration file logging.properties under the resource path, which contains:
... my.logger.handlers = java.util.logging.ConsoleHandler my.logger.level = INFO my.logger.useParentHandlers = false
code:
@Test public void testMyLogProperties() throws IOException { // Loading configuration files through classes InputStream in = JulTest.class.getClassLoader().getResourceAsStream("logging.properties"); // Create LogManger load profile LogManager logManager = LogManager.getLogManager(); logManager.readConfiguration(in); Logger logger = Logger.getLogger("my.logger"); logger.severe("server"); logger.warning("warning"); logger.info("info"); logger.finest("finest"); }
2. Log4j learning
2.1 Log4j introduction
Log4j is an open source log framework under Apache. By using log4j in the project, we can control the location of log information output (console, file and database); we can also control the output format of each log. By defining the output level of the log, we can more flexibly control the log output process and facilitate the debugging of the project.
Log4j component
Log4j is mainly composed of Loggers, Appenders and Layout.
- Loggers: controls the output level of logs and whether logs are output
- Appenders: specifies how logs are output (console, file)
- Layout: output format of console log information
1. Loggers
Loggers: loggers, which are responsible for processing log records. The naming of instances is the fully qualified name of classes. The name of loggers is case sensitive. Its naming has an inheritance mechanism. For example, the logger of org.apache.commons inherits the logger of org.apache.
In Log4j, there is a special logger called root, which is the root of all loggers. The root logger can be obtained through the Logger.getRootLogger() method.
2. Appenders
Appenders is used to specify where the log is output. You can also specify the output destination of the log. There are several common destinations:
- Console appender: output logs to the console
- FileAppender: outputs logs to a file
- Daily rolling file appender: output the log to a log file and a new file every day
- RollingFileAppender: output the log to a log file and specify the file size. When the file size reaches the specified size, the file name will be automatically changed and a new file will be generated
- JDBC appender: save log to database
3. Layouts
Layouts is used to control the format of log output content, so that we can output logs in various required formats. Common layouts:
- HTML Layout: format the log output in HTML tabular form
- Simple Layout: simple log output format. The printed log format is (info - message)
- Pattern Layout: the most powerful formatter. You can output the log according to the custom format. If no conversion format is specified, the default conversion format is used
2.2 quick start
Create a new SpringBoot project and introduce log4j dependency:
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
Introductory case:
public class Log4jTest { @Test public void testQuick() { Logger logger = Logger.getLogger(Log4jTest.class); logger.info("info"); } }
After execution, view the console:
It can be seen that the system configuration is required. Generally, it is configured with a configuration file. Here, it is configured with code for the time being.
@Test public void testQuick() { BasicConfigurator.configure(); Logger logger = Logger.getLogger(Log4jTest.class); logger.info("info"); }
In this way, the log information can be output normally.
2.3 log level
Log level:
- Fatal: fatal error. It usually causes the system to crash and terminate the operation
- Error: error message. It will not affect the system operation
- warn: warning message. Problems may occur
- info: operation information. Data connection, network connection, IO operation, etc
- Debug: debug information. It is generally used in development to record program variables, parameters, transfer information, etc
- Trace: trace information. Record all process information of the program
The default level of Log4j is debug. As long as the log level is higher than debug, it will be output.
2.4 using configuration files
Create a new configuration file log4j.properties under resources:
# Specifies the default configuration information of the RootLogger top-level parent element # Specify the log level = info, and the appender used is console log4j.rootLogger = info,console # Specifies the appender for console log output log4j.appender.console = org.apache.log4j.ConsoleAppender # Specify message format layout log4j.appender.console.layout = org.apache.log4j.SimpleLayout
Use in Code:
@Test public void testProperties() { Logger logger = Logger.getLogger(Log4jTest.class); logger.fatal("fatal"); logger.error("error"); logger.warn("warn"); logger.info("info"); logger.debug("debug"); logger.trace("trace"); }
1. Customize the format of the configuration Appender
In the log4j.properties configuration file, we define the log output level and output end, and configure the log output format in the output end respectively:
# Specifies the default configuration information of the RootLogger top-level parent element # Specify the log level = info, and the appender used is console log4j.rootLogger = info,console # Specifies the appender for console log output log4j.appender.console = org.apache.log4j.ConsoleAppender # Specify message format layout log4j.appender.console.layout = org.apache.log4j.PatternLayout #Specifies the content of the message format log4j.appender.console.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n
log4j uses the print format similar to the printf() function of C language to format the log information. The specific placeholders and their meanings are as follows:
%m=Output the information specified in the code %p=Output priority %n=Newline character %r=Output from application startup to output log The number of milliseconds the message took %c=Output the fully qualified name of the class to which the print statement belongs %t=Output the full name of the thread that generated the log %d=The current time of the output server. Default to ISO8601. Format can be specified:%d{yyyy year MM month dd day HH:mm:ss} %l=Where the output log occurred. Including: class name, thread name and the number of lines in the code %F=The name of the file where the output log message is generated %L=Line number in output code %%=Output a % character
You can add modifiers between% and characters to control the minimum width, maximum width, and how the text is aligned. For example:
%5c=The fully qualified name of the output class. The minimum width is 5. The class name is less than 5. By default, it is right aligned %-5c=The fully qualified name of the output class. The minimum width is 5, and the class name is less than 5“-" Specify left alignment, there will be spaces %.5c=The fully qualified name of the output class. The maximum width is 5. If the class name is greater than 5, the extra characters on the left will be truncated; if it is less than 5, there will be no spaces %20.30c%=If the class name is less than 20, fill in spaces and align right; if it is greater than 30, the extra characters on the left will be truncated
2. FileAppender of custom configuration file
log4j.properties: output the log information to the file FileAppender
# Specifies the default configuration information of the RootLogger top-level parent element # Specify the log level = info, and the appender used is console log4j.rootLogger = info,console,rollFile # Specifies the appender for console log output log4j.appender.console = org.apache.log4j.ConsoleAppender # Specify message format layout log4j.appender.console.layout = org.apache.log4j.PatternLayout # Specifies the content of the message format log4j.appender.console.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n # Specifies the appender for console log output log4j.appender.file = org.apache.log4j.FileAppender # Specify message format layout log4j.appender.file.layout = org.apache.log4j.PatternLayout # Specifies the content of the message format log4j.appender.file.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n # Specify the path to save the log file log4j.appender.file.file = E:/temp/logs.log # Specifies the character set of the log file log4j.appender.file.encoding = UTF-8
log4j.properties: split by file size
# Specifies the default configuration information of the RootLogger top-level parent element # Specify the log level = info, and the appender used is console log4j.rootLogger = info,console,rollFile # Specifies the appender for console log output log4j.appender.console = org.apache.log4j.ConsoleAppender # Specify message format layout log4j.appender.console.layout = org.apache.log4j.PatternLayout # Specifies the content of the message format log4j.appender.console.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n # appender object split by file size log4j.appender.rollFile = org.apache.log4j.RollingFileAppender # Specify message format layout log4j.appender.rollFile.layout = org.apache.log4j.PatternLayout # Specifies the content of the message format log4j.appender.rollFile.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n # Specify the path to save the log file log4j.appender.rollFile.file = E:/temp/logs.log # Specifies the character set of the log file log4j.appender.rollFile.encoding = UTF-8 # Specifies the size of the log file contents log4j.appender.rollFile.maxFileSize = 1MB # Specifies the number of log files log4j.appender.rollFile.maxBackupIndex = 10
@Test public void testPropertiesBySize() { Logger logger = Logger.getLogger(Log4jTest.class); for (int i = 0; i < 10000; i++) { logger.fatal("fatal"); logger.error("error"); logger.warn("warn"); logger.info("info"); logger.debug("debug"); logger.trace("trace"); } }
log4j.properties: split by time
# Specifies the default configuration information of the RootLogger top-level parent element # Specify the log level = info, and the appender used is console log4j.rootLogger = info,dailyFile # appender object split by time size log4j.appender.dailyFile = org.apache.log4j.DailyRollingFileAppender # Specify message format layout log4j.appender.dailyFile.layout = org.apache.log4j.PatternLayout # Specifies the content of the message format log4j.appender.dailyFile.layout.conversionPattern = [%p]%r %l %d{yyyy-MM-dd HH:mm:ss} %m%n # Specify the path to save the log file log4j.appender.dailyFile.file = E:/temp/logs.log # Specifies the character set of the log file log4j.appender.dailyFile.encoding = UTF-8 # Specify rules for log file splitting log4j.appender.dailyFile.datePattern = '.'yyyy-MM-dd-HH-mm-ss
3. User defined Logger
log4j.properties:
# Specifies the default configuration information of the RootLogger top-level parent element # Specify the log level = info, and the appender used is console log4j.rootLogger = trace,console # The custom logger will also inherit the RootLogger, so it will also be output to the console log4j.logger.com.zzc.sbexp.log.log4j = info,file # apache's logger will be output to the console only if it is at or above the error level, and will not be output to a file log4j.logger.org.apache = error ...
@Test public void testMyLogger() { Logger logger = Logger.getLogger(Log4jTest.class); logger.fatal("fatal"); logger.error("error"); logger.warn("warn"); logger.info("info"); logger.debug("debug"); logger.trace("trace"); // apache logger Logger logger1 = Logger.getLogger(Logger.class); logger1.fatal("fatal1"); logger1.error("error1"); logger1.warn("warn1"); logger1.info("info1"); logger1.debug("debug1"); logger1.trace("trace1"); }
After operation: