springboot中使用application.yml
或者 application.properties
配置文件,就能够简单的配置log日志的打印格式,输出文件名以及路径了。但是如果要求分级别输出,配置日志回滚策略等自定义比较高的操作就需要引入logback-spring.xml
或者logback.xml
;spring官方推荐使用logback-spring.xml
说明:
logback和logback-spring.xml都可以用来配置logback,但是2者的加载顺序是不一样的。logback.xml
> application.properties
> logback-spring.xml
logback.xml
> application.yml
> logback-spring.xml
logback.xml加载早于application.properties,所以如果你在logback.xml使用了变量时,而恰好这个变量是写在application.properties时,那么就会获取不到,只要改成logback-spring.xml就可以解决。但是如果你想使用其他日志框架,要跳过springboot集成的日志框架,那就需要用logback.xml了,还有剔除掉依赖包的引入,这里就不详细说明了。
补充一下各日志框架对应的配置文件
- Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
- Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
- Log4j2:log4j2-spring.xml, log4j2.xml
- JDK (java Util Logging):logging.properties
springboot中使用的是Logback日志框架,暂时不去评论框架的优缺点。官方推荐优先使用带有-spring的文件名作为你的日志配置文件,并且放在src/main/resources下面。这里我们虽然使用了logback-spring.xml
,但是依然不能直接用 ${****}
(例如${spring.application.name}
)来获取application中已经加载的变量,需要使用spring的标签springProperty
引入需要用到的变量,然后再用 ${****}
获取。例如:
<!--读取application.yml中配置的项目id-->
<springProperty scope="context" name="application.name" source="spring.application.name"/>
这里的 source就是application里面的变量名,name是在本xml中的命名,也可以保持跟source一致,本文中做别名以区分。对比普通的property 标签就可以发现springProperty标签的相似之处和区别
<!--自定义项目id-->
<property name="project.name" value="service-feign-promise"/>
下面是Logback日志配置步骤,干货(本文使用的是application.yml
)
1、修改application.yml
spring:
profiles:
active: dev #开发环境
application:
name: service-feign-promise
#日志输出配置
logging:
config: classpath:logback-spring.xml
level:
root: INFO
com.paixi.promise.mapper: DEBUG
org.springframework: INFO
可以看到,日志的配置中,不再配置文件输出路径,多配置了一个config
项,这是引导至logback-spring.xml
中,由此文件负责日志的各种配置。level
项还是要保留的,这里的level不是指记录输出到log文件的级别,是指源码的要输出的级别。
比喻:log文件或者控制台是收货人,源码是发货人。那么这里的level就是决定是否发货,发什么货;而logback-spring.xml
中配置的level
就是决定我们的log文件或者控制台是否收货,收的是什么货。光发货不收货,或者光收货不发货都是不能成功完成交易的。当然了,这里只是个比喻,其原理远比这里复杂,就不多说了。
2、配置logback-spring.xml
先不多说了,先把源码贴出来吧,以表诚意,也是给自己做个笔记以免忘记。哈哈哈
源码中已经注释了许多,在源码的后面也会对一部分的标签作详细的说明,有兴趣的可以移步。也可以在使用的过程中百度或者谷歌一下都可以找到的。
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="org.springframework.web" level="INFO"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--读取application.yml中配置的项目id-->
<springProperty scope="context" name="application.name" source="spring.application.name"/>
<!--自定义项目id-->
<property name="project.name" value="service-feign-promise"/>
<!--开发环境下的日志目录统一配置-->
<property name="dev.log.path" value="D:/prise-logs/${project.name}"/>
<!--测试环境下的日志目录统一配置-->
<property name="test.log.path" value="/usr/local/prise-logs/${project.name}"/>
<!--生产环境下的日志目录统一配置-->
<property name="pro.log.path" value="/usr/local/prise-logs/${project.name}"/>
<!--控制台输出统一定义,各环境下共享-->
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--设置日志输出格式-->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--开发环境,不用输出到文件-->
<springProfile name="dev">
<root level="INFO">
<!--5、输出 level 为 debug 的日志,时间滚动输出 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${dev.log.path}/debug.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${dev.log.path}/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>6KB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 过滤得到debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
</root>
</springProfile>
<!--测试环境-->
<springProfile name="test">
<root level="INFO">
<!--1、输出所有level 日志,时间滚动输出 -->
<appender name="ALL_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${test.log.path}/all.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${test.log.path}/all-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
</appender>
<!-- 5、输出level为 ERROR 日志,时间滚动输出 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${test.log.path}/error.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${test.log.path}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 过滤得到ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
</root>
</springProfile>
<!--生产环境-->
<springProfile name="pro">
<root level="INFO">
<!--1、输出所有level 日志,时间滚动输出 -->
<appender name="ALL_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${pro.log.path}/all.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${pro.log.path}/all-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
</appender>
<!--2、 输出level为 INFO 日志,时间滚动输出 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${pro.log.path}/info.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${pro.log.path}/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 过滤得到info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 3、输出 level 为 debug 的日志,时间滚动输出 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${pro.log.path}/debug.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${pro.log.path}/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 过滤得到debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 4、输出 level为 WARN 日志,时间滚动输出 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${pro.log.path}/warn.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${pro.log.path}/warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 过滤得到warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 5、输出level为 ERROR 日志,时间滚动输出 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${pro.log.path}/error.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${pro.log.path}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>50MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 过滤得到ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
</root>
</springProfile>
</configuration>
附:
1、springProfile
<springProfile name="dev">
..................
</springProfile >
这是spring的专用标签,与springProperty同父异母;主要用以多环境配置,标签的name属性与application中的spring. profiles.active变量值关联,根据不同的值,选择加载不同的配置文件块。
2、rollingPolicy
日志回滚策略配置; logback本身只提供了两种文件的rolling策略:FixedWindowRollingPolicy和 TimeBasedRollingPolicy,另外提供了一种触发器策略SizeBasedTriggeringPolicy。由于log文件记录有回 滚信息,因此我希望能够每一次执行导入程序就产生一个新的log文件并且将原有的log文件进行备份,实际上也就是每次启动程序就roll一下log文 件
TimeBasedRollingPolicy是一个基于日期的回滚策略,可以配置成每天备份一个日志
FixedWindowRollingPolicy是一个很简单的日志滚动策略,每次 触发器触发滚动事件时,则将log滚动一次