logback配置文件详解
<?xml version="1.0" encoding="UTF-8"?>
<!-- 根节点 , logback的全局配置 , 包含3个属性
scan : 当文件发生变更时是否重载 , 默认值ture
scanPeriod : 监测文件的间隔时间 , 即每隔多少时间扫描一次配置文件 仅当scan=true时生效. 默认间隔时间1min , 如果不写单位默认是毫秒;
debug : 是否为debug模式 , 为true时会打印出logack内部日志 , 便于查看logback实时信息 . 默认值false
-->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 上下文名称 , 每个logger都关联到上下文 , 默认值为default . 设置之后不可动态修改 -->
<contextName>logback</contextName>
<!-- 定义变量 , 在配置文件其他地方可通过${变量名}访问 -->
<property name="appName" value="xdemo"/>
<!-- 内部变量 , 获取时间戳字符串 . key为变量名 , datePattern为解析的日期字符串格式 , 与SimpleDateFormat格式相同 -->
<timestamp key="time" datePattern="yyyyMMdd HHmmss"/>
<!-- 日志输出组件 有两个必须的属性
name : 当前appender的名称 , 在logger组件中相关联
class : 日志的输出控制类 , 通过class将日志输出到控制台/文件/远程socket服务器/数据库等
不同的class有着不同的配置
-->
<!-- ConsoleAppender , 将日志输出到控制台 . 有encoder和target两个子节点(新版本有filter子节点 , 在下文中详细说明) -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 子节点encoder , 指定日志输出的格式 , 具体格式配置见下方表格 -->
<encoder>
<pattern>%d{HH:mm:ss} [%thread][%X{traceId}] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<!-- 子节点target , 日志输出的对象 System.out 或 System.err -->
<target></target>
</appender>
<!-- FileAppender , 将日志输出到文件 . 有file/append/encoder/prudent四个子节点(新版本有filter子节点 , 在下文中详细说明) -->
<appender name="file" class="ch.qos.logback.core.FileAppender">
<!-- 子节点file , 输出的目标文件名 , 父级目录不存在会自动创建 . 无默认值 -->
<file>xdemo.log</file>
<!-- 子节点append , 是否为追加模式 . 为true则日志被追加到文件末尾 , false则清空现文件重新写入 . 默认值true -->
<append>true</append>
<!-- 子节点encoder , 指定日志输出的格式 -->
<encoder>
<pattern>%d{HH:mm:ss} [%thread][%X{traceId}] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<!-- 子节点produent , 是否为安全写入模式 . 为ture则日志会被安全的写入文件 , 即使其他FileAppender同时做写入操作 , 效率低 . 默认值false -->
<prudent>true</prudent>
</appender>
<!-- RollingFileAppender , 将日志动态输出到文件 . 通过clas指定策略 , 符合某个策略时 , 会自动创建新日志文件并输出(按日期/大小等) . 有file/append/rollingPolicy等几个节点 -->
<!-- RollingFileAppender详细配置参见下文 -->
<!-- logger 日志返回/级别及输出目标配置 有必填属性name和选填属性level/additivity , 一个appender-ref 子节点(可配置1个或多个)
name : 指定遵守该logger约束的一个包或具体的某个类
level : 日志级别 ,有以下值TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF , 不区分大小写
additivity : 是否向上级logger传递日志信息 , 默认为ture . (如果上级logger也输出日志 , 则会输出两份 . 所以通常情况下配置为false)
-->
<logger name="org.springframework" level="INFO" additivity="false">
<appender-ref ref="console"/><!-- 输出到相关联的appender中 -->
<appender-ref ref="file"/>
</logger>
<!-- 更多常用的三方框架logger配置见下文 -->
<!-- root本身也是一个logger节点(相当于name="root"的logger) , 但仅能配置一个 , 是所有logger的父级(可以理解为Java中的Object) , 只有一个level属性, 默认值DEBUG -->
<root level="error">
<appender-ref ref="console"/>
<appender-ref ref="file" />
</root>
</configuration>
RollingFileAppender详细配置
<!-- RollingFileAppender详细配置
其中有file/append/pruduent几个通用节点 , 不再详述 .
具体讲一下rollingPolicy节点相关 , 该节点通过class属性指定不同的配置指定RoolingFileAppender的动态行为 , 涉及日志文件的移动/重命名等
-->
<!-- TimeBasedRollingPolicy 最常用的动态策略 , 根据时间来分割日志 主要有fileNamePattern和maxHistory子节点 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 子节点fileNamePattern : 文件目录表达式 , 包含文件名及%d转换表达式 , %d可以包含一个SimpleDateFormat格式的日期字符串 , 如"yyyyMMdd" , 如省略直接写%d则默认为"yyy-MM-dd", 则按照日期自动分割每天产生的日志
配置该节点后 , RollingFileAppender的file节点可有可无 , 如果同时配置了两个节点的话 , 日志文件会归档为两套(一套按日期分割 , 一套整个写入file指定的文件) -->
<fileNamePattern>/data/logs/%d/xdemo_%d{yyMMdd}.log</fileNamePattern>
<!-- 子节点maxHistory : 非必填节点 , 控制历史归档的最大数量 , 超出该配置则删除旧文件 . 如果配置按天归档且maxHistory为30 , 则只保存最近30天的日志文件(包括为该文件而创建的目录) -->
<maxHistory>30</maxHistory>
<!-- 子节点totalSizeCap , 在 1.1.6版本后才开始支持, 配置总日志文件的大小上限 -->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<!-- SizeBasedTriggeringProlicy 根据大小来分割日志 , 只有一个专属子节点maxFileSize -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<file>/data/logs/xdemo.log</file>
<!-- 单个日志的大小上限 , 超出该上线则新建日志(后缀名_1/2/3)继续写入 -->
<maxFileSize>500MB</maxFileSize>
</rollingPolicy>
<!-- SizeAndTimeBasedRollingPolicy 综合时间和大小分割 , 单个时间段内超过大小继续分割 -->
<!-- ?FixedWindowRollingPolicy 根据固定窗口算法分割文件? -->
常用的三方框架logger配置
<!-- 常用的三方框架logger配置 -->
<!-- myBatis/JDBC 日志 -->
<logger name="com.apache.ibatis" level="DEBUG"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- hibernate日志 -->
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="DEBUG" />
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
filter详细配置
<!-- filter: 日志过滤器 , 可以过滤不符合规则的内容 , 使之不输出到控制台或文件 , 为appender的子节点
logback过滤器是基于Ternary Logic, 允许多个过滤器搭配使用 , 配置多个过滤器时按照书写顺序依次执行
执行一个过滤器会返回以下几个枚举值
ACCEPT: 该日志符合规则 , 接受处理 . 同时不会再经过其他过滤器
NEUTRAL: 当前过滤器不处理 , 下个过滤器继续处理
DENY: 该日志将被过滤抛弃 , 且不再经过其他过滤器
-->
<appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- ...其他配置略... -->
<!-- LevelFilter: 级别过滤器; 过滤掉非配置等级的日志 , 只有等于当前级别时才会处理 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch><!-- 匹配等级的返回值 -->
<onMismatch>DENY</onMismatch><!-- 不匹配的返回值 -->
</filter>
<!-- ThresholdFilter: 阀值过滤器; 过滤掉低于阀值的日志 , 当日志级别等于或高于阀值 , 过滤器返回NEUTRAL , 否则直接返回DENY -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- EvaluatorFilter: 条件过滤器; 评估鉴别日志是否符合指定条件 , 有一个主要的evaluator(鉴定器)子节点 -->
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<!-- 过滤器 -->
<evaluator> <!-- 默认为 ch.qos.logback.classic.boolex.JaninoEventEvaluator -->
<expression>return message.contains("xinfo");</expression><!-- 布尔表达式 , 还有一种正则表达式的形式 -->
</evaluator>
<OnMatch>ACCEPT</OnMatch>
<OnMismatch>DENY</OnMismatch>
</filter>
</appender>
日志输出格式详细说明
参数 | 说明 | 示例 |
---|---|---|
c{length} lo{legnth} logger{length} | 输出日志的logger , length缩短logger名 , 设置为0表示只输入logger最右边点符号之后内容(从左开始缩短 ,每个层级至少保留1位) | 完整logger名 : cn.xbz.test.HelloController %logger : cn.xbz.test.HelloController %logger{0}: HelloController %logger{5}: c.x.t.HelloController %logger{20}: c.x.test.HelloController
|
C{length} class{length} | 输出当前调用者的全名(包名+类名) , 参数与上面一致 , 效率不高 , 尽量避免使用 | %class |
contextName cn | 输出xml中配置的上下文名称 | %contextName |
d{pattern} date{pattern} | 输出当前的时间 , 字符串语法与SimpleDateFormat相同 | %d : 2019-01-10 10:01:10,816 %date : 2019-01-10 10:01:10,816 %date{HH:mm:ss.SSS} : 10:01:10,816 %date{yyyy-MM-dd hh:mm:ss} : 2019-01-10 10:01:10 |
F file | 输出日志写入目标的文件名 , 尽量避免使用 | %file |
caller{depth} caller{depth, evaluator-1, ... evaluator-n} | 当前调用者的位置信息 | ? |
L line | 输出日期请求的行号 , 尽量避免使用 | %line |
m msg message | 输出日志信息(必用) | %message |
M method | 当前执行日志请求的方法名 , 尽量避免使用 | %method |
n | 输出平台相关的换行符("\n" 或 "\r\n") | %n |
p le level | 输出日志级别(TRACE/DEBUG/INFO/WARN/ERROR/FATAL) | %level |
r relative | 输出自程序启动到创建日志记录的时间 , 单位毫秒 | %relative |
t thread | 输出调用日志的线程名 | %thread |
replace(p){r,t} | 替换输出内容 , p为日志内容 , r是正则表达式 , 将p中符合r的内容替换为t | %replace(%msg){'\s',''} |
日志格式修饰符
可选的格式修饰符位于“%”和转换符之间。(%-5level / %.6logger)
第一个可选修饰符是左对齐 标志,符号是减号“-”;接着是可选的最小宽度 修饰符,用十进制数表示。如果字符小于最小宽度,则左填充或右填充,不填符号默认是左填充(即右对齐),填充符为空格。如果字符大于最小宽度,字符永远不会被截断。最大宽度 修饰符,符号是点号"."后面加十进制数。如果字符大于最大宽度,则从前面截断。点符号“.”后面加减号“-”在加数字,表示从尾部截断。
例如:%-4relative 表示,将输出从程序启动到创建日志记录的时间 进行左对齐 且最小宽度为4