SpringBoot log
- Log overview
- Log usage
- Print log
-
- Get log object
- Print log using log object
- Introduction to log framework
-
- facade mode
- Introduction to SLF4J framework (simple logging facade for java)
- Log format description
- Log level
-
- Classification of log levels
- Use of log levels
- Log configuration
-
- Configure log level
- Log persistence
-
- Configure the path and file name of the log file
- Configure the save path of the log file
- Configure log file splitting
- Simpler log output
Log overview
- Why study?
Logs are no stranger to us. From the JavaSE part, we have been using System.out.print to print logs. We can find and locate problems by printing logs, or analyze the operation of the program based on the logs. Process. When learning Spring, we often analyze and locate problems based on console logs.
As the complexity of projects increases, we also have greater needs for printing logs, not just for locating and troubleshooting problems.
If you need to record some company’s operation records (some audit companies will require it), you may also need to use logs to record some of your preferences, persist the logs, and conduct subsequent data analysis, etc. However, System.out.print cannot meet our needs very well, so we need to use some professional frameworks (leave professional things to professionals)
Log usage
The Spring Boot project will have log output by default when it is started, as shown in the following figure:
We can see that the logs produced by SpringBoot lack a lot of information
The logs printed by SpringBoot include log time, log level, thread, location of printed log, log information, etc.
Springboot has a built-in log framework slf4j. We can call slf4j directly in the program to output logs
Print log
Steps to print logs:
- Get the log object in the program
- Use a log object to output what you want to print
Get log object
To obtain the log object in the program, you need to use the LoggerFactory, as shown in the following code:
public class LogController {<!-- --> private static Logger logger = LoggerFactory.getLogger(LogController.class); }
LoggerFactory.getLogger needs to pass a parameter to identify the name of the log. This will make it clearer which class outputs the log. When there is a problem, it can be more convenient and intuitive to locate the problem class
Use log object to print log
There are many ways to print log objects. We can first use the info() method to output the log
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class LogController {<!-- --> private static Logger logger = LoggerFactory.getLogger(LogController.class); @RequestMapping("/log") public String logger(){<!-- --> logger.info("This is a log"); return "Print log"; } }
Introduction to log framework
SLF4J is different from other logging frameworks. It is not a real log implementation, but an abstraction layer, a specification, standard, and interface specified for the log framework. All SLF4J cannot be used independently and needs to be used in conjunction with a specific log framework.
Facade mode
SLF4J is a typical application of the facade pattern
Facade Pattern is a software design pattern that provides a unified interface for accessing a group of interfaces in a subsystem. This pattern simplifies the interaction between clients and subsystems by creating a high-level interface, thereby reducing the coupling between systems.
Typically, a system consists of multiple subsystems, each with its own interfaces and functions. The client needs to interact with these subsystems, which may cause the client code to become complex and sensitive to system changes. The emergence of facade mode is to solve this problem.
Through the facade pattern, the client only needs to interact with the facade object, and the facade object is responsible for delegating the request to the corresponding subsystem for processing. In this way, the client does not need to know the specific implementation details of the subsystem, thereby reducing the coupling between the client and the subsystem, and also facilitating the modification and maintenance of the subsystem.
In general, the facade pattern can help simplify the interface of complex systems and improve the flexibility and maintainability of the system. It can also hide the complexity of the system and make it easier for clients to use.
The facade mode mainly includes two roles
The appearance role also becomes the facade role, the unified interface of the system to the outside world.
A subsystem role can have one or more SubSystems at the same time. Each SubSystem is not a separate class, but a collection of classes. SubSystem does not know the existence of Facade.
SLF4J framework introduction (simple logging facade for java)
SLF4J is the facade of other logging frameworks. SLF4J can be understood as a unified API interface that provides log services and does not involve specific log logic implementation.
Do not introduce log facade
Common log frameworks include log4j, logback, etc. If a project already uses log4j, and you depend on another class library, if you depend on another log framework logback, then you need to add logback as well.
There is a problem
- Different log frameworks have different API interfaces and configuration files. If multiple log frameworks coexist, multiple sets of configuration files have to be maintained (the configuration file here refers to the user-defined configuration file)
- If you want to change the logging framework, the application will have to modify the code, and there may be some code conflicts during the modification process
- If multiple third-party frameworks are introduced, multiple sets of configurations will have to be maintained.
Introducing a log facade
After the introduction of the log facade framework, there is a unified API interface between the application and the log framework. At this time, the application only needs to maintain a set of log file configurations, and when the underlying implementation framework changes, there is no need to change the application code.
Log format description
As you can see from the picture above, the log output content elements are as follows:
- Time period: accurate to milliseconds
- Log level: ERROR, WARN, INFO, DEBUG or TRACE
- Process ID
- Thread name
- Logger name (usually the class name of the source code)
- ?Journal content
Log level
The log level represents the severity of the problem corresponding to the log information, in order to quickly filter the log information that meets the target.
Classification of log levels
In the Spring framework, log levels usually follow common log level standards, such as those defined in SLF4J or Logback. The Spring framework itself does not define its own log levels, but uses these common standards. The following are common log levels:
TRACE: Provides very detailed log information, usually used for debugging and tracking details during program execution.
DEBUG: Used to output debugging information to assist in locating problems and debugging programs.
INFO: Provides general runtime information indicating that the application is running.
WARN: Indicates a potential problem that will not cause the application to stop running, but may require attention.
ERROR: Used to indicate that although an error has occurred, the program is still allowed to continue running.
FATAL: Indicates a serious error that may cause the application to exit.
When configuring the log level of a Spring application, it can be set through a configuration file (such as logback.xml or log4j2.xml) or through code. Generally speaking, setting through configuration files is more flexible, and different log levels can be set according to different packages or classes. In Spring, the log level can also be configured through Spring Boot’s application.properties or application.yml file.
In general, by setting the log level appropriately, it can help developers understand the running status of the application, quickly locate problems, and improve the maintainability and stability of the system.
Using log levels
The log level is set by the developer. The developer judges the importance of the information based on the user’s understanding.
For these levels, the Logger object provides corresponding methods to output logs.
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class LogController {<!-- --> private static Logger logger = LoggerFactory.getLogger(LogController.class); @RequestMapping("/log") public String logger(){<!-- --> logger.trace("This is a trace log"); logger.debug("This is a debug log"); logger.info("This is an info log"); logger.warn("This is a warning log"); logger.error("This is an error log"); return "Print log"; } }
SpringBoot’s default logging framework is Logback. Logback does not have FATAL level, it is mapped to ERROR.
The appearance of a fatal log indicates that the service has become inoperable to some extent and requires emergency intervention by the system administrator. Normally, there should be at most a maximum of FATAL records in the life cycle of a process.
It turns out that only info, warn and error level logs are printed
This is related to the configuration of the log level. The default level of log output is the info level, so only logs greater than or equal to this level will be printed, that is, info, warn and error
Log configuration
The above is the purpose of the journal. The journal framework supports our more flexible output journal, including content, format, etc.
Configure log level
We can configure the logging.level configuration item in the configuration file application.yml
We can find that the Debug level log can be printed at this time.
Log persistence
The above logs are all output on the console. However, in an online environment, we need to save the logs so that we can trace the problem after problems occur. Saving the logs is called persistence. strong>
Two ways of log persistence
- Configuration log file name
- Configuration log storage directory
Configure the path and file name of the log file
yml configuration file configuration
Set the file name of the file
Configure the saving path of the log file
This method can only set the path of the log, and the file name is fixed spring.log.
Notice:
When both logging.file.name and logging.file.path are configured, only the other will take effect, and logging.file.name will prevail
Configure log file split
If our logs are placed in one file, as the project progresses, the log files will become larger and larger, and the log files will need to be segmented.
Of course, the logging framework also takes this into consideration for us, so if we do not configure it, we will configure it automatically.
By default, log files exceeding 10M will be split
Configuration item | Description | Default value |
---|---|---|
logging.logback.rollingpolicy.file-name-pattern | File name format after log splitting | ${LOG_FILE}.%d{yyyy-MM-dd}. %i.gz |
logging.logback.rollingpolicy.max-file-size | If the log file exceeds this, it will be automatically split | 10MB |
Profile Splitting
yml configuration
logging: logback: rollingpolicy: max-file-size: 1KB file-name-pattern: ${<!-- -->LOG_FILE}.%d{<!-- -->yyyy-MM-dd}.%i
- Log files will be split if they exceed 1KB (setting 1KB is for better development. Enterprise development is usually set to 200M, 500M, etc., there is no
There are clear standards)- The name of the divided journal file is: journal name.issue.index
Simpler log output
It is very cumbersome to use LoggerFactory.getLogger(xxx.class) every time, and each class must be added several times. Lombok provides us with a simpler way.
- Add lombok framework support
- Use the @slf4j annotation to output the log.
import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController public class LogController {<!-- --> // private static Logger logger = LoggerFactory.getLogger(LogController.class); @RequestMapping("/log") public String logger(){<!-- --> //The object name is fixed log at this time log.trace("This is a trace log"); log.debug("This is a debug log"); log.info("This is an info log"); log.warn("This is a warning log"); log.error("This is an error log"); return "Print log"; } }
We can find that the life cycle of this annotation only exists in the source code stage
**After the code is compiled, the Logger object is automatically generated for us **