vlambda博客
学习文章列表

Just Do IT,你的SpringBoot日志输出格式,由你来定!

LogBack是默认集成在SpringBoot里面的,是基于Slf4j的日志框架。默认情况下,SpringBoot是按照INFO级别输出到控制台的。

日志级别顺序如下:

ALL < TRACE < DEBUG < INFO < WARN < ERROR < OFF

在实际项目中,通常需要将日志信息落盘保存,因此需要添加对应配置文件。

SpringBoot中Logback配置

1 添加自定义的配置文件

LogBack可以直接在application.propertiesapplication.yml中配置,但仅支持一些简单的配置,复杂的文件输出还是需要配置在 xml 配置文件中。

有两种选择:

1、使用固定的logback-spring.xml作为名称,无需额外配置即可

logback启动时会尝试在classpath目录中查找logback-test.xml文件;如果文件不存在,则查找logback.xml文件;如果还不存在,则会自动配置,使用默认配置。

SpringBoot结合时,官方推荐使用的xml名字的格式为:logback-spring.xml而不是logback.xml,因为带spring后缀的可以使用 这个标签。

所以,在resource下创建logback-spring.xml文件,然后在此xml中进行配置,即可。

2、使用自定义的配置文件名称,需要额外的指定日志配置的文件路径信息

如果没有使用上面1中提及的默认名称,则需要在配置文件中指定需要加载的日志配置文件路径名称。示例如下


Just Do IT,你的SpringBoot日志输出格式,由你来定!


2 Logback配置文件示例与含义解说

LogBack配置中可以对日志输出情况做一些个性化的定制,主要支持如下能力:

1.支持读取application.yml或者application.properties中的属性;2.支持根据不同的spring profile类型,实现不同的log输出配置;3.支持日志输出到文件中根据级别进行的过滤;4.支持日志文件的绕接、定时备份、超时清理、超限清理等机制;5.支持日志输出内容的定制。

各种关键配置的配置方式以及含义说明,参见如下的一个配置示例,注释上有详细的说明。

对于pattern的含义说明,详细信息可以参见http://logback.qos.ch/manual/layouts.html说明。

<?xml version="1.0" encoding="UTF-8"?><!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --><!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true --><!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。--><!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。--><configuration scan="true" scanPeriod="10 seconds"> <!-- ERROR日志格式,后面在对应的appender定义中指定pattern为此值,即可以按照此处的日志格式进行输出 --> <property name="FILE_ERROR_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} %file:%line: %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 彩色日志 --> <!-- 彩色日志依赖的渲染类 --> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式,后面在对应的appender定义中指定pattern为此值,即可以按照此处的日志格式进行输出 --> <!-- 默认情况下, 自带的CONSOLE_LOG_PATTERN属性,即为彩色的,此处重新定义了个新的属性,用于演示彩色控制台的使用示例--> <property name="CONSOLE_LOG_PATTERN_COLOR" 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{0}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 解说下具体的pattern中属性的含义,详细参见http://logback.qos.ch/manual/layouts.html--> <!-- %logger{x},或者写为%c{x},表示类名信息,如果x为0则表示仅输出类名,如果x大于0则尝试输出全路径,并按照指定的x值进行缩写。 比如com.test.sample.Main 设置%logger{0}为Main 设置%logger{5}可缩写为c.t.s.Main 设置%logger{20}为com.test.sample.Main--> <!-- %d表示日期信息(或者%date),默认格式为【yyyy-MM-dd HH:mm:ss,SSS】,可以通过%d{x}自定义格式,比如%d{yyyy-MM-dd HH:mm:ss.SSS}--> <!-- %p表示日志的level,或者%le\%level--> <!-- %L表示相对应的行号,或者%line--> <!-- %m表示实际的需要输出的日志内容字符串,或者%msg\%message都可以--> <!-- %replace(p){r,t}表示对p中给定的内容进行字符串替换,将r替换为t,支持正则,比如将p中的换行替换为下划线,防止日志攻击--> <!-- %M表示方法名称,或者%method也可以--> <!-- %t表示线程名称,或者%thread也可以--> <!-- %ex{x}用于指定错误异常堆栈的打印策略,x可以为short\full或者具体数字,表示打印多少行堆栈--> <!-- %n表示换行--> <!-- 字符串对齐、截取、格式化说明: 在上述的各个占位符中,在%和具体字符之间,可以插入格式化指令,以%c为例,如下: %20c 表示%c的内容如果不足20位,则在左侧以空格填充满20长度 %-20c 与%20c相似,区别在于,会在右侧以空格填满20长度 %.20c 表示%c内容如果超过20,则会截取掉开头的内容,只留下右侧20位长度 %.-20c 与%.20c相似,区别在于,会截取掉末尾的内容,只留下开头20位长度 以此类推,还可以组合出如下使用方式: %20.30c 表示最短20位,最长30位,如果不足20位则左侧补齐空格,如果超过30位则丢弃左侧开头的字符串 %-20.30c 和%20.30c类似,区别在于不足20位的时候,在右侧补齐空格 %-20.-30c 和%-20.30c类似,区别在于超过30位的时候会丢弃结尾部分的字符串 %20.-30c 20.30c类似,区别在于超过30位的时候会丢弃结尾部分的字符串 -->
<property name="SELF_DEFINE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%5.5p] [%5.10t] [%30.30c{0}.%20.20M:%4.4L] -> %replace(%.-300m){'\r\n','__'}%ex{full}%n"/>
<!-- Spring Boot 提供了一个默认的 xml 配置,可以按照如下方式引入 --> <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!-- 引入application.yml配置文件,后续可以直接引用里面的属性值--> <!-- 注意:在此文件中直接${}的方式引用application.yml里面配置可能会报错. 因为logback.xml的加载顺序早于springbootapplication.yml (或application.properties) 配置文件。 所以可以先springProperty的方式定义个本地变量引入进来,再进行引用此本地变量--> <!-- 可以将一些公共的内容放到application.yml里面去配置,然后此文件中引用,后续可以避免修改此xml,简单的参数直接修改下application.yml就行了--> <!-- 比如将日志存放路径与文件大小信息从配置中读取,这样dev和prod可以指定不同的逻辑--> <property resource="application.yml"/> <springProperty scope="context" name="LOG_HOME" source="selfdefine.logfile.rootPath"/> <springProperty scope="context" name="LOG_FILE_SIZE" source="selfdefine.logfile.max-size"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> </filter>
<!-- 指定此append对应的日志内容的格式--> <encoder> <pattern>${CONSOLE_LOG_PATTERN_COLOR}</pattern> <charset>UTF-8</charset> </encoder>
</appender>
<appender name="CONSOLE2" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> </filter>
<!-- 指定此append对应的日志内容的格式--> <encoder> <pattern>${SELF_DEFINE_LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder>
</appender>
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高, 所以我们使用下面的策略,可以避免输出 Error 的日志--> <!-- 指定过滤的日志级别,并可以额外指定是拒绝还是允许。如果仅配置了level属性,则表示只有高于等于level的值才会记录,其余丢弃(参考下面FILE_ERROR对应appender)--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!--过滤 Error--> <level>ERROR</level> <!--匹配到就禁止--> <onMatch>DENY</onMatch> <!--没有匹配到就允许--> <onMismatch>ACCEPT</onMismatch> </filter> <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则如果同时有<File>和<FileNamePattern>,那么 当天日志是<File>,明天会自动把今天的日志改名为今天的日期。即,<File> 的日志都是当天的。--> <!--<File>logs/info.spring-boot-demo-logback.log</File>--> <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--文件路径,支持相对路径或者绝对路径(尽量避免相对路径,通过绝对路径保证存储位置的固定),定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间--> <!-- 指定文件的路径以及对应的文件命名格式,其中%i表示递增标识ID序号,日志切换绕接的时候递增--> <FileNamePattern>${LOG_HOME}/spring-boot-demo-logback/info_%d{yyyy-MM-dd}.part_%i.log</FileNamePattern> <!--只保留最近90天的日志--> <maxHistory>90</maxHistory> <!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志--> <!--<totalSizeCap>1GB</totalSizeCap>--> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 --> <!--此处演示从application.yml中读取配置的属性值,通过${}的方式引用--> <maxFileSize>${LOG_FILE_SIZE}</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <!--<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">--> <!--<maxFileSize>1KB</maxFileSize>--> <!--</triggeringPolicy>-->
<!-- 指定此append对应的日志内容的格式--> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> </appender>
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter--> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <!-- 指定过滤的日志级别,只有等于或者高于此级别的,才会通过此appender进行输出--> <level>Error</level> </filter> <!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天的日志改名为今天的日期。即,<File> 的日志都是当天的。--> <!--<File>logs/error.spring-boot-demo-logback.log</File>--> <!--滚动策略,按照时间滚动 TimeBasedRollingPolicy--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间--> <FileNamePattern>logs/spring-boot-demo-logback/error.created_on_%d{yyyy-MM-dd}.part_%i.log</FileNamePattern> <!--只保留最近90天的日志--> <maxHistory>90</maxHistory> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <!-- maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 --> <maxFileSize>2MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy>
<!-- 指定此append对应的日志内容的格式--> <encoder> <pattern>${FILE_ERROR_PATTERN}</pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> </appender>
<!-- 指定日志输出到哪些位置、以及root日志的输出level--> <!-- 默认情况下的使用,任何spring profile值情况下都会使用下面的配置,即输出到console中--> <root level="info"> <appender-ref ref="CONSOLE2"/>
</root>
<!-- 在SpringBoot中,可以通过springProfile属性来实现在不同环境上执行不同的输出策略,如下示例中指定prod和dev上有不同的策略--> <!-- 指定在prod环境使用的输出配置--> <springProfile name="prod"> <root level="info"> <appender-ref ref="FILE_ERROR"/> </root> </springProfile>
<!-- 指定在dev环境使用的输出配置--> <springProfile name="dev"> <root level="info"> <appender-ref ref="FILE_INFO"/> <appender-ref ref="FILE_ERROR"/> </root> </springProfile></configuration>

上面的示例xml中引用的一个application.yml中的属性定义如下:

3 LogBack与Log4j的区别

LogBack是基于SLF4j(Simple Logging Facade for Java)实现的日志框架,各方面性能相比Log4j要更优一些。

LogBackLog4j是非常相似的,LogBack的内核重写了,在一些关键执行路径上性能提升10倍以上。而且LogBack不仅性能提升了,初始化内存加载也更小。

在使用LogBack的时候,不需要在代码中或配置文件中指定你打算使用哪个具体的日志系统,因为SLF4J提供了统一的记录日志的接口,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过具体日志系统的配置来实现,因此可以在应用中灵活切换日志系统。

推荐使用SLF4j/LogBack替换Log4j作为日志打印框架。




引用链接