First, the log framework
Xiao Zhang: developed a large distributed system;
- System.out.println (""); print the key data on the console; remove it? Write in a file?
- Framework to record some runtime information of the system; log framework; zhanglogging.jar;
- A few functions on the tall? Asynchronous mode? Automatic archiving? xxxx? zhanglogging-good.jar?
- Remove the previous frame? Put on a new framework and re-modify the previous related API; zhanglogging-prefect.jar;
- JDBC --- Database driver;
Wrote a unified interface layer; log facade (an abstract layer of the log); logging-abstract.jar;
Import specific log implementations into the project; our previous log frameworks are all abstract layers of implementation;
(1) Log framework on the market;
JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j....
Log facade (the abstract layer of the log) | Log implementation |
---|---|
SLF4j(Simple Logging Facade for Java)
|
Log4j (without logback advanced) JUL (java.util.logging) (included with jdk) Log4j2 (apache development is particularly good, but many frameworks have not yet been adapted) Logback |
Choose a facade (abstract layer) on the left and an implementation on the right;
- Log facade: SLF4J;
- Log realization: Logback;
- SpringBoot: The bottom layer is the Spring framework, and the Spring framework uses JCL by default;
SpringBoot selects SLF4j and logback;
Second, the use of SLF4j log slf4j official website link
(1) How to use SLF4j in the system.
In the future development, the call of the logging method should not directly call the implementation class of the log, but call the method in the log abstraction layer;
Import slf4j jar and logback implementation jar into the system.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
Each log implementation framework has its own configuration file. After using slf4j, the configuration file is still made into the log implementation framework's own configuration file;
(2) Legacy problems (the previous framework used its own logging framework, and the last system used many different logging frameworks)
- slf4j+logback
- Spring(commons-logging)
- Hibernate(jboss-logging)
- MyBatis、xxxx
How to unify the logging framework records, even if other frameworks and I use slf4j to output together?
- How to make all the logs in the system unified to slf4j;
- First exclude other log frameworks in the system
- Then replace the original logging framework with a middleware
- Then we import other implementations of slf4j
Three, Spring Boot log relationship
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
SpringBoot uses it for log function;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
Underlying dependencies
to sum up:
- The bottom layer of SpringBoot also uses slf4j + logback for logging
- SpringBoot also replaced other logs with slf4j;
- Intermediate replacement package? (Stealing beams for column packages)
@SuppressWarnings("rawtypes")
public abstract class LogFactory {
static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J =
"http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j";
//中间包 实际是对log4j日志 new slf4j的对象 进行替换过度
static LogFactory logFactory = new SLF4JLogFactory();
What if we want to introduce other frameworks? Must the default log dependency of this framework be removed?
The Spring framework uses commons-logging;
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
in conclusion:
SpringBoot can automatically adapt all logs, and the bottom layer uses slf4j + logback to record logs. When introducing other frameworks, you only need to exclude the log framework that this framework depends on;
Four, Spring Boot log usage
(1) The default configuration of Spring Boot 2.2.5 official website log instructions
- SpringBoot helps us configure logs by default;
// 记录器
Logger LOGGER = LoggerFactory.getLogger(SpringBootTest.class);
@Test
public void contextLoad(){
// System.out.println();
/**
* 日志级别由高到低
* 日志级别:ERROR,WARN,INFO,DEBUG,或TRACE。
* 可以调整输出的日志级别;日志就只会在这个级别以以后的高级别生效
*/
LOGGER.trace("日志踪迹");
LOGGER.debug("日志debug模式");
//SpringBoot默认给我们使用的是info级别的
//,没有指定级别的就用SpringBoot默认规定的级别;root级别
LOGGER.info("日志提示信息");
LOGGER.warn("日志警告信息");
LOGGER.error("日志提示错误信息");
}
Log output format description:
日志输出格式: %d表示日期时间, %thread表示线程名, %-5level:级别从左显示5个字符宽度 %logger{50} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息, %n是换行符 --> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
# 调整日志隔离级别 wxw目录下的调成trace springboot 默认是root级别
#logging.level.com.wxw=trace
# 默认是控制台输出
# 写入spring.log指定的目录。名称可以是确切的位置,也可以相对于当前目录。
#logging.file.path=springboot/log
# 指定目录 logging.file.name :写入指定的日志文件。名称可以是确切的位置,也可以相对于当前目录。
#logging.file.name=springboot/boot.log
# 在控制台输出的日志的格式
#logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
# 指定文件中日志输出的格式
#logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
Logging properties:
logging.file.name |
logging.file.path |
An example | description |
---|---|---|---|
(No) |
(No) |
Console recording only. |
|
Specific files |
(No) |
|
Write to the specified log file. The name can be the exact location or relative to the current directory. |
(No) |
Specific directory |
|
Write to the |
(2) Custom log configuration
You can activate various logging systems by including appropriate libraries in the classpath, and you can Environment
further customize various logging systems by providing appropriate configuration files in the root directory of the classpath or in the location specified by the following Spring properties logging.config
.
- Disable default logging : You can
org.springframework.boot.logging.LoggingSystem
force Spring Boot to use a specific logging system by using the system property. This value should be the fully qualified class name of the implementationLoggingSystem
. You can also completely disable Spring Boot's logging configuration by using the valuenone。
- Put each log framework's own configuration file under the class path; SpringBoot will not use his default configuration
Logging System | Customization |
---|---|
Logback |
|
Log4j2 |
|
JDK (Java Util Logging) |
|
note:
- logback.xml : directly recognized by the log framework;
- logback-spring.xml : The log framework does not directly load log configuration items. The log configuration is parsed by Spring Boot , and the advanced profile function of Spring Boot can be used
- Springboot environment switch to open mode, (1) properties / yml configuration file (2) command line configuration
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
可以指定某段配置只在某个环境下生效
</springProfile>
E.g:
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!--
日志输出格式:
%d表示日期时间,
%thread表示线程名,
%-5level:级别从左显示5个字符宽度
%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
%msg:日志消息,
%n是换行符
-->
<layout class="ch.qos.logback.classic.PatternLayout">
<springProfile name="dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ---->
[%thread] ---> %-5level %logger{50} - %msg%n</pattern>
</springProfile>
<springProfile name="!dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ====
%-5level %logger{50} - %msg%n</pattern>
</springProfile>
</layout>
</appender>
If you use logback.xml as the log configuration file, but also use the profile function, there will be the following error
no applicable action for [springProfile]
Five, Spring Boot switching log framework
According to the log adaptation diagram of slf4j, relevant switching can be performed;
(1) The way of slf4j + log4j;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
Switch to log4j2
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>