vlambda博客
学习文章列表

日志框架之logback详细配置

点击👇关注,这个靓仔有货

1.  日志框架和日志门面(Logging Facade)



主要有这几个关键字需要理解:JUL 、 JCL 、 Log4j 、 Logback 、 Slf4j2、Log4j2。还有日志框架和日志门面这两个概念需要区分开。


  • 日志框架:主要有JUL、Log4j、Logback、Log4j2

  • 日志门面:主要有JCL 、 Slf4j 。是门面模式的一个应用。可以抽象的理解为java的接口,日志框架可以理解为接口的具体实现。只要日志框架有统一的日志门面,后面可以轻松更换应用的日志框架。日志门面兼容了多种日志框架,使得应用和框架的耦合性大大降低。



2. 日志框架



  • JUL:Java Util Log 是Java官方提供的日志库。使用的并不是非常广泛,因为其开发出来的时间晚、第三方log bin功能丰富,它默认没有classpasth加载的功能,并且相比于Logback和Log4j,它的性能低下。

  • Log4j: Apache开源的一个项目,创始人是 Ceki Gulcu。是java领域的元老项目。配置自由度高,并且通过运行时可以读取外部的配置文件。主要有三个部分:Loggers、Appenders、Layouts。Loggers负责捕获记录信息、Appenders负责发布日志信息、发送到不同的目的地。Layouts负责格式化不同风格的日志信息( 这点Logback参考了 )


  • Logback: 创始人还是Log4j的创始人,作为Log4j的后继者发展而来,相比于Log4j提供了Async异步logger、filter等特性。主要分为三个模块:logback-core(是另外两个模块的基础模块)、Logback-classic (扩展了核心模块logback-core,是log4j的一个改良版本,并且完整实现了Slf4j的api(可以实现logback和其他日志框架的来回切换)这样可以很方便将应用系统的日志框架更换为log4j或者JUL)、Logback-access(访问模块与Servlet容器集成、为tomcat提供http访问日志的功能)


  • Log4j2: 基于 Log4j 上为了提高其性能开发出了 Log4j2 。它和 Log4j 并不兼容,并且设计模仿了 Logback ,性能倒是提高了不少。Log4j2也做了 Facade(门面)/ Implemention(实现)的分离设计,分成了 Log4j-api 和 Log4j-core


对比

性能上 Log4j2 要强,但是生态上 Logback是优先的 
1 log4j2比logback更新:log4j2的GA版在2014年底才推出,比logback晚了好几年,这期间log4j2确实吸收了slf4j和logback的一些优点(比如日志模板),同时应用了不少的新技术
2 由于采用了更先进的锁机制和LMAX Disruptor库,log4j2的性能优于logback,特别是在多线程环境下和使用异步日志的环境下
3 二者都支持Filter(应该说是log4j2借鉴了logback的Filter),能够实现灵活的日志记录规则(例如仅对一部分用户记录debug级别的日志)
4 二者都支持对配置文件的动态更新
5 二者都能够适配slf4j,logback与slf4j的适配应该会更好一些,毕竟省掉了一层适配库
6 logback能够自动压缩/删除旧日志
7 logback提供了对日志的HTTP访问功能
8 log4j2实现了“无垃圾”和“低垃圾”模式。简单地说,log4j2在记录日志时,能够重用对象(如String等),尽可能避免实例化新的临时对象,减少因日志记录产生的垃圾对象,减少垃圾回收带来的性能下降
9 log4j2和logback各有长处,总体来说,如果对性能要求比较高的话,log4j2相对还是较优的选择。


3. 日志门面


  • JCL:

    common-logging 是apache的一个开源项目,也叫做 Jakarta Common Logging,缩写 JCL(common-logging) 的功能是提供日志功能的 API 接口,本身并不提供日志的具体实现(当然,common-logging 内部有一个 Simple logger 的简单实现,但是功能很弱,直接忽略),而是在运行时动态的绑定日志实现组件来工作(如 log4j、JUL (java.util.loggin) )。


  • Slf4j:

    Simple Logging Facade For Java:简单java日志门面,创始人:Ceki Gulcu类似于 Common-Logging,slf4j 是对不同日志框架提供的一个 API 封装,可以在部署的时候不修改任何配置即可接入一种日志实现方案。但是,slf4j 在编译时静态绑定真正的 Log 库。使用 SLF4J 时,如果你需要使用某一种日志实现,那么你必须选择正确的 SLF4J 的 jar 包的集合(各种桥接包)。

          

对比


 slf4j 库类似于 Apache Common-Logging。但是,他在编译时静态绑定真正的日志库。这点似乎很麻烦,其实也不过是导入桥接 jar 包而已。
不需要使用logger.isDebugEnabled()来解决日志因为字符拼接产生的性能问题。slf4j 的方式是使用{}作为字符串替换符,形式如:logger.debug("id: {}, name: {} ", id, name);


4. 使用


  • Slf4j + Logback

  • JCL(common-logging) + log4j



5. 日志级别


  • 日志级别:

TRACE < DEBUG < INFO < WARN < DEBUG

Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.
Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.
Info:消息在粗粒度级别上突出强调应用程序的运行过程.
Warn:输出警告及warn以下级别的日志.
Error:输出错误信息日志.
  • 参数化日志记录:它本身不是 logback 的功能,是SLF4J的一部分:logger.debug("你好,我叫"+用户名+",我是"+年龄+"岁。"); 在上述调用中,即使日志请求被禁用,也需要承担构造 String 类型消息的成本。SLF4J 提供以下替代方案:logger.debug("你好,我叫{},我{}岁", username, age);



6. Logback



Append



  •  主要用于控制日志输出目的地(控制台、文件、远程(logstash)服务器、Mysql、PostreSQL、Oracle等数据库、JMS和远程UNIX Syslog守护进程等等)


  • ch.qos.logback.core.ConsoleAppender :控制日志输出到控制台的形式,比如在console-appender.xml中定义的默认控制台输出。

<target>: ConsoleTarget : System.out (默认) 、 System.err 
<encoder>: 对日志消息进行格式化
  • ch.qos.logback.core.rolling.RollingFileAppender :控制日志文件生成策略,比如文件名称格式、超过多大重新生成文件以及删除超过多少天的文件。

<file>: 被写入的文件名
<append>: 如果true日志被追加到文件结尾,如果false截断文件再保存日志
<rollingPolicy>:滚动策略,
<fileNamePattern> :文件明明格式
%d{yyyy-MM-dd} :日期格式转换符
<maxHistory>:保留文件的最大天数,默认为30天
<maxFileSize>: 日志文件的大小,默认值是10MB。
<encoder charset="UTF-8">:对记录事件格式化
<pattern>:日志记录内容,再encoder节点下
<filter> ,过滤器,筛选日志级别



滚动策略


  • TimeBasedRollingPolicy: 常用滚动策略

它允许根据时间进行翻转。可以指定每天、每周或每月发生一次翻转
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/service/error/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>${log.maxHistory}</maxHistory>
</rollingPolicy>


  • FixedWindowRollingPolicy:根据固定窗口算法重命名文件

<!-- 设置为按照索引的方式滚动,定义文件名称的时候使用%i作为占位符,滚动后会会用角标替换 -->
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>/logback/log/test-%i.log</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<!-- 指定文件最大尺寸,达到该尺寸,就触发rollingPolicy对应的策略,maxFileSize属性指定文件大小 -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>1MB</maxFileSize>
</triggeringPolicy>

minIndex:窗口索引最小值
maxIndex:窗口索引最大值,当用户指定的窗口过大时,会自动将窗口设置为20。
fileNamePattern:必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz 或者 没有log%i.log.zip
  • SizeBasedTriggeringPolicy: 查看当前正在写入的文件的大小。如果它增长到大于指定大小,则使用 SizeBasedTriggeringPolicy 的 FileAppender 滚动文件并创建一个新文件

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>test.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>

<!--当文件大小超过5MB时,通知RollingPolicy轮转-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>

<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>




Logger


只有配置到logger节点上的appender才会被使用,logger用于配置哪种条件下的日志被打印,



Root


root是一种特殊的appender



Filter



主要用在appender上,用于过滤日志级别的输出,主要两种过滤器 ThresholdFilter和LevelFilter

  • ch.qos.logback.classic.filter.ThresholdFilter : 临界值过滤器,如下,过滤掉ERROR以下的过滤器,只会显示 ERROR 及 ERROR级别以上的日志

<!--设置error级别为error日志-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>

  • ch.qos.logback.classic.filter.LevelFilter :级别过滤器,根据日志级别进行过滤。日志级别 : 用于配置符合过滤条件的操作 (选项值:DENY 丢弃, NEUTRAL 中立, ACCEPT 接收;) :用于配置不符合过滤条件的操作 (选项值:DENY 丢弃, NEUTRAL 中立, ACCEPT 接收;)

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> 
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>
%-4relative [%thread] %-5level %logger{30} - %msg%n
</pattern>
</encoder>
</appender>



7. Logback日志输出目的



输出到Mysql


  • pom.xml :引入dbcp连接池依赖,数据库连接驱动

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
  • logback.xml 可以搭配filter使用

<appender name="mysql" class="ch.qos.logback.classic.db.DBAppender">
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
<dataSource class="org.apache.commons.dbcp.BasicDataSource">
<driverClassName>com.mysql.jdbc.Driver</driverClassName>
<url>jdbc:mysql://xxx.xxx.xxx.xxx3306/logback-log?useUnicode=true&amp;characterEncoding=utf-8&amp;allowMultiQueries=true&amp;useSSL=false</url>
<username>xx</username>
<password>xx</password>
</dataSource>
</connectionSource>
</appender>

<root level="INFO">
<appender-ref ref="mysql" />
</root>
  • 数据库表结构,参考 MySQL数据库表创建脚本在ch.qos.logback.classic.db.scrip

  • 可以自行拓展 ch.qos.logback.classic.db.DBAppender


输出到logstash



<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.2.11:5000</destination>
<queueSize>1048576</queueSize>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<pattern>
<pattern>
{
"severity": "%level",
"service": "${springAppName:-}",
"port": "${serverPort:-}",
"trace": "%X{X-B3-TraceId:-}",
"span": "%X{X-B3-SpanId:-}",
"exportable": "%X{X-Span-Export:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"rest": "%message"
}
</pattern>
</pattern>
</providers>
<!-- 动态output设置索引名,需要在input设置 codec => json -->
<customFields>{"appname":"better-elk"}</customFields>
</encoder>
</appender>




7. logback区分业务场景滚动日志



  • debug日志:记录DEBUG级别的日志,只在开发、测试环境的日志收集

  • error日志:记录ERROR级别的日志,所有环境都开启收集

  • info日志:记录INFO界别的日志,所有环境都开启收集

  • 业务日志:  记录应用中需要收集日志,所有环境都开启收集参考项目中的 logback-dev.yml 配置


8. MDC应用



  • 全链路调用日志追踪

  • logback动态格式颜色


后面会出这两个MDC应用的具体文章,敬请期待!!