【Logback】Logback 中的 Appenders

目录

1、什么是 Appenders?

2、解说 AppenderBase.doAppend() 方法

3、logback-core 模块中的 Appenders

(1)OutputStreamAppender

(2)ConsoleAppender

(3)FileAppender

(4)RollingFileAppender


1、什么是 Appenders?

        Appender 组件负责处理 Logback 日志写入的任务,该组件必须实现 ch.qos.logback.core.Appender 接口,该接口的主要方法总结如下://主要是解决将日志写到哪里去的问题

package ch.qos.logback.core;

import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.spi.LifeCycle;

public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable<E> {
    String getName();

    //核心方法
    void doAppend(E var1) throws LogbackException;

    void setName(String var1);
}

        Appender 接口中其实就一个最核心的方法,即 doAppend() 方法,且该方法只有一个参数,也就是类型为 E 的对象实例。泛型 E 的实例类型需要根据 logback 的具体模块进行决定,在 logback-classic 模块内,E 的类型为 ILoggingEvent(日志记录事件),在 logback-access 模块内,E 的类型为 AccessEventdoAppend() 方法可以说是 logback 框架中最重要的方法,它负责将日志记录事件以合适的格式输出到合适的输出设备//该方法框架的灵魂和各组件之间的桥梁

2、解说 AppenderBase.doAppend() 方法

        抽象类 ch.qos.logback.core.AppenderBase 实现了 Appender 接口,该类是所有 Appender 组件的父类,它提供了所有 Appender 组件共享的基本功能,比如获取和设置 Appender 组件的名称,激活状态,layout 组件,过滤器等。在该类中有一个非常重要的方法实现,就是我们上边提到的 doAppend() 方法,AppenderBase 类的具体实现逻辑源码如下:

public synchronized void doAppend(E eventObject) {
        if (!this.guard) {
            try {
                //1、防止递归调用
                this.guard = true;
                //2、判断Appender是否开启
                if (!this.started) {
                    //状态重复计数
                    if (this.statusRepeatCount++ < 5) {
                        //发出警告信息
                        this.addStatus(new WarnStatus("Attempted to append to non started appender [" + this.name + "].", this));
                    }

                    return;
                }
                //3、检查Appender过滤器决策结果
                if (this.getFilterChainDecision(eventObject) == FilterReply.DENY) {
                    return;
                }
                //4、调用子类的append()的实现
                this.append(eventObject);
            } catch (Exception var6) {
                if (this.exceptionCount++ < 5) {
                    this.addError("Appender [" + this.name + "] failed to append.", var6);
                }
            } finally {
                //5、释放guard
                this.guard = false;
            }

        }
    }

        上边这段代码我在《Logback 日志框架的架构》这篇文章中也提到过,但也只是简要提及,这里将具体分析一下。

        AppenderBase 类中的 doAppend() 方法是同步方法(synchronized修饰),所以不同的线程把日志记录到同一个 Appender 时都是线程安全的(独占访问)。

        这里需要注意,同步有时候并不总是合适的,所以 logback 还提供了 doAppend() 的一般实现,即 ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(),该类中的实现除了不使用synchronized修饰方法外,其他逻辑与 AppenderBase 类中的实现几乎一样。

        第一步,判断 guard 属性是否被设置为 true。如果为 true,那么程序将立即跳出此方法,如果没有设置 guard ,则在下一条语句中将其设置为 true。该 guard 属性确保了 doAppend() 方法不会递归调用自己。比如,如果在 append() 方法之外的某个地方想要调用 Appender 组件去记录一些内容,那么它可能会定向到刚刚调用它的同一个 Appender 组件,从而导致无限循环和堆栈溢出。//guard 属性防止程序递归调用

        第二步,判断 started(开启状态) 是否为 true,如果为 false,doAppend() 将发送警告消息并返回。也就是说,一旦 Appender 已经关闭,就无法对其进行写入。

        Appender 对象实现了 LifeCycle 接口,这意味着它们也实现了 start()、stop() isStarted() 方法。当设置完 Appender 的所有属性后,logback 的配置框架(Joran)将调用 start() 方法来通知 Appender 激活这些属性。如果某些属性缺失或者属性之间相互干扰,那么 Appender 可能无法启动。一般情况下,根据 Appender 的类型,具体的启动的逻辑也会有所不同。//start()方法用来检查Appender配置是否完整,并激活Appender

        如果 Appender 无法启动或已停止,则会通过 logback 的内部状态管理系统发出警告消息。为了避免系统被相同的警告消息淹没,经过几次尝试后(5次),doAppend() 将停止发出这些警告。

        第三步,检查 Appender 过滤器决策结果。根据 Appender 过滤器链产生的决策结果,判断日志事件是否被拒绝或者被接受。在过滤器链没有做出决定的情况下,默认会接受日志事件。

        然后,调用子类的 append() 的实现append() 方法负责将日志记录事件输出到指定的设备上。

        最后,释放 guard ,以允许其他线程调用 doAppend() 方法。

3、logback-core 模块中的 Appenders

        logback-core 模块为构建其他 logback 模块奠定了基础,因此在 logback-core 中,实现了一些最小化定制的组件,下边,我们将探讨几个开箱即用的 Appenders(追加器)。

(1)OutputStreamAppender

        OutputStreamAppender 会使用 java.io.OutputStream 来处理日志事件。这个类会为其它 Appender 组件的构建提供基础服务。以下是该 Appender 的几个属性配置:

属性名称类型描述
encoderEncoder 编码器配置
immediateFlushString

默认值为“true”,立即刷新输出流可确保日志记录事件立即写出,防止日志记录丢失

如果将此属性设置为“false”,可能会使记录吞吐量增加四倍左右(仅是测试值),不过,当应用程序退出,Appender未被正确关闭时,就可能使尚未写入磁盘的日志记录丢失。

        用户通常不会直接实例化 OutputStreamAppender 对象,所以我们为什么还要提到它呢?

        因为 OutputStreamAppender 是 ConsoleAppender、FileAppender、RollingFileAppender 这3 个非常重要的 Appender 对象的父类,所以重要性不言而喻,下图是 OutputStreamAppender 及其子类的类图。//都是基于OutputStream进行日志处理的Appender

(2)ConsoleAppender

        顾名思义,ConsoleAppender 是将日志输出到控制台上,更准确的来说是输出到 System.out 或 System.err 上。ConsoleAppender 通过用户指定的 encoder 来格式化日志,因为 System.out 和 System.err 都是 java.io.PrintStream 类型,所以,它们都被包装在一个带有缓冲区的 OutputStreamWriter 中。

        该 Appender 可以配置的属性如下:

属性名称类型描述
encoderEncoder 编码器配置
target String输出字符串,目标为 System.out 或 System.err 。默认是 System.out
withJansibooleanwithJansi 属性默认为 false,为 true 时会激活 Jansi 库,该库在 Windows 计算机上提供对 ANSI 颜色代码的支持。请注意,基于 Unix 的操作系统(例如 Linux 和 Mac OS X)默认支持 ANSI 颜色代码。//win系统颜色支持

        以下是使用 ConsoleAppender 的示例配置:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!--默认为 ch.qos.logback.classic.encoder.PatternLayoutEncoder-->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} -%kvp- %msg %n</pattern>
    </encoder>
  </appender>

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

(3)FileAppender

        前面提到过,FileAppender 也是 OutputStreamAppender 的子类,它的作用是把日志输出到指定的文件中。

        该 Appender 可以配置的属性如下:

属性名称类型描述
appendboolean默认设置为 true,即将日志追加到文件现有内容的末尾。如果为 false,则覆盖原有文件中的内容
encoderEncoder 编码器配置
fileString

要写入的文件。如果该文件不存在,则创建该文件。该选项没有默认值,示例的配置值为:c:/temp/test.logc:\\temp\\test.log

注意,如果文件的父目录不存在,FileAppender 也会自动的创建它。

bufferSizeFileSize

设置输出缓冲区的大小。默认值为 8192,即使在负载非常重且持续的情况下,256 KB 值一般也足够了。该属性在 OutputStreamAppender.immediateFlush 为 false 时可用。

该选项可以通过在数值后分别添加 KB、MB 和 GB 来指定字节、千字节、兆字节或千兆字节。例如,5000000、5000KB、5MB 和 2GB 都是有效值,其中前三个值是等效的。

prudent(谨慎的)boolean

默认值为 false,如果设置为 true,即开启 Prudent 模式。在 prudent 模式下,即使存在多个不同主机(JVM)上运行的 FileAppender 实例,FileAppender 也会将日志安全地写入到指定文件。//安全模式

Prudent 模式依赖独占的文件锁,实验表明,使用文件锁定的成本大约是正常写入成本的三倍 (x3),因此在 Prudent 模式下,会降低日志写入的吞吐量。

Prudent 模式可以有效地将写入同一文件的所有 JVM 之间的 I/O 操作进行排序。因此,随着竞争访问文件的 JVM 数量增加,每个 I/O 操作产生的延迟也会增加。不过,只要 I/O 操作总数仅为每秒 20 个日志请求左右时,该模式对性能的影响就可以忽略不计。但是,如果是每秒生成 100 次或更多 I/O 操作的应用程序,那么该模式可能会对性能产生影响,因此,在这种情况下应该避免使用 Prudent 模式。

当日志文件位于网络文件系统上时,Prudent 模式的成本会更大。需要注意的是,网络文件系统上的文件锁有时可能存在强烈的偏差,使得当前拥有锁的进程在释放锁后可以立即重新获得锁。因此,当一个进程霸占日志文件的锁时,其他进程可能因为等待该锁而陷入死锁状态

        默认情况下,每个日志记录事件都被会立即刷新到底层的输出流。如果应用程序在没有正确关闭 Appender 的情况下退出,这时的日志记录也不会丢失,所以这种方式也更加的安全。

        但是,为了显着提高日志记录的吞吐量,可能也会需要将 immediateFlush 属性设置为 false。

        以下是使用 FileAppender 的示例配置:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>testFile.log</file>
    <append>true</append>

    <!--将immediateFlus设置成false可以获得更高的日志吞吐量-->
    <immediateFlush>true</immediateFlush>

    <!-- 默认使用PatternLayoutEncoder-->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} -%kvp- %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

        如果使用时间戳对写入文件进行唯一命名?

        如果希望应用程序在每次启动时都自动创建一个新的日志文件,除了可以手动更改日志文件的名称以外,还有一种非常方便的方式,那就是使用时间戳,下边就是一个简单的例子:

<configuration>

  <!--把当前事件格式化为"yyyyMMdd'T'HHmmss",然后将其命名为bySecond,
      这个值对于所有后续配置的元素都是可用的-->
  <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <!--使用之前创建的时间戳来创建唯一的日志文件名称-->
    <file>log-${bySecond}.txt</file>
    <encoder>
      <pattern>%logger{35} -%kvp- %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

        <timestamp> 元素有两个强制的属性 key 和 datePattern 以及一个可选的 timeReference 属性。

  • key 属性是键的名称,在该键 key 下时间戳将作为变量可供后续配置元素使用。
  • datePattern 属性用于将当前时间(解析配置文件的时间)转换为字符串的日期模式。日期模式应遵循 SimpleDateFormat 中定义的约定。
  • timeReference 属性表示时间戳的参考时间。该时间默认是配置文件的解析时间(即当前时间)。然而,在某些情况下,参考时间使用日志上下文创建的时间可能会更加的合适。为了实现这一目标,只要将 timeReference 属性设置为 “contextBirth” 就可以了。

        示例的配置如下:

<configuration>
  <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" 
             timeReference="contextBirth"/>
  ...
</configuration>

(4)RollingFileAppender

        RollingFileAppender 对 FileAppender 的功能进行了扩展,它提供了滚动更新日志文件的功能。比如,使用 RollingFileAppender 将日志记录到名为 log.txt 的文件,当满足特定条件时,可以将其记录的目标更改为另一个文件。//日志文件滚动更新

        实现 RollingFileAppender 的日志滚动功能需要配置两个重要的组件,第一个组件是 RollingPolicy(滚动策略),负责执行滚动所需的操作,第二个组件是 TriggeringPolicy(触发策略),用来定义什么时候进行滚动。//滚动策略+触发策略

        一般来说,RollingFileAppender 必须同时设置 RollingPolicy 和 TriggeringPolicy。但是,如果一个 RollingPolicy 也实现了 TriggeringPolicy 接口,那么只需显式指定 RollingPolicy 即可

        以下是 RollingFileAppender 的可用属性:

属性名称类型描述
appendboolean默认设置为 true,即将日志追加到文件现有内容的末尾。如果为 false,则覆盖原有文件中的内容
encoderEncoder 编码器配置
fileString

要写入的文件

请注意,此处文件可以为空,在这种情况下,输出仅写入由 RollingPolicy 指定的目标。

rollingPolicyRollingPolicy滚动执行策略,见下文详述
triggeringPolicyTriggeringPolicy滚动触发策略,见下文详述
prudent(谨慎的)boolean

Prudent 模式不支持 FixedWindowRollingPolicy(弃用策略)

Prudent 模式只支持 TimeBasedRollingPolicy,但是有两个限制:

(1)在 Prudent 模式下,不支持也不允许文件压缩。 因为不能让一个 JVM 写入文件时,而另一个 JVM 正在压缩该文件。

(2)Appender 的 file 属性不能设置,且必须留空。因为大多数操作系统不允许在另一个进程打开文件时重命名该文件。

        什么是滚动策略(RollingPolicy)?

        RollingPolicy 用来定义文件滚动和重命名时所执行的操作,RollingPolicy 的接口如下所示:

package ch.qos.logback.core.rolling;

import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.rolling.helper.CompressionMode;
import ch.qos.logback.core.spi.LifeCycle;

public interface RollingPolicy extends LifeCycle {
    void rollover() throws RolloverFailure;

    String getActiveFileName();

    CompressionMode getCompressionMode();

    void setParent(FileAppender<?> var1);
}

        RollingPolicy 接口中一共有四个方法,其中 rollover() 方法用来执行滚动(归档)当前日志文件所涉及的工作,getActiveFileName() 用来方法来获取当前日志文件(写入实时日志的位置)的文件名,getCompressionMode() 用来获取日志的压缩模式,最后,setParent() 方法使 RollingPolicy 实例可以获得对其父类的引用。

        基于时间的滚动策略:TimeBasedRollingPolicy

        TimeBasedRollingPolicy 用来定义基于时间的滚动策略,比如按天或者按月进行滚动。

        TimeBasedTriggeringPolicy 同时实现了 RollingPolicy 和 TriggeringPolicy 接口。它的可配置属性如下:

属性名称类型描述
fileNamePatternString

必须配置,该属性用来定义滚动(归档)日志文件。

该文件名称中一般会包含 %d 转换符,%d 转换符后边一般也还包含指定的日期和时间模式,比如:/test.%d{yyyy-MM-dd-HH}.log,表示按小时对日志文件进行滚动,默认的日期和时间模式为 yyyy-MM-dd

注意,当配置 RollingFileAppender 的 file 属性(父类中的属性)时,当前活动日志文件的名称就是 file 属性指定的文件名称,此时活动日志文件的名称不会随时间的改变而改变。因此,可以利用这个属性解耦活动日志文件的位置和归档日志文件的位置,这个在后边会举例。

多个 %d 转换符的说明:

fileNamePattern 的值可以包含多个 %d 转换符,但是其中只能有一个 %d 是推动日志文件滚动周期的主要转换符,其他 %d 必须使用 "aux" 参数进行标记,指明这是一个辅助性的转换符。

多个 %d 转换符有助于使用不同于滚动周期的文件夹结构来组织存档文件。比如,以下显示的文件名将按年和月来命名日志文件夹,但按天来更新日志文件:

/var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log

注意,fileNamePattern 属性内,日期和时间模式内任意位置的正斜杠 "/" 或反斜杠 "\" 字符将被解释为目录分隔符。

maxHistoryint

该属性用于控制要保留的归档文件的最长时间,超过该配置时间的旧文件会被异步删除。

比如,如果指定策略为每月滚动,并将 maxHistory 设置为 6,那么将只保留 6 个月内的存档文件。当旧的存档文件被删除时,为这些文件存档而创建的文件夹都会被删除。

maxHistory 的默认配置为零,即默认情况下不删除存档。

totalSizeCapint

该属性用于控制所有归档文件的总大小。当超过总大小上限时,最旧的存档将被异步删除。

此外,要使 totalSizeCap 属性生效,还需要设置 maxHistory 属性。框架 首先应用 maxHistory 属性限制,然后再应用 "总大小上限" 限制。//即首先删除超时的,然后再删除超大小的

totalSizeCap 属性的值可以通过在数值后分别添加 KB、MB 和 GB 来指定为字节、千字节、兆字节或千兆字节的单位。

默认情况下,totalSizeCap 设置为零,这意味着没有总大小上限。

cleanHistoryOnStartboolean

默认情况下,此属性设置为 false。如果设置为 true,则存档删除将在 Appender 启动时执行。

存档删除通常在日志回滚期间执行。但是,某些应用程序的生存时间可能不够长,无法触发滚动。因此,对于此类短暂的应用程序,存档删除可能永远没有机会执行。所以通过将 cleanHistoryOnStart 设置为 true,可以避免以上这种情况

        以下是一些 fileNamePattern 的值及其效果的说明:

fileNamePattern表达式回滚时间示例
/wombat/foo.%d

按日滚动,由于 %d 转换符后省略了日期和时间匹配模式,所以采用的是默认的模式 yyyy-MM-dd

file 属性未设置:2023年11月23日的日志将输出到文件 /wombat/foo.2023-11-23。同样,24日期间的日志将输出到 /wombat/foo.2006-11-24

file 属性设置为 /wombat/foo.txt 时:2023年11月23日的日志将输出到文件 /wombat/foo.txt。日志回滚时,foo.txt 将被重命名为 /wombat/foo.2023-11-23。此外,还将创建一个新的 /wombat/foo.txt 文件,用来记录24日的日志输出,此种情况下的活动日志文件始终是 /wombat/foo.txt//file属性的作用

/wombat/%d{yyyy/MM}/foo.txt按月滚动

file 属性未设置:在2023年10月期间,日志输出将转到 /wombat/2023/10/foo.txt。 11月期间,日志输出到 /wombat/2023/11/foo.txt

file 属性设置为 /wombat/foo.txt:活动日志文件将始终为 /wombat/foo.txt。在2023年10月期间的日志将输出到 /wombat/foo.txt。 日志按月滚动后,/wombat/foo.txt 将更名为 /wombat/2023/10/foo.txt。此外,将创建一个新的 /wombat/foo.txt 文件,用来记录11月份的日志输出。 11月滚动时,/wombat/foo.txt 也将更名为 /wombat/2023/11/foo.txt

/wombat/foo.%d{yyyy-ww}.log按周滚动示例与上边类似
/wombat/foo%d{yyyy-MM-dd_HH}.log按小时滚动示例与上边类似
/wombat/foo%d{yyyy-MM-dd_HH-mm}.log按分钟滚动示例与上边类似
/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log按分钟滚动,并指定时区在某些情况下,可能希望根据与主机时区不同的时钟来滚动日志文件。那么就可以在 %d 转换符的日期和时间匹配模式中传递时区参数。

/foo/%d{yyyy-MM,aux}/%d.log

//非常有用的匹配模式

按日滚动,按年和月来归档日志文件

在此示例中,第一个 %d 转换符被标记为辅助标记。然后,第二个 %d 转换符(省略了时间和日期匹配模式)被定为主要标记。因此,滚动将每天发生(默认为 %d),并且文件夹也将按照年份和月份命名。例如,在2023年11月期间,日志文件将全部放置在 /foo/2023-11/ 文件夹下,比如 /foo/2023-11/2023-11-14.log

        如何进行自动文件压缩?

        TimeBasedRollingPolicy 支持自动文件压缩。如果 fileNamePattern 选项的值以 .gz 或 .zip 结尾,则自动启用文件压缩功能

fileNamePattern表达式回滚时间示例
/wombat/foo.%d.gz

按日滚动,自动对存档文件进行 GZIP 压缩

file 属性未设置:2023年11月23日期间的日志将输出到文件 /wombat/foo.2023-11-23。但是,当日日志滚动时,该文件将被压缩为 /wombat/foo.2023-11-23.gz。 11月24日,日志记录将输出到 /wombat/folder/foo.2023-11-24,同样到第二天开始滚动时进行压缩。

file 属性设置为 /wombat/foo.txt:2023年11月23日期间的日志输出到文件 /wombat/foo.txt。滚动时该文件将被压缩并重命名为 /wombat/foo.2023-11-23.gz。此外,将创建一个新的 /wombat/foo.txt 文件,用来记录11月24日期间的日志输出。 11月24日日志滚动时,/wombat/foo.txt 将被压缩并重命名为 /wombat/foo.2023-11-24.gz

        总结上边的配置信息,我们可以发现 fileNamePattern 属性具有有双重用途,首先,通过定义的日期和时间匹配模式,logback 可以获得请求的滚动周期。此外,它还可用于定义每个存档文件的名称。

        这里需要提一下,日期和时间匹配模式 yyyy-MM 和 yyyy@MM 都可以指定日志按月滚动,只不过它们生成的存档文件将带有不同的名称,比如:foo.2023-11.log,foo.2023@11.log。

        示例的配置文件内容如下:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <!--滚动策略-->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!--按日滚动-->
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

      <!--保留30天的历史记录,总大小限制为3GB-->
      <maxHistory>30</maxHistory>
      <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>

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

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

        基于文件大小和时间的滚动策略:SizeAndTimeBasedRollingPolicy

        有时后,你可能既希望按日期对日志文件进行归档,但同时又希望限制每个日志文件的大小。特别是当后期处理工具对日志文件大小有限制要求时(很多文件读取工具都有文件大小限制),这种需求会非常的迫切。

        为了满足上述这些要求,logback 也附带了基于文件大小和时间的滚动策略 SizeAndTimeBasedRollingPolicy。

        除了 "%d" 转换符之外,基于大小的滚动策略还依赖于 "%i" 转换符。在该策略下,%i 和 %d 两个转换符都是必需的。"%i" 转换符的作用,就是当前日志文件在滚动时间到达之前,如果达到 maxFileSize 时,都会从 0 开始递增索引并对其进行归档。

        下表列出了适用于 SizeAndTimeBasedRollingPolicy 的属性:

属性名称类型描述
maxFileSizeFileSize

当前日志文件在滚动时间到达之前,如果达到 maxFileSize 时,都会从 0 开始递增索引并对其进行归档。

配置值后可以添加 KB、MB 和 GB 等单位来指定字节、千字节、兆字节或千兆字节。

checkIncrementDuration检查文件大小是一项成本相对较高的操作,所以默认情况下每 60 秒执行一次。但是,你也可以设置不同的检查时间增量作为持续时间。

        需要注意的是,这些属性都只是对适用于 TimeBasedRollingPolicy 的属性的补充,也就是说,适用于 TimeBasedRollingPolicy 的属性也同样适用于 SizeAndTimeBasedRollingPolicy。

        示例的配置文件内容如下:

<configuration>

  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.txt</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!--按日滚动-->
      <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
       <!--每个文件最大100M,仅保留60天,且保留的文件的总的大小不超过20G-->
       <maxFileSize>100MB</maxFileSize>    
       <maxHistory>60</maxHistory>
       <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

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

</configuration>

        什么是触发策略(TriggeringPolicy)?

        TriggeringPolicy 用来指示 RollingFileAppender 何时滚动,TriggeringPolicy 接口仅包含一个方法。

package ch.qos.logback.core.rolling;

import ch.qos.logback.core.spi.LifeCycle;
import java.io.File;

public interface TriggeringPolicy<E> extends LifeCycle {
    boolean isTriggeringEvent(File var1, E var2);
}

        isTriggeringEvent() 方法将活动文件和当前正在处理的日志记录事件作为参数。具体实现需要根据这些参数来确定是否触发日志滚动。

        用得最多的触发策略,就是 TimeBasedRollingPolicy,它同时也实现了 RollingPolicy 接口,所以也兼作滚动策略。上边我们对 TimeBasedRollingPolicy 已经做了详细的介绍,此处不再赘述。

        至此,logback-core 模块中的 Appenders 就已经介绍完了,除了 logback-core 模块外,logback-classic 和 logback-access 模块中也有附带了很多的 Appenders,比如,SocketAppender(明文输送到远程目标)、SSLSocketAppender(加密输送到远程目标)、SMTPAppender(输送到电子邮件)、DBAppender(输送到数据库)、SyslogAppender(输送到远程日志系统)、SiftingAppender(筛选日志记录)、AsyncAppender(异步处理日志记录) 等。此外还可以自定义 Appender,因为篇幅限制,不再详细叙述,感兴趣的可以去查阅相关文档。

        至此,全文结束。

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值