Spring Boot实践(二):logback日志配置
1、logback是什么?
工作中一直用的是log4j日志框架,接触了SpringBoot后,因为logback是默认框架,才开始进行了解。
来看下官网的相关介绍。
可以看到,logback是log4j的进化版,是为了替代log4j的。
logback分三个模块:
- logback-core:核心模块,是其他两个模块的基础
- logback-classic:实现了slf4j api,可以和其他实现了slf4j的日志框架切换使用,统一的日志标准,一般都需引用
- logback-access:主要是与Servlet集成的(tomcat、jetty等),提供http访问日志输出
2、为什么要用logback?
logback既然作为Spring Boot的默认框架,是有很多优点的,官网上也有优点说明,这里我截出一部分,
可以看到,优点非常多,内存小、运行速度快、测试充分、相关文档充分、支持XML和Groovy配置、自动加载配置、I/O故障自动恢复、自动删除历史归档日志等等,后面还有很多。
既然这么好,那肯定要用了。
3、logback的使用
各节点属性与log4j的类似,下面配置有比较详细的说明,官网也有相关资料。
由于是配合SpringBoot使用的,我命名的是logback-spring.xml,有SpringBoot解析,下面贴一下我的配置:
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false" scan="true" scanPeriod="60 seconds"> <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --> <!--<property name="log.path" value="../logs" />--> <!--读取application.yml配置文件,log属性配置--> <springProperty scope="context" name="log.path" source="path.log"/> <!-- appender是configuration的子节点,是负责写日志的组件。 --> <!-- ConsoleAppender:把日志输出到控制台 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- 默认情况下,每个日志事件都会立即刷新到基础输出流。 这种默认方法更安全,因为如果应用程序在没有正确关闭appender的情况下退出,则日志事件不会丢失。 但是,为了显着增加日志记录吞吐量,您可能希望将immediateFlush属性设置为false --> <!--<immediateFlush>true</immediateFlush>--> <encoder> <!-- %37():如果字符没有37个字符长度,则左侧用空格补齐 --> <!-- %-37():如果字符没有37个字符长度,则右侧用空格补齐 --> <!-- %15.15():如果记录的线程字符长度小于15(第一个)则用空格在左侧补齐,如果字符长度大于15(第二个),则从开头开始截断多余的字符 --> <!-- %-40.40():如果记录的logger字符长度小于40(第一个)则用空格在右侧补齐,如果字符长度大于40(第二个),则从开头开始截断多余的字符 --> <!-- %logger:输出日志的logger名,可有一个整形参数,如%logger{40},功能是缩短logger名,设置为0表示只输入logger最右边点符号之后的字符串。 --> <!-- %msg:日志打印详情 --> <!-- %n:换行符 --> <!-- %highlight():转换说明符以粗体红色显示其级别为ERROR的事件,红色为WARN,BLUE为INFO,以及其他级别的默认颜色。 --> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%thread] %cyan(%logger) : %msg%n</pattern> <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 --> <charset>UTF-8</charset> </encoder> </appender> <!-- debug 日志--> <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 --> <!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_info.log --> <!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名--> <appender name="debug_log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--日志文件路径和名称--> <File>${log.path}/debug/debug.log</File> <!--是否追加到文件末尾,默认为true--> <append>true</append> <!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。 但是,将拒绝级别低于阈值的事件 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>DEBUG</level><!-- 低于DEBUG级别的日志(TRACE)将被拒绝,等于或者高于DEBUG的级别将相应NEUTRAL --> </filter> <!--有两个与RollingFileAppender交互的重要子组件。 第一个RollingFileAppender子组件,即RollingPolicy:负责执行翻转所需的操作。 RollingFileAppender的第二个子组件,即TriggeringPolicy:将确定是否以及何时发生翻转。 因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候. 作为任何用途,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,但是,如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 --> <!-- 文件名:logs/project_info.2017-12-05.0.log --> <!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 --> <fileNamePattern>${log.path}/debug/debug.%d.%i.log</fileNamePattern> <!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天 如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd--> <maxHistory>30</maxHistory> <!-- 每个日志文件到2mb的时候开始切分,最多保留30天,但最大到500MB,哪怕没到30天也要删除多余的日志 --> <totalSizeCap>500MB</totalSizeCap> <!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成5KB看效果 --> <maxFileSize>4MB</maxFileSize> </rollingPolicy> <!--编码器--> <encoder> <!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%thread] %logger : %msg%n</pattern> <!-- 记录日志的编码:此处设置字符集 - --> <charset>UTF-8</charset> </encoder> </appender> <!-- info 日志--> <appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>${log.path}/info.log</File> <append>true</append> <!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。 但是,将拒绝级别低于阈值的事件 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level><!-- 低于INFO级别的日志(TRACE,DEBUG)将被拒绝,等于或者高于INFO的级别将相应NEUTRAL --> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/info.%d.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <totalSizeCap>400MB</totalSizeCap> <maxFileSize>2MB</maxFileSize> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%thread] %logger : %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- warn 日志--> <appender name="warn_log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>${log.path}/warn/warn.log</File> <append>true</append> <!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。 但是,将拒绝级别低于阈值的事件 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>WARN</level><!-- 低于WARN级别的日志(TRACE,DEBUG,INFO)将被拒绝,等于或者高于WARN的级别将相应NEUTRAL --> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/warn/warn.%d.%i.log</fileNamePattern> <maxHistory>30</maxHistory> <totalSizeCap>100MB</totalSizeCap> <maxFileSize>2MB</maxFileSize> </rollingPolicy> <!--编码器--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%thread] %logger : %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- error 日志--> <appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>${log.path}/error/error.log</File> <append>true</append> <!-- 此日志文件只记录ERROR级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${log.path}/error/error.%d.%i.log</fileNamePattern> <maxHistory>60</maxHistory> <totalSizeCap>50MB</totalSizeCap> <maxFileSize>2MB</maxFileSize> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%thread] %logger : %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!--给定记录器的每个启用的日志记录请求都将转发到该记录器中的所有appender以及层次结构中较高的appender(不用在意level值)。 换句话说,appender是从记录器层次结构中附加地继承的。 例如,如果将控制台appender添加到根记录器,则所有启用的日志记录请求将至少在控制台上打印。 如果另外将文件追加器添加到记录器(例如L),则对L和L'子项启用的记录请求将打印在文件和控制台上。 通过将记录器的additivity标志设置为false,可以覆盖此默认行为,以便不再添加appender累积--> <!-- configuration中最多允许一个root,别的logger如果没有设置级别则从父级别root继承 --> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="debug_log" /> <appender-ref ref="info_log" /> <appender-ref ref="warn_log" /> </root> <!-- 关闭日志 --> <!--<logger name="org.springframework.boot" level="OFF"/>--> <!--开发环境:打印控制台--> <!-- <springProfile name="dev"> <logger name="com.talking" level="debug"/> </springProfile>--> <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 --> <!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE --> <!--<logger name="com.sailing.springbootmybatis" level="INFO"> <appender-ref ref="info_log" /> <appender-ref ref="error_log" /> </logger>--> <!-- additivity=false代表禁止默认累计的行为,即com.atomikos中的日志只会记录到日志文件中,不会输出层次级别更高的任何appender--> <!--<logger name="com.atomikos" level="INFO" additivity="false"> <appender-ref ref="info_log" /> <appender-ref ref="error_log" /> </logger>--> </configuration>
至此,debug、info、warn、error等相关日志配置大功告成了!