Java日志框架学习--LogBack和Log4j2--下

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java日志框架学习--LogBack和Log4j2--下相关的知识,希望对你有一定的参考价值。

Java日志框架学习--LogBack和Log4j2--下


Logback

Logback是由log4j创始人设计的又一个开源日志组件。

Logback当前分成三个模块:logback-core,logback- classic和logback-access。

  • logback-core是其它两个模块的基础模块。
  • logback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4J API。使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging
  • logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能

Logback中的组件

  • Logger: 日志的记录器,主要用于存放日志对象,也可以定义日志类型、级别。
  • Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等。
  • Layout: 负责把事件转换成字符串,格式化的日志信息的输出。
  • 在Logback中Layout对象被封装在encoder中。
  • 也就是说我们未来使用的encoder其实就是Layout

Logback配置文件

Logback提供了3种配置文件

  • logback.groovy
  • logback-test.xml
  • logback.xml

如果都不存在则采用默认的配置


日志输出格式

日志输出格式:

  • %-10level 级别 案例为设置10个字符,左对齐
  • %dyyyy-MM-dd HH:mm:ss.SSS 日期
  • %c 当前类全限定名
  • %M 当前执行日志的方法
  • %L 行号
  • %thread 线程名称
  • %m或者%msg 信息
  • %n 换行

使用演示

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.36</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.11</version>
        </dependency>


配置文件

输出到控制台

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
   <!--
    配置文件通用属性
    可以在当前配置文件中通过$name的形式,取得value值
    我们在此指定通用的日志输出格式
    日志输出格式:
    %-10level  级别 案例为设置10个字符,左对齐
    %dyyyy-MM-dd HH:mm:ss.SSS 日期
    %c  当前类全限定名
    %M  当前执行日志的方法
    %L  行号
    %thread 线程名称
    %m或者%msg    信息
    %n  换行
         -->

   <property name="pattern" value="[%-5level]  %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>

   <!--
      配置控制台输出的appender
      -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <!--
        表示对于日志输出目标的配置
        默认: system.out 表示以黑色字体输出日志
              system.err 表示以红色字体输出日志
            -->
        <target>
            System.err
        </target>

    <!--
       配置日志输出格式
           -->
       <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
          <!--  格式引用通用属性配置  -->
           <pattern>$pattern</pattern>
       </encoder>
    </appender>


     <!--
        日志记录器
        配置Root Logger
         level: 日志级别
        -->
     <root level="all">
         <appender-ref ref="console"/>
     </root>
</configuration>


输出到控制台和文件

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--
     配置文件通用属性
     可以在当前配置文件中通过$name的形式,取得value值
     我们在此指定通用的日志输出格式
     日志输出格式:
     %-10level  级别 案例为设置10个字符,左对齐
     %dyyyy-MM-dd HH:mm:ss.SSS 日期
     %c  当前类全限定名
     %M  当前执行日志的方法
     %L  行号
     %thread 线程名称
     %m或者%msg    信息
     %n  换行
          -->

    <property name="pattern" value="[%-5level]  %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>

    <!--  配置文件的输出路径   -->
    <property name="dir" value="logback.log"></property>


    <!-- 配置文件输出的appender   -->
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <!-- 引入文件位置   -->
        <file>$dir</file>

        <!--
          配置日志输出格式
       -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--  格式引用通用属性配置  -->
            <pattern>$pattern</pattern>
        </encoder>

    </appender>

    <!--
       配置控制台输出的appender
       -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            表示对于日志输出目标的配置
            默认: system.out 表示以黑色字体输出日志
                  system.err 表示以红色字体输出日志
                -->
        <target>
            System.err
        </target>

        <!--
           配置日志输出格式
               -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--  格式引用通用属性配置  -->
            <pattern>$pattern</pattern>
        </encoder>
    </appender>


    <!--
       日志记录器
       配置Root Logger
        level: 日志级别
       -->
    <root level="all">
        <appender-ref ref="file"/>
        <appender-ref ref="console"/>
    </root>
</configuration>



因为符合OGNL规范,因此配置文件中可以配置的属性,大多可以通过翻看对应的类源码,通过set方法或者属性名推测出来


输出到控制台,文件和html

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--
     配置文件通用属性
     可以在当前配置文件中通过$name的形式,取得value值
     我们在此指定通用的日志输出格式
     日志输出格式:
     %-10level  级别 案例为设置10个字符,左对齐
     %dyyyy-MM-dd HH:mm:ss.SSS 日期
     %c  当前类全限定名
     %M  当前执行日志的方法
     %L  行号
     %thread 线程名称
     %m或者%msg    信息
     %n  换行
          -->

    <property name="pattern" value="[%-5level]  %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>

    <!--  配置文件的输出路径   -->
    <property name="fileDir" value="logback.log"></property>

    <!--  配置输出为html形式的appender   -->
    <appender name="html" class="ch.qos.logback.core.FileAppender">
         <!-- 输出的文件位置 -->
        <file>logback.html</file>
         <!--  设置layout为输出html形式的  -->
         <layout class="ch.qos.logback.classic.html.HTMLLayout">
             <pattern>
                 $pattern
             </pattern>
         </layout>
    </appender>

    <!-- 配置文件输出的appender   -->
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <!-- 引入文件位置   -->
        <file>$fileDir</file>

        <!--
          配置日志输出格式
       -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--  格式引用通用属性配置  -->
            <pattern>$pattern</pattern>
        </encoder>

    </appender>

    <!--
       配置控制台输出的appender
       -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            表示对于日志输出目标的配置
            默认: system.out 表示以黑色字体输出日志
                  system.err 表示以红色字体输出日志
                -->
        <target>
            System.err
        </target>

        <!--
           配置日志输出格式
               -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--  格式引用通用属性配置  -->
            <pattern>$pattern</pattern>
        </encoder>
    </appender>


    <!--
       日志记录器
       配置Root Logger
        level: 日志级别
       -->
    <root level="all">
        <appender-ref ref="file"/>
        <appender-ref ref="console"/>
        <appender-ref ref="html"/>
    </root>
</configuration>



html展示效果如果:


日志拆分

日志拆分使用的是RollingFileAppender,它继承了FileAppender,因此父类中能配置的属性,这里都可以配置,我们只需要关注当前类新增的查日志拆分策略属性即可。

在当前RollingFileAppender中也为我们提供了两个设置日志拆分策略的set方法:


先看一波如何配置,再来分析源码:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--
     配置文件通用属性
     可以在当前配置文件中通过$name的形式,取得value值
     我们在此指定通用的日志输出格式
     日志输出格式:
     %-10level  级别 案例为设置10个字符,左对齐
     %dyyyy-MM-dd HH:mm:ss.SSS 日期
     %c  当前类全限定名
     %M  当前执行日志的方法
     %L  行号
     %thread 线程名称
     %m或者%msg    信息
     %n  换行
          -->

    <property name="pattern" value="[%-5level]  %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>

    <!--  配置文件的输出路径   -->
    <property name="fileDir" value="logback.log"></property>

    <!--  配置输出为html形式的appender   -->
    <appender name="html" class="ch.qos.logback.core.FileAppender">
         <!-- 输出的文件位置 -->
        <file>logback.html</file>
         <!--  设置layout为输出html形式的  -->
         <layout class="ch.qos.logback.classic.html.HTMLLayout">
             <pattern>
                 $pattern
             </pattern>
         </layout>
    </appender>

    <!-- 配置文件输出的appender   -->
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <!-- 引入文件位置   -->
        <file>$fileDir</file>

        <!--
          配置日志输出格式
       -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--  格式引用通用属性配置  -->
            <pattern>$pattern</pattern>
        </encoder>

    </appender>

    <!--
       配置控制台输出的appender
       -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            表示对于日志输出目标的配置
            默认: system.out 表示以黑色字体输出日志
                  system.err 表示以红色字体输出日志
                -->
        <target>
            System.err
        </target>

        <!--
           配置日志输出格式
               -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--  格式引用通用属性配置  -->
            <pattern>$pattern</pattern>
        </encoder>
    </appender>

    <!-- 配置文件的appender,可拆分可归档-归档是压缩的意思   -->
    <appender name="roll" class="ch.qos.logback.core.rolling.RollingFileAppender">
         <!--  设置输出格式    -->
         <layout class="ch.qos.logback.classic.PatternLayout">
             <pattern>$pattern</pattern>
         </layout>
         <!--  设置未归档的日志文件输出位置   -->
         <file>roll_logback.log</file>

          <!--  指定拆分规则  -->
          <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
               <!--   按照时间和压缩格式声明文件名,压缩格式gz    -->
              <fileNamePattern>roll.%dyyyy-MM-dd.log%i.gz</fileNamePattern>

              <!--   按照文件大小来进行拆分 -->
              <maxFileSize>1KB</maxFileSize>
          </rollingPolicy>
    </appender>

    <!--
       日志记录器
       配置Root Logger
        level: 日志级别
       -->
    <root level="all">
        <appender-ref ref="roll"/>
    </root>
</configuration>


下面分析一波,这里源码流程从subAppend函数讲起,因为每一条日志的输出,都需要交给至少一个appender,完成日志的输出,而交给appender后,一定会来到appender的subAppend这里,各位可以自行debug源码流程

这里拿RollingFileAppender进行讲解:

    @Override
    protected void subAppend(E event) 
        //日志真正写入前,现需要判断是否应该触发当前日志文件的归档行为
        //因为可能当前写入数据超过了日志文件大小的限制,那么当前日志就应该归档,再创建一个新的日志文件
        // The roll-over check must precede actual writing. This is the
        // only correct behavior for time driven triggers.
      
        // We need to synchronize on triggeringPolicy so that only one rollover
        // occurs at a time
        //加锁确保一次只有一个线程进行日志roll操作
        synchronized (triggeringPolicy) 
        //triggeringPolicy负责判断是否需要进行roll over
            if (triggeringPolicy.isTriggeringEvent(currentlyActiveFile, event)) 
                rollover();
            
        
        //调用父类方法真正执行写入操作 
        super.subAppend(event);
    

具体回滚策略是如何执行的,这里不再进行分析


过滤器

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <property name="pattern" value="[%-5level]  %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n"></property>

    <!--  配置文件的输出路径   -->
    <property name="fileDir" value="logback.log"></property>

    <!--
       配置控制台输出的appender
       -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            表示对于日志输出目标的配置
            默认: system.out 表示以黑色字体输出日志
                  system.err 表示以红色字体输出日志
                -->
        <target>
            System.err
        </target>

        <!--
           配置日志输出格式
               -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--  格式引用通用属性配置  -->
            <pattern>$pattern</pattern>
        </encoder>

     <!-- 配置过滤器  -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!--  设置日志的输出级别 -->
                <level>ERROR</level>
               <!--     高于Level中设置的日志级别,则打印日志      -->
               <onMatch>ACCEPT</onMatch>
               <!--     低于Level中设置的日志级别,则跳过          -->
              <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <!--
       日志记录器
       配置Root Logger
        level: 日志级别
       -->
    <root level="all">
        <appender-ref ref="console"/>
    </root>
</configuration>


通过过滤器,我们可以设置某个appender的日志过滤输出


过滤器链在何时会执行呢?


异步日志

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <property name="pattern" value="[%-5level]  %dyyyy-MM-dd HH:mm:ss:SSS %c %M %L %thread %m%n">Java日志框架:logback详解

Java日志框架:logback详解

java日志框架之logback初探

Java日志框架SLF4J和log4j以及logback的联系和区别

Java 学习总结(187)—— 轻量级开源日志框架 tinylog 简介

Java日志Log4j或者Logback的NDC和MDC功能