Java日志记录框架Logback详解(4)

<appender>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>
   
    <appender> 
        <rollingPolicy> 
              <fileNamePattern>D:/rolling-file-%d{yyyy-MM-dd}.log</fileNamePattern> 
              <maxHistory>30</maxHistory>   
        </rollingPolicy> 
        <encoder>
              <pattern>%-4relative [%thread] %-5level %lo{35} - %msg%n</pattern> 
        </encoder> 
    </appender>
   
    <!-- 异步输出 --> 
    <appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender"> 
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> 
        <discardingThreshold>0</discardingThreshold> 
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --> 
        <queueSize>256</queueSize> 
        <!-- 添加附加的appender,最多只能添加一个 --> 
        <appender-ref ref ="ROLLING-FILE-1"/> 
    </appender>
   
    <logger additivity="false" />
    <logger level="DEBUG">
        <appender-ref ref="ASYNC" />
    </logger>
   
    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
   
</configuration>

即,我们引入了一个AsyncAppender,先说一下AsyncAppender的原理,再说一下几个参数:

当我们配置了AsyncAppender,系统启动时会初始化一条名为"AsyncAppender-Worker-ASYNC"的线程

当Logging Event进入AsyncAppender后,AsyncAppender会调用appender方法,appender方法中再将event填入Buffer(使用的Buffer为BlockingQueue,具体实现为ArrayBlockingQueye)前,会先判断当前Buffer的容量以及丢弃日志特性是否开启,当消费能力不如生产能力时,AsyncAppender会将超出Buffer容量的Logging Event的级别进行丢弃,作为消费速度一旦跟不上生产速度导致Buffer溢出处理的一种方式。

上面的线程的作用,就是从Buffer中取出Event,交给对应的appender进行后面的日志推送

从上面的描述我们可以看出,AsyncAppender并不处理日志,只是将日志缓冲到一个BlockingQueue里面去,并在内部创建一个工作线程从队列头部获取日志,之后将获取的日志循环记录到附加的其他appender上去,从而达到不阻塞主线程的效果。因此AsyncAppender仅仅充当的是事件转发器,必须引用另外一个appender来做事。

从上述原理,我们就能比较清晰地理解几个参数的作用了:

discardingThreshold,假如等于20则表示,表示当还剩20%容量时,将丢弃TRACE、DEBUG、INFO级别的Event,只保留WARN与ERROR级别的Event,为了保留所有的events,可以将这个值设置为0,默认值为queueSize/5

queueSize比较好理解,BlockingQueue的最大容量,默认为256

includeCallerData表示是否提取调用者数据,这个值被设置为true的代价是相当昂贵的,为了提升性能,默认当event被加入BlockingQueue时,event关联的调用者数据不会被提取,只有线程名这些比较简单的数据

appender-ref表示AsyncAppender使用哪个具体的<appender>进行日志输出

<encoder>

<encoder>节点负责两件事情:

把日志信息转换为字节数组

把字节数组写到输出流

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8e687584a611807a04e52a0779e5ff97.html