介绍 市面上常见的日志框架有很多。通常情况下,日志是由一个抽象层+实现层的组合来搭建的,而用户通常来说不应该直接使用具体的日志实现类,应该使用日志的抽象层。
SpringBoot 支持 Java Util Logging
,Log4J
,Log4J2
和 Logback
日志框架,默认采用 logback
日志。在实际 SpringBoot 项目中使用 SpringBoot 默认日志配置是不能够满足实际生产及开发需求的,需要选定适合的日志输出框架,灵活调整日志输出级别、日志输出格式等。本章主要讲述如何进行 SpringBoot 项目的日志详细配置。
日志门面(日志的抽象层) 日志实现 JCL(Jakarta Commons Logging)(2014年后不再维护) jboss-logging (不适合企业项目开发使用) SLF4J(Simple Logging Facade for java) Log4j JUL(java.util.logging)(java.util.logging)(担心被抢市场,推出的) Log4j2( apache开发的很强大,借了log4j的名,但很多框架未适配上) Logback(Log4j同一个人开发的新框架,做了重大升级)
SpringBoot 默认选择的是 SLF4J + Logback 的组合,如果不需要更改为其他日志系统(如 Log4j2 等),则无需多余的配置,LogBack 默认会将日志打印到控制台上。
基本用法 因为新建的 Spring Boot 项目一般都会引用 spring-boot-starter
或者 spring-boot-starter-web
,而这两个起步依赖中都已经包含了对于 spring-boot-starter-logging
的依赖,所以,我们无需额外添加依赖。
1.1 日志级别介绍 (1)日志级别从小到大为 trace < debug < info < warn < error < fatal ,由于默认日志级别设置为 INFO ,因此上面样例 trace 和 debug 级别的日志都看不到。 (2)我们可以在 applicaition.properties 文件中修改日志级别。比如下面将全局日志级别都改成 trace ,因此系统所有的日志都能看到:
1 2 3 4 logging: level: root: trace
(3)我们也可以只设置某个包的日志级别,这样能够更方便准确地定位问题。比如下面配置,只对所有 com.xiang.learn 包下面产生的日志级别改成 trace :
1 2 3 4 logging: level: com.xiang.learn: trace
打印结果当前包下能打印完整:
**如果设置成其它包,结果就不能打印 Trace
和 Debug
**
1.2 日志文件生成 日志文件生成在配置文件有两种方式写法,分别是:
logging.file.path
,只能指定路径,不能自定义文件名,自动生成 spring.log 文件logging.file.name
,它可以自定义文件名1 2 3 4 5 6 logging: level: file: path: logfile name: logfile/my.log
不管是哪一种配置,Spring Boot
都会自动按天分割日志文件,也就是说每天都会自动生成一个新的 log 文件,而之前的会自动打成 GZ 压缩包。
另外也可以设置日志文件的保留时间,以及单个文件的大小:
1 2 3 4 5 logging: logback: rollingpolicy: max-file-size: 2KB max-history: 1
1.3 日志输出格式配置 (1)我们可以分别修改在控制台输出的日志格式,以及文件中日志输出的格式:
符号说明:
%d{HH:mm:ss.SSS} :日志输出时间%-5level :日志级别,并且使用 5 个字符靠左对齐%thread :输出日志的进程名字,这在 Web 应用以及异步任务处理中很有用%logger :日志输出者的名字%msg :日志消息%n :平台的换行符{50}: 限制字符长度 1 2 3 4 logging: pattern: console: '%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n' file: '%d{yyyy-MM-dd HH:mm:ss.SSS} >>> [%thread] >>> %-5level >>> %logger{50} >>> %msg%n'
(2)我们自定义设置文件输出格式通过上图发现没有最开始打印的颜色了,没有颜色区分始终感觉有点别扭,如果想让不同类型的数据具有不同的高亮效果,记得添加 %clr()
配置如下:
1 2 3 4 logging: pattern: console: '%d{yyyy-MM-dd} [%thread] %clr(%-5level) %clr(%logger{50}){cyan} - %msg%n' file: '%d{yyyy-MM-dd HH:mm:ss.SSS} >>> [%thread] >>> %-5level >>> %logger{50} >>> %msg%n'
日志底层实现分析 前面我们也讲了,新建的 Spring Boot 项目一般都会引用 spring-boot-starter
或者 spring-boot-starter-web
,而这两个起步依赖中都已经包含了对于 spring-boot-starter-logging
的依赖,所以,我们无需额外添加依赖。
在org\springframework\boot\logging\logback\base.xml 做了日志的默认配置
然后它会通过org.springframework.boot.logging.LoggingSystemProperties 类中读取上面的配置信息
自定义Logback日志配置 Logging System 自定义日志配置文件名 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
在 resources 目录下创建 logback.xml , 文件内容如下,SpringBoot就会采用以下日志配置: 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 89 90 91 92 93 94 95 96 97 98 99 100 101 <?xml version="1.0" encoding="UTF-8" ?> <configuration scan ="false" scanPeriod ="60 seconds" debug ="false" > <property name ="LOG_HOME" value ="./logfile" /> <property name ="appName" value ="springboot-learn" > </property > <conversionRule conversionWord ="clr" converterClass ="org.springframework.boot.logging.logback.ColorConverter" /> <property name ="console.log.pattern.dev" value ="%d{yyyy-MM-dd HH:mm:ss.SSS} - [%thread] - %clr(%-5level) - %clr(%logger{50}){cyan} - %msg%n" /> <property name ="console.log.pattern.prod" value ="%d{yyyy-MM-dd HH:mm:ss.SSS} >>> [%thread] >>> %clr(%-5level) >>> %clr(%logger{50}){cyan} >>> %msg%n" /> <property name ="log.pattern" value ="%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n" /> <appender name ="stdout" class ="ch.qos.logback.core.ConsoleAppender" > <layout class ="ch.qos.logback.classic.PatternLayout" > <springProfile name ="dev" > <pattern > ${console.log.pattern.dev}</pattern > </springProfile > <springProfile name ="!dev" > <pattern > ${console.log.pattern.prod}</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 > 100</MaxHistory > <timeBasedFileNamingAndTriggeringPolicy class ="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP" > <maxFileSize > 100MB</maxFileSize > </timeBasedFileNamingAndTriggeringPolicy > </rollingPolicy > <layout class ="ch.qos.logback.classic.PatternLayout" > <pattern > ${log.pattern}</pattern > </layout > </appender > <logger name ="com.xiang" level ="debug" /> <logger name ="org.springframework" level ="warn" additivity ="false" > </logger > <root level ="info" > <appender-ref ref ="stdout" /> <appender-ref ref ="appLogAppender" /> </root > </configuration >
1.1 logback.xml 和 logback-spring.xml 差别 logback.xml :是直接就被日志框架加载了。
logback-spring.xml:配置项不会被日志框架直接加载,而是由 SpringBoot 解析日志配置文件
logback.xml加载早于application.properties,所以如果你在logback.xml使用了变量时,而恰好这个变量是写在application.properties时,那么就会获取不到,只要改成logback-spring.xml就可以解决。
因为logback-spring.xml是由 SpringBoot 解析日志配置文件,故可以使用SpringBoot 的 Profifile 特殊配置
1.2 使用 Profile 特殊配置 使用日志 Profille 特殊配置, 可根据不同的环境激活不同的日志配置 将 自定义日志配置文件名 logback.xml
改为 logback-spring.xml
修改 日志配置文件中 第38行,如下: 1 2 3 4 5 6 7 8 <layout class ="ch.qos.logback.classic.PatternLayout" > <springProfile name ="dev" > <pattern > ${console.log.pattern.dev}</pattern > </springProfile > <springProfile name ="!dev" > <pattern > ${console.log.pattern.prod}</pattern > </springProfile > </layout >
指定运行环境: --spring.profiles.active=dev
如果使用 logback.xml 作为日志配置文件,还指定 Profile 特殊配置,则会有以下错误
1 2 16:31:30,080 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@39:39 - no applicable action for [springProfile], current ElementPath is [[configuration][appender][layout][springProfile]] 16:31:30,082 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@42:40 - no applicable action for [springProfile], current ElementPath is [[configuration][appender][layout][springProfile]]
配置正确就出现如下打印:
切换日志框架 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > <exclusions > <exclusion > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-logging</artifactId > </exclusion > </exclusions > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-log4j2</artifactId > </dependency >
(1)新建 log4j2.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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 <?xml version="1.0" encoding="UTF-8" ?> <configuration monitorInterval ="5" > <Properties > <property name ="LOG_PATTERN" value ="%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n%xwEx" /> <Property name ="FILE_PATTERN" > %date{yyy-MM-dd HH:mm:ss.SSS} %5p ${sys:PID}} --- [%15.15t] %-40.40c{1.}{cyan} : %m%n%xwEx</Property > <property name ="FILE_PATH" value ="./logfile" /> <property name ="FILE_NAME" value ="springboot-log" /> </Properties > <appenders > <console name ="Console" target ="SYSTEM_OUT" > <PatternLayout pattern ="${LOG_PATTERN}" /> <ThresholdFilter level ="DEBUG" onMatch ="ACCEPT" onMismatch ="DENY" /> </console > <RollingFile name ="RollingFileInfo" fileName ="${FILE_PATH}/info.log" filePattern ="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz" > <ThresholdFilter level ="info" onMatch ="ACCEPT" onMismatch ="DENY" /> <PatternLayout pattern ="${FILE_PATTERN}" /> <Policies > <TimeBasedTriggeringPolicy interval ="1" /> <SizeBasedTriggeringPolicy size ="10MB" /> </Policies > <DefaultRolloverStrategy max ="15" /> </RollingFile > <RollingFile name ="RollingFileWarn" fileName ="${FILE_PATH}/warn.log" filePattern ="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz" > <ThresholdFilter level ="warn" onMatch ="ACCEPT" onMismatch ="DENY" /> <PatternLayout pattern ="${FILE_PATTERN}" /> <Policies > <TimeBasedTriggeringPolicy interval ="1" /> <SizeBasedTriggeringPolicy size ="10MB" /> </Policies > <DefaultRolloverStrategy max ="15" /> </RollingFile > <RollingFile name ="RollingFileError" fileName ="${FILE_PATH}/error.log" filePattern ="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz" > <ThresholdFilter level ="error" onMatch ="ACCEPT" onMismatch ="DENY" /> <PatternLayout pattern ="${FILE_PATTERN}" /> <Policies > <TimeBasedTriggeringPolicy interval ="1" /> <SizeBasedTriggeringPolicy size ="10MB" /> </Policies > <DefaultRolloverStrategy max ="15" /> </RollingFile > </appenders > <loggers > <logger name ="org.mybatis" level ="info" additivity ="false" > <AppenderRef ref ="Console" /> </logger > <Logger name ="org.springframework" level ="info" additivity ="false" > <AppenderRef ref ="Console" /> </Logger > <root level ="info" > <appender-ref ref ="Console" /> <appender-ref ref ="RollingFileInfo" /> <appender-ref ref ="RollingFileWarn" /> <appender-ref ref ="RollingFileError" /> </root > </loggers > </configuration >
(2)在 application.yml
配置文件中引入 log4j2.xml
1 2 logging: config: classpath:log4j2.xml
(3)启动项目,查看控制台及文件输出
有什么问题,欢迎大家留言~
参考源码
小翔SpringBoot 日志介绍lab