knowing logback

Logback是由log4j创始人Ceki Gülcü设计的又一个开源日志组件。根据logback官网上的说明:

Logback is intended as a successor to the popular log4j project, picking up where log4j leaves off.

logback旨在替代log4j成为最通用的日志框架。相比log4j,Ceki重写了log4j的内核形成了logback,这使得在一些关键执行路径上logback的性能相比log4j提升10倍以上。而且logback的初始化内存加载也更小了。

总所周知slf4j是一个标准的日志接口,而logback则是非常标准的实现。以至于未来替换掉logback非常容易。

这里来看看logback的几个组件。

appender

appender是logback中定义输出位置的组件,它明确了日志输出的位置,是控制台、文件还是数据库等等。

logback中两个最经典的实现就是ConsoleAppenderFileAppender了。除此之外还有很多非常实用的实现,例如:等等。

如果所有现有的实现都不能满足我们的需求也不要紧,logback作为slf4j的实现框架,为我们提供了非常好的扩展。

如果我们需要自己实现一个appender,那么我们就新写一个类,继承AppenderBase就可以了。

public class CountingConsoleAppender extends AppenderBase<ILoggingEvent> {
    public void append(ILoggingEvent event) {
        // export the log to custom place
    }
}

Encoder

appender负责告诉logback把日志送到哪里去,那么怎么显示就需要接下来介绍的一些列组件了,其中Encoder组件负责将日志事件转换成二进制流的形式传递到相应的位置上。

配置中默认使用的Encoder类型是ch.qos.logback.classic.encoder.PatternLayoutEncoder

layout

Encoder负责传递日志流,而layout则负责将一条条日志根据我们的习惯转换成可以阅读的文字。这也是我们在配置logback中最需要自定义的部分了。

最常见的场景就是我们使用ch.qos.logback.classic.PatternLayout这个类了。

平时我们在配置中使用的配置pattern标签使用的就是这个类。

<pattern>
    %d{yyyy-MM-dd HH:mm:ss} |-%-5level ${PID:- } in %-50(%logger[%thread]) : %msg%n
</pattern>

配置中具体的模板转换词可以参考logback的说明http://logback.qos.ch/manual/layouts.html#conversionWord)。

filter

在logback中,我们可以根据自己的需求定制出相对应的规则,过滤掉一些日志,减少排查时候的错误信息。完成这个过滤规则定制的组件就是filter

每个过滤器都会实现一个decide()方法,这个方法会返回一个FilterReply枚举类对象,FilterReply中有DENY,NEUTRAL,ACCEPT三种类型:

  • DENY:日志将立即被抛弃不再经过其他过滤器
  • NEUTRAL:有序列表里的下个过滤器过接着处理日志
  • ACCEPT:日志会被立即处理,不再经过剩余过滤器

filter中最常用的可能就是LevelFilter了。LevelFilter可以帮助过滤指定的日志的等级。

举个栗子,比如我在一个APPENDER组件中放入两个filter

<filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>INFO</level>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>NEUTRAL</onMismatch>
</filter>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>ERROR</level>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>DENY</onMismatch>
</filter>

这个上面这个配置中,每条日志都会被检查是不是INFO等级的日志,如果是则被接受,如果不是就被丢给下一个filter,第二个filter开始检查是不是ERROR等级,如果等级是日志则被打印,否则日志就被丢弃。

如果我们自己想去实现一个filter,可以定义一个继承ch.qos.logback.classic.filter.Filter的类。在decide()类中去写自己的规则就可以了。

如果我们希望自己定义的filter也能像LevelFilter一样使用onMatchonMismatch两个标签,可以选择继承ch.qos.logback.classic.filter.AbstractMatcherFilter这个类。

Spring Boot和logback

Spring Boot借助成熟的Spring体系,已经在Java生态中大红大紫了,Spring Boot也将logback作为了自己的默认日志处理框架。

一般情况下logback的配置文件会被取成logback.xml,但是Spring Boot中如果需要使用SpringBoot的一些插件,那么需要将插件的配置文件文件名称设置成logback-spring.xml,因为logback.xml加载的时机太早了,以至于Spring还没有启动logback的配置以及完成了。

Spring Boot主要解决的问题就是配置问题,在logback中原先要读取配置是比较麻烦的。

Spring Boot提供了一个插件springProperty:

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
    <remoteHost>${fluentHost}</remoteHost>
    ...
</appender>

这样配置文件会自动从application.properties文件中读取相应的配置,并在logback中使用这些变量。

针对Spring Boot一个jar,四处运行 的宗旨,Spring Boot还提供了一个springProfile的插件:

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev, staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

这样logback就会根据Spring Boot当时所处的环境,切换到对应的配置上。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,169评论 19 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,993评论 6 342
  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 5,110评论 1 13
  • 8.7 Spring Boot集成日志 SLF4J与Logback简介 Java日志框架众多,常用的有java.u...
    光剑书架上的书阅读 10,564评论 3 31
  • Spring Boot-日志配置(超详细) 更新日志:20170810 更新通过 application.yml传...
    inke阅读 67,792评论 9 122