当前位置: 首页 > news >正文

【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、释放guardthis.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,因为篇幅限制,不再详细叙述,感兴趣的可以去查阅相关文档。

        至此,全文结束。

相关文章:

  • C#使用Stack<T>类进行堆栈设计
  • Mybatis Plus + Spring 分包配置 ClickHouse 和 Mysql 双数据源
  • 【零基础学习04】嵌入式linux驱动中信号量功能基本实现
  • 网工内推 | 国企、上市公司网工、运维,CCNA即可,补贴福利多
  • IP数据报格式
  • 数据结构导航 -- 38篇
  • C语言 指针(5) 数组和指针题解析
  • 基于LSTM实现春联上联对下联
  • 批量提取PDF指定区域内容到 Excel 以及根据PDF里面第一页的标题来批量重命名-附思路和代码实现
  • 【InternLM 笔记】使用InternLM2-chat-1.8b制作时事问答知识库
  • zabbix 7.0编译部署教程
  • leetcode刷题(javaScript)——分治思想(二分查找、快速排序)相关场景题总结
  • 【Linux】-Linux下的软件商店yum工具介绍(linux和windows互传文件仅仅一个拖拽搞定!!!!)
  • Flutter第四弹:Flutter图形渲染性能
  • 银河麒麟V10SP3操作系统-网络时间配置
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • input实现文字超出省略号功能
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Python学习之路13-记分
  • Python中eval与exec的使用及区别
  • SwizzleMethod 黑魔法
  • ViewService——一种保证客户端与服务端同步的方法
  • 安装python包到指定虚拟环境
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 简单数学运算程序(不定期更新)
  • 力扣(LeetCode)357
  • 聊聊redis的数据结构的应用
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 正则表达式
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • Mac 上flink的安装与启动
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • # Java NIO(一)FileChannel
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • # 透过事物看本质的能力怎么培养?
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #define,static,const,三种常量的区别
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #Z2294. 打印树的直径
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (06)Hive——正则表达式
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)fiber的基本认识
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • .md即markdown文件的基本常用编写语法
  • .NET Core IdentityServer4实战-开篇介绍与规划