Spring Boot的日志框架:
简介
在项目的开发中,日志是必不可少的一个记录事件的组件,所以也会相应的在项目中实现和构建我们所需要的日志框架。
而市面上常见的日志框架有很多,比如:JCL、SLF4J、Jboss-logging、jUL、log4j、log4j2、logback等等,我们该如何选择呢?
通常情况下,日志是由一个抽象层+实现层的组合来搭建的。
日志门面 (日志的抽象层) |
日志实现 |
JCL(Jakarta Commons Logging) SLF4j(Simple Logging Facade for Java) jboss-logging
|
Log4j JUL(java.util.logging) Log4j2 Logback
|
SpringBoot:底层是Spring框架,Spring框架默认是用JCL;
SpringBoot选用 SLF4j和logback;
SLF4j使用
使用SLF4j https://www.slf4j.org
在开法过程中,日志记录方法的调用不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法;
1 2 3 4 5
|
@Test public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(HelloWorld.class); logger.info("Hello World"); }
|
1
|
20:33:41.673 [main] INFO com.hph.springboot.HelloWorld - Hello World
|
每一个日志的实现框架都有自己的配置文件。使用slf4j以后,配置文件还是做成日志实现框架自己本身的配置文件;
遗留问题
a(slf4j+logback): Spring(commons-logging)、Hibernate(jboss-logging)、MyBatis、其他框架
统一日志记录,即使是别的框架和如何和我一起统一使用slf4j进行输出呢?
如何让系统中所有的日志都统一到slf4j;
将系统中其他日志框架先排除出去。
用中间包来替换原有的日志框架。
我们导入slf4j其他的实现。
日志关系
引入springboot-logging
1 2 3 4
|
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency>
|
引入maven以来后
由上图我们可以知道在SpringBoot底层也是使用slf4j+logback的方式进行日志记录、SpringBoot也把其他的日志都替换成了slf4j;在者中间发生了什么呢?
原来是包被替换掉了
如果我们要引入其他框架?一定要把这个框架的默认日志依赖移除掉,Spring框架用的是commons-logging;
1 2 3 4 5 6 7 8 9 10
|
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
|
SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
@Test public void contextLoads() { Logger logger = LoggerFactory.getLogger(getClass());
logger.trace("这是trace日志..."); logger.debug("这是debug日志..."); logger.info("这是info日志..."); logger.warn("这是warn日志..."); logger.error("这是error日志..."); }
|
1 2 3
|
2019-03-28 21:15:40.771 INFO 6056 --- [ main] c.h.s.SpringBootLoggingApplicationTests : 这是info日志... 2019-03-28 21:15:40.771 WARN 6056 --- [ main] c.h.s.SpringBootLoggingApplicationTests : 这是warn日志... 2019-03-28 21:15:40.772 ERROR 6056 --- [ main] c.h.s.SpringBootLoggingApplicationTests : 这是error日志...
|
logging.file |
logging.path |
Example |
Description |
(none) |
(none) |
|
只在控制台输出 |
指定文件名 |
(none) |
my.log |
输出日志到my.log文件 |
(none) |
指定目录 |
/var/log |
输出到指定目录的 spring.log 文件中 |
给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置的了
Logging System |
Customization |
Logback |
logback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy |
Log4j2 |
log4j2-spring.xml or log4j2.xml |
JDK (Java Util Logging) |
logging.properties |
输出格式
1 2 3 4 5 6 7 8 9
|
日志输出格式: %d表示日期时间, %thread表示线程名, %-5level:级别从左显示5个字符宽度 %logger{50} 表示logger名字最长50个字符,否则按照句点分割。 %msg:日志消息, %n是换行符 --> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
|
配置格式
1 2 3 4 5 6 7 8 9 10 11
|
logging.level.com.hph.springboot=trace
#loging.path= #不指定路径在当前目录下生成springboot.log日志 #可以指定完整的路径 logging.file=D:/spring-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
|
控制台
文件
logback.xml:直接就被日志框架识别了;
指定配置
logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能
1 2 3 4
|
<springProfile name="staging"> 可以指定某段配置只在某个环境下生效 </springProfile>
|
如:
如果使用logback.xml作为日志配置文件,还要使用profile功能,会有以下错误
no applicable action for [springProfile]
因此我们可以把logback.xml重命名为logback-spring.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="false" scanPeriod="60 seconds" debug="false"> <property name="LOG_HOME" value="D:/log" /> <property name="appName" value="hph-springboot"></property> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<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>
<appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${appName}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<MaxHistory>365</MaxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern> </layout> </appender>
<logger name="com.hph" level="debug" /> <logger name="org.springframework" level="debug" additivity="false"></logger>
<root level="info"> <appender-ref ref="stdout" /> <appender-ref ref="appLogAppender" /> </root> </configuration>
|
切换日志框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
<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> <dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
### 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{ABSOLUTE} ======> %5p ==> %c{ 1 }:%L --- %m%n
#### 输出到日志文件 ### log4j.appender.D = org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File = D:/log/springboot-log4j.log log4j.appender.D.Append = true log4j.appender.D.Threshold = DEBUG ## 输出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.D = org.apache.log4j.DailyRollingFileAppender #log4j.appender.D.File = logs/error.log ## 异常日志文件名 #log4j.appender.D.Append = true #log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!! #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
|
控制台
日志
切换为log4j2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
<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>
|
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error" monitorInterval="30"> <appenders> <Console name="Console" target="SYSTEM_OUT"> <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{HH:mm:ss.SSS} ==> %-5level %class{36} %L %M ===> %msg%xEx%n"/> </Console> <File name="log" fileName="D:/log/log4j2-spring.log" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <RollingFile name="RollingFile" fileName="D:/logs/app.log" filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> <SizeBasedTriggeringPolicy size="50MB"/> <DefaultRolloverStrategy max="20"/> </RollingFile> </appenders> <loggers> <root level="trace"> <appender-ref ref="RollingFile"/> <appender-ref ref="Console"/> </root> </loggers> </configuration>
|