logback使用说明

一、概述

        记得前些年项目中的日志记录,最开始用的是log4j。对一般的项目使用还算可以,肯定谈不上很好,但还是可以勉强用的。后来有了log4j 2、commons logging、slf4j、logback等日志框架。但slf4j不是具体的日志实现框架,而是提供了常用的日志接口,在使用的时候我们可以直接调用其接口,通过使用提供的,隐藏了日志的具体实现。logback则提供了日志记录的功能。

        logback使用说明


二、logback介绍

        logback的性能比log4j更好,在某此操作上,其性能得到了显著的提升。log4j和logback源自同一个作者,但logback是log4j的升级,所以logback自然比log4j有很多优秀的地方。不过logback和log4j是比较相似的,如果你对log4j很熟悉或者使用过log4j,那对logback就能很快的应用起来。下面列出一部分logback的优点:

        2.1,logback原生实现了slf4j的api

        logback-classic实现了slf4j,但我们感觉不到logback-classic。如果我们要改用log4j会很容易,换相应的jar就好,不需要去更改slf4j的api实现。

        2.2,支持xml、Groovy方式进行配置

        2.3,支持配置文件中加入条件判断

        通过在配置文件中加入条件判断,会增加灵活度,以处理不同的情况。比如通过<if>、<then>和<else>来配置日志适用于不同的环境中,一个配置文件可以用到开发、测试、生产、演示环境中。当然也可以一个环境写一个配置文件。

        2.4,更为强大的过滤器

        比如在诊断某一问题时,需要打出日志。对log4j只有降低日志级别,但这样打打印出很多不需要的日志,同时也影响性能。对logback,可以继续保持日志级别,然后除掉某种特殊的情况。在使用中,可以针对不同用户的登陆打印不同级别的日志,而且配置也不复杂,可参考MDCFilter。

        2.5,更充分的测试

        到目前为此,logback发展已经有些年了,经受住了广大用户的测试。

        2.6,丰富的免费文档

        官网上有很多文档,另外也有许多同行写的一些使用说明文档可供参考。

        2.7,自动重载有变更的配置文件

        当配置文件有了修改,logback-classic可以自动重新加载配置文件。扫描的过程快而且安全,它并不需要重新创建一个扫描线程。可通过<configuration>标签的scan和scanPeriod来配置。

        2.8,自动压缩历史日志

        RollingFileAppender在产生新日志文件时,自动压缩日志。同时压缩是个异步的过程,在压缩的过程中,并不会影响应该的使用。

        2.9,打印异常信息时自动包含package名称及版本号

        2.10,快速实现

        logback的内核进行了重写,在一些地方性能有明显的提升,且初始化内存的加载也更小了。

        2.11,自动去除旧的日志文件

        可以控制历史日志文件的保留时间,如果过期了会被清除。此功能涉及<maxHistory>标签。

        2.12,SiftingAppender

        SiftingAppender可以根据给定的一个运行参数来分割日志文件。比如可以区别日志事件,跟进用户的session,可根据要求一个用户产生一个日志文件。

        2.13,Lilith

        Lilith是log事件的观察者,是logback的logging和AccessEvent查看工具,目录已经更新到8.1以上了。和log4j的chainsaw类似。面Lilith还可处理大数量的log数据。      

        2.14,谨慎的模式和非常友好的恢复

        在谨慎模式下,多个FileAppender实例跑在多个JVM下,能够安全的写进同一个日志文件中。RollingFileAppender会有些限制。logback的FileAppender和它的子类包括RollingFileAppender能够非常友好的从I/O异常中恢复。


三、logback配置介绍

        3.1,logback配置文件结构

        根节点为<configuration>标签,其子节点有Appender、Logger、Root。如下图所示。

          logback使用说明

        3.2,标签与属性解释说明

        下面对logback配置的部分标签及标签属性进行解释说明。

标签或属性名 解释说明
<configuration> 配置的根节点
--scan 为ture时,若配置文件属性改变会被扫描并重新加载,默认为true
--scanPeriod 监测配置文件是否有修改的时间间隔,若没给出时间单位,默认单位为毫秒;默认时间为1分钟;当scan="true"时生效
--debug

为true时,将打出logback的内部日志信息,实时查看logback运行状态;默认值为false

<contextName> 上下文名称,默认为“default”,使用此标签可设置为其它名称,用于区分不同应用程序的记录;一旦设置不能修改
<appender> <configuration>的子节点,负责写日志的组件,有name和class两个必要属性
-name addender的名称
-class appender的全限定名,就是对应的某个具体的Appender类名,比如ConsoleAppender、FileAppender
-append 为true地,日志被追加到文件结尾,如果是flase,清空现存的文件,默认值为true


        3.3,默认规则

        日志级别为:TRACE < DEBUG < INFO < WARN < ERROR。

        如果logback-test.xml和logback.xml都不存在,logback默认地调用BasicConfigurator,然后创建一个最小化的配置。此配置由一个关联到根logger的ConsoleAppender组成,输出结果使用模式为%d{HH:mm:ss.SSS} [%thread] % -5level %logger{36} -%msg %n的PatternLayoutEncoder进行格式化。默认的级别为DEBUG。

        3.4,格式化参数说明        

        在日志的pattern中,%d表示日期,%thread表示线程名,%-5level表示日志级别从左显示5个字符内容,%msg表示日志消息内容,%n表示换行。它们一起配合使用对日志的输出内容进行格式化。下面举例说明。

        %d{yyyy-MM-dd HH:mm:ss.SSS},表示对时间进行按照yyyy-MM-dd HH:mm:ss.SSS格式进行格式化输出,例如2017-07-07 12:07:07.222;

Conversion Pattern Result
%d 2006-10-20 14:06:49,812
%date 2006-10-20 14:06:49,812
%date{ISO8601} 2006-10-20 14:06:49,812

        %thread和%-5level觉得没什么可以说的;

        %logger{36}表示logger名称最长为36个字符,如果不够36就是有多少就显示多少;

Conversion specifier Logger name Result
%logger mainPackage.sub.sample.Bar mainPackage.sub.sample.Bar
%logger{0} mainPackage.sub.sample.Bar Bar
%logger{5} mainPackage.sub.sample.Bar m.s.s.Bar
%logger{10} mainPackage.sub.sample.Bar m.s.s.Bar
%logger{15} mainPackage.sub.sample.Bar m.s.sample.Bar
%logger{16} mainPackage.sub.sample.Bar m.sub.sample.Bar
%logger{26} mainPackage.sub.sample.Bar mainPackage.sub.sample.Bar

        %msg显示的日志的内容,%n换行,主要是用于方便查看日志,如果所有的日志都在一行,那真的看不下去了。


四、logback使用说明

        4.1,具体使用说明    

        以下日志配置是当前在做一个项目时配置的内容。

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true" scan="true" scanPeriod="60">
   <!-- 设置日志的存储路径,方便后面引用 -->
   <property name="log.dir" value="E:/data/logs/capabilityService" />
   <property name="max.history" value="30" />
   <!-- 活动文件的最大大小 -->
   <property name="max.file.size" value="100MB" />
   <!-- 所有归档日志文件的总大小/容量 -->
   <property name="total.size.cap" value="10G" />

   <!-- 控制台日志的Appender -->
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
      <!--<Encoding>UTF-8</Encoding>-->
      <!--<layout class="ch.qos.logback.classic.PatternLayout">-->
      <!--&lt;!&ndash; 格式化输出 &ndash;&gt;-->
      <!--<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} -%msg%n</pattern>-->
      <!--</layout>-->
      <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
         <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] - %logger{50} -- %msg%n</pattern>
      </encoder>
   </appender>

   <!-- 错误日志 输出日志文件-->
   <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <!-- 根据文件名称的模式,设置按天回滚 -->
         <fileNamePattern>${log.dir}/com.worldStar-error-%d{yyyy-MM-dd}.log</fileNamePattern>
         <!-- 最大历史天数,即保存多少天的日志文件 -->
         <maxHistory>${max.history}</maxHistory>
      </rollingPolicy>
      <!-- 对记录事件进行格式化 -->
      <encoder charset="UTF-8" class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
         <pattern>[%-5level] - %d{HH:mm:ss.SSS} [%thread] %logger{50} -- %msg%n</pattern>
      </encoder>
   </appender>

   <!-- 访问日志的Appender -->
   <appender name="ACCESS" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <fileNamePattern>${log.dir}/com.worldStar-access-%d{yyyy-MM-dd}.log</fileNamePattern>
         <maxHistory>${max.history}</maxHistory>
      </rollingPolicy>
      <encoder charset="UTF-8" class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
         <pattern>[%-5level] - %d{HH:mm:ss.SSS} [%thread] %logger{36} -- %msg%n</pattern>
      </encoder>
   </appender>

   <!-- 监控日志的Appender -->
   <appender name="MONITOR" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <fileNamePattern>${log.dir}/com.worldStar-monitor-%d{yyyy-MM-dd}.log</fileNamePattern>
         <maxHistory>${max.history}</maxHistory>
      </rollingPolicy>
      <encoder charset="UTF-8" class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
         <pattern>[%-5level] - %d{HH:mm:ss.SSS} [%thread] %logger{36} -- %msg%n</pattern>
      </encoder>
   </appender>

   <!-- 缓存日志的Appender -->
   <appender name="CACHE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <!-- 按天回滚 -->
         <fileNamePattern>${log.dir}/com.worldStar-cache-%d{yyyy-MM-dd}.log</fileNamePattern>
         <maxHistory>${max.history}</maxHistory>
      </rollingPolicy>
      <encoder charset="UTF-8" class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
         <pattern>[%-5level] - %d{HH:mm:ss.SSS} [%thread] [%logger{36}] -- %msg%n</pattern>
      </encoder>
   </appender>

   <!-- 操作日志的Appender -->
   <appender name="OPERATOR" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
         <fileNamePattern>${log.dir}/com.worldStar-operator-%d{yyyy-MM-dd}.log</fileNamePattern>
         <maxHistory>${max.history}</maxHistory>
      </rollingPolicy>
      <encoder charset="UTF-8" class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
         <pattern>[%-5level] - %d{HH:mm:ss.SSS} [%thread] [%logger{36} -- %msg%n]</pattern>
      </encoder>
   </appender>

   <!-- springframework的日志 -->
   <logger name="org.springframework" level="ERROR" />
   <!-- apache的日志 -->
   <logger name="org.apache" level="ERROR" />
   <!-- 这里addivitity要为false,否则STDOUT的日志也会达到ERROR里 -->
   <!-- 监控日志 -->
   <logger name="WORLDSTAR_MONITOR" additivity="false" level="INFO">
      <appender-ref ref="MONITOR" />
   </logger>
   <!-- 错误日志 -->
   <logger name="WORLDSTAR_ERROR" additivity="false" level="DEBUG">
      <appender-ref ref="ERROR" />
   </logger>
   <!-- 访问日志 -->
   <logger name="WORLDSTAR_ACCESS" addivitity="false" level="INFO">
      <appender-ref ref="ACCESS" />
   </logger>
   <!-- 缓存日志 -->
   <logger name="WORLDSTAR_CACHE" additivity="false" level="INFO">
      <appender-ref ref="CACHE" />
   </logger>
   <!-- 操作日志 -->
   <logger name="WORLDSTAR_OPERATOR" additivity="false" level="INFO">
      <appender-ref ref="OPERATOR" />
   </logger>

   <root level="DEBUG">
      <appender-ref ref="STDOUT" />
   </root>

</configuration>
            

            addivitity用于children-logger是否使用root-logger配置的appender进行输出。为false时表示只用当前logger的appender,为true时表示当前logger的appender-ref和root-logger的appender-ref都有效。

        4.2,总结

        logback使用过程中,要配置输出日志的添加器Appender、日志打印的子节点logger和根节点root。日志的输出是从子节点开始,如果子节点有输出内容则直接输入到根节点,如果子节点没有输出内容,则判断logger节点的additivity,是否向上级Root传递,如果传递的话则使用Root的输出,否则就不打印日志。


五、第三方工具、扩展

    5.1,Lilith

    这个在文章的上面提到过,是logback的Logging和AccessEvent查看器。

    5.2,Logback-akka

    由几个基于akka的logback实用程序组成,包括ActorAppender,HoptoadActorAppender和Logstash redis appender。

    5.3,Logback-android

    可以将logback强大的功能应用在Android上。

    5.4,Simpledb-appender

    Logback Appender可以写入Amazon SimpleDB。

    5.5,logback-configuration

    一个服务层(使用Spring)和一个REST风格的接口,它提供了以下方法:添加或更新日志,解析日志文件,解析logback配置文件,并上载logback配置文件并重新加载它。

    5.6,Logback-gelf

    可以通过GELF消息将消息记录到Graylog2服务器。

    5.7,Logback-testing

    TestNG Reporter的logback appender。