使用logback的原因
项目中使用的最多的日志记录框架,有log4j、logback,logback是log4j的创始人对log4j的一个优化,logback对于log4j的优势就不记录了
logback基础
logback分成了三个模块:logback_core,logback_classic,lgoback_access三个模块组成。
logback_core是其他两个模块的基础,提供了核心原件的接口和实现;
logback_classic实现了slf4j API,因此可以将logback将其他slf4j的实现进行替换,而不需要修改代码;
lgoback_access提供了在web容器中http-access日志功能的实现
一般工程中pom依赖需要引入的jar包如下
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
logback配置
当使用logback时,logback通过如下几种方式读取配置启动:
- 从系统配置文件System Propertis中寻找logback.configurationfile对应的value
- 在工程的classpath下寻找logback.groovy(logback支持通过groovy来配置,更直观)
- 在classpath下寻找logback-test.xml
- 在classpath下寻找logback.xml
对上述四个地址进行依次扫描,任何一个地址扫描到了配置文件后就不再继续扫描,如果在这四个地方都没有扫描到配置文件,logback会调用方法自己创建配置来输出日志至控制台(调用ch.qos.logback.classic.BasicConfigurator的configure方法,构造一个ConsoleAppender用于向控制台输出日志,默认日志输出格式为”%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} – %msg%n”)
在这里我们只学习logback.xml的配置方法,logback的配置基础标识是< configuration />标签
< configuration />标签
它只有三个属性:scan、scanPeriod、debug
- scan:属性为true/false,当标志位true时,配置文件修改,会被重新载入
- scanPeriod:检测配置文件修改的时间,默认单位为毫秒,当scan配置为true时,默认检测时间为一分钟
- debug:属性为true/false,true会打印logback内部日志记录
<configuration scan="true" scanPeriod="60 seconds" debug="false">
</configuration>
configuration 标签下 还有三个标签:root、logger、appender三种子节点,下面介绍这三种标签
< root />标签
根logger标签,他只有level属性,level总共有五个级别:TRACE、DEBUG、INFO、WARN、ERROR,配置level后就输出大于等于该级别的日志。其中也可以配置一个或多个的appender子节点,用来配置日志输出的格式
<root level = "debug" >
</root>
< logger />标签
普通的logger标签,除了level属性之外,他还有name、additivity两个属性
- level:日志打印的级别设置,若不设置会默认获取上一级的level属性
- name:用来指定该logger约束的一个类或者包,即该logger只会打印类或包路径下的日志
- additivity:布尔值,决定是否向上级传递日志信息,不填默认为true
上述三个属性举个例子
<root level = "warn">
<appender-ref ref = "appender1" />
</root>
<logger name = "java.lang" additivity = "true">
</logger>
<logger name = "java" level = "debug" additivity = "false">
<appender-ref ref = "appender2" />
</logger>
如果按上述配置时,有一个java.lang包下的类异常时,会已经以下几步:
- 首先会先找到name = “java.lang”的logger(下面简称langLogger),但langLogger没有配置level;
- 默认获取上一级即name = “java”(下面简称javaLogger)的日志打印级别即debug,即langLogger可以输出debug及以上的日志;
- langLogger没有配置日志输出格式appender,所以无输出,additivity配置为true即向上级javaLogger传输日志信息;
- javaLogger根据level和appender,按appender2日志格式输出大于等于debug的日志;
- javaLogger的additivity为false,即父节点root无法获取到日志,日志打印结束
< appender />标签
这个标签用来配置日志打印的详细配置,他有两个属性:name、class
- name即指定appender的名称,logger引用时用的就是这个值
class即指定apperder的全限定名,指定打印日志的实现
举一个简单的例子:
<appender name = "demo" class = "ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss:SSSXXX} - %msg%n</pattern>
</encoder>
</appender>
上面这个例子中这个appender的引用名称即demo,class中的ConsoleAppender会将日志打印到控制台,其中的encoder这个节点配置日志输出的格式,其中的%d即输出日志信息,{}中定义了日期的格式,%msg即输出异常信息,打印出的消息格式如下:
2018-06-04T15:27:51:724+08:00 - error输出
encoder标识对参数进行格式化,老版本的logback的为layout,0.9.19版本后引进了encoder,现在的版本两种都可用,不过建议使用encoder进行日志的配置。
class中常用的有FileAppender,这个是负责将日志输出到文件中,简单里配置例子如下:
<appender name = "demo" class = "ch.qos.logback.core.FileAppender">
<File>D:/demo.log</File>
<append>true</append>
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss:SSSXXX} - %msg%n</pattern>
</encoder>
</appender>
- file配置了输出的文件地址
- append属性为true时是默认将新的日志追加在文件的末尾,为false时会清空文件
- encoder即日志参数的格式化
- prudent如果为true表示日志会被安全地写入文件,即使其他的FileAppender也在向此文件做写入操作,效率低,默认为false
另一种常用的时RollingFileAppender,应该是项目日志中最常用的,可以实现滚动记录日志,先将日志记录到对应的文件中,当符合一定条件后再将日志迁移到其他文件,举一个使用的例子:
<!-- ERROR日志 (文件最大25M,最多10个) -->
<appender name="demo" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>rolling-file-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss:SSSXXX} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
上面的例子中使用了RollingFileAppender,其中上面的TimeBasedRollingPolicy是最常用的滚动策略,它根据时间指定滚动策略,既负责滚动也负责触发滚动
- fileNamePattern:必要节点,包含文件名及”%d”转换符,”%d”可以包含一个Java.text.SimpleDateFormat指定的时间格式,如%d{yyyy-MM},如果直接使用%d那么格式为yyyy-MM-dd。
- maxHistory:最大保存的文件数量,上述的例子中,也就是最多保存30天的日志
appender中还有一个子节点filter,会在当前logger的日志级别上再进行一次筛选,最基本的Filter有ch.qos.logback.classic.filter.LevelFilter和ch.qos.logback.classic.filter.ThresholdFilter两种,这两种的配置方式如下:
<!--LevelFilter配置-->
<appender>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--ThresholdFilter配置-->
<appender>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
</appender
- LevelFilter的配置只会打印WARN级别的日志,因为在filter中对匹配到WARN级别时做了ACCEPT(接受),对未匹配到WARN级别时做了DENY(拒绝)
- ThresholdFilter的配置对小于level的日志进行全过滤,只会打印出WARN及以上的体质信息