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

聊聊logback的TimeBasedRollingPolicy

本文主要研究一下logback的TimeBasedRollingPolicy

TimeBasedRollingPolicy

public class TimeBasedRollingPolicy<E> extends RollingPolicyBase implements TriggeringPolicy<E> {static final String FNP_NOT_SET = "The FileNamePattern option must be set before using TimeBasedRollingPolicy. ";// WCS: without compression suffixFileNamePattern fileNamePatternWithoutCompSuffix;private Compressor compressor;private RenameUtil renameUtil = new RenameUtil();Future<?> compressionFuture;Future<?> cleanUpFuture;private int maxHistory = UNBOUNDED_HISTORY;protected FileSize totalSizeCap = new FileSize(UNBOUNDED_TOTAL_SIZE_CAP);private ArchiveRemover archiveRemover;TimeBasedFileNamingAndTriggeringPolicy<E> timeBasedFileNamingAndTriggeringPolicy;boolean cleanHistoryOnStart = false;//......
}    

TimeBasedRollingPolicy继承了RollingPolicyBase,它定义了maxHistory、cleanHistoryOnStart、timeBasedFileNamingAndTriggeringPolicy等属性

start

    public void start() {// set the LR for our utility objectrenameUtil.setContext(this.context);// find out period from the filename patternif (fileNamePatternStr != null) {fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);determineCompressionMode();} else {addWarn(FNP_NOT_SET);addWarn(CoreConstants.SEE_FNP_NOT_SET);throw new IllegalStateException(FNP_NOT_SET + CoreConstants.SEE_FNP_NOT_SET);}compressor = new Compressor(compressionMode);compressor.setContext(context);// wcs : without compression suffixfileNamePatternWithoutCompSuffix = new FileNamePattern(Compressor.computeFileNameStrWithoutCompSuffix(fileNamePatternStr, compressionMode), this.context);addInfo("Will use the pattern " + fileNamePatternWithoutCompSuffix + " for the active file");if (compressionMode == CompressionMode.ZIP) {String zipEntryFileNamePatternStr = transformFileNamePattern2ZipEntry(fileNamePatternStr);zipEntryFileNamePattern = new FileNamePattern(zipEntryFileNamePatternStr, context);}if (timeBasedFileNamingAndTriggeringPolicy == null) {timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<>();}timeBasedFileNamingAndTriggeringPolicy.setContext(context);timeBasedFileNamingAndTriggeringPolicy.setTimeBasedRollingPolicy(this);timeBasedFileNamingAndTriggeringPolicy.start();if (!timeBasedFileNamingAndTriggeringPolicy.isStarted()) {addWarn("Subcomponent did not start. TimeBasedRollingPolicy will not start.");return;}// the maxHistory property is given to TimeBasedRollingPolicy instead of to// the TimeBasedFileNamingAndTriggeringPolicy. This makes it more convenient// for the user at the cost of inconsistency here.if (maxHistory != UNBOUNDED_HISTORY) {archiveRemover = timeBasedFileNamingAndTriggeringPolicy.getArchiveRemover();archiveRemover.setMaxHistory(maxHistory);archiveRemover.setTotalSizeCap(totalSizeCap.getSize());if (cleanHistoryOnStart) {addInfo("Cleaning on start up");Instant now = Instant.ofEpochMilli(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());cleanUpFuture = archiveRemover.cleanAsynchronously(now);}} else if (!isUnboundedTotalSizeCap()) {addWarn("'maxHistory' is not set, ignoring 'totalSizeCap' option with value [" + totalSizeCap + "]");}super.start();}

start方法根据fileNamePatternStr创建FileNamePattern,根据compressionMode创建Compressor,对于zip压缩的创建zipEntryFileNamePattern,另外默认设置了DefaultTimeBasedFileNamingAndTriggeringPolicy,然后执行其start,对于maxHistory不为0的,则设置archiveRemover

stop

   public void stop() {if (!isStarted())return;waitForAsynchronousJobToStop(compressionFuture, "compression");waitForAsynchronousJobToStop(cleanUpFuture, "clean-up");super.stop();}private void waitForAsynchronousJobToStop(Future<?> aFuture, String jobDescription) {if (aFuture != null) {try {aFuture.get(CoreConstants.SECONDS_TO_WAIT_FOR_COMPRESSION_JOBS, TimeUnit.SECONDS);} catch (TimeoutException e) {addError("Timeout while waiting for " + jobDescription + " job to finish", e);} catch (Exception e) {addError("Unexpected exception while waiting for " + jobDescription + " job to finish", e);}}}    

stop方法执行waitForAsynchronousJobToStop,主要是等待compressionFuture及cleanUpFuture

rollover

    public void rollover() throws RolloverFailure {// when rollover is called the elapsed period's file has// been already closed. This is a working assumption of this method.String elapsedPeriodsFileName = timeBasedFileNamingAndTriggeringPolicy.getElapsedPeriodsFileName();String elapsedPeriodStem = FileFilterUtil.afterLastSlash(elapsedPeriodsFileName);if (compressionMode == CompressionMode.NONE) {if (getParentsRawFileProperty() != null) {renameUtil.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);} // else { nothing to do if CompressionMode == NONE and parentsRawFileProperty ==// null }} else {if (getParentsRawFileProperty() == null) {compressionFuture = compressor.asyncCompress(elapsedPeriodsFileName, elapsedPeriodsFileName,elapsedPeriodStem);} else {compressionFuture = renameRawAndAsyncCompress(elapsedPeriodsFileName, elapsedPeriodStem);}}if (archiveRemover != null) {Instant now = Instant.ofEpochMilli(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());this.cleanUpFuture = archiveRemover.cleanAsynchronously(now);}}

rollover方法通过timeBasedFileNamingAndTriggeringPolicy获取elapsedPeriodsFileName,然后将当前文件重命名为elapsedPeriodsFileName,对于archiveRemover不为null的则执行cleanAsynchronously

ArchiveRemover

ch/qos/logback/core/rolling/helper/ArchiveRemover.java

public interface ArchiveRemover extends ContextAware {void clean(Instant instant);void setMaxHistory(int maxHistory);void setTotalSizeCap(long totalSizeCap);Future<?> cleanAsynchronously(Instant now);
}

ArchiveRemover定义了clean、setMaxHistory、setTotalSizeCap、cleanAsynchronously方法

TimeBasedArchiveRemover

ch/qos/logback/core/rolling/helper/TimeBasedArchiveRemover.java

public class TimeBasedArchiveRemover extends ContextAwareBase implements ArchiveRemover {static protected final long UNINITIALIZED = -1;// aim for 32 days, except in case of hourly rollover, see// MAX_VALUE_FOR_INACTIVITY_PERIODSstatic protected final long INACTIVITY_TOLERANCE_IN_MILLIS = 32L * (long) CoreConstants.MILLIS_IN_ONE_DAY;static final int MAX_VALUE_FOR_INACTIVITY_PERIODS = 14 * 24; // 14 days in case of hourly rolloverfinal FileNamePattern fileNamePattern;final RollingCalendar rc;private int maxHistory = CoreConstants.UNBOUNDED_HISTORY;private long totalSizeCap = CoreConstants.UNBOUNDED_TOTAL_SIZE_CAP;final boolean parentClean;long lastHeartBeat = UNINITIALIZED;public TimeBasedArchiveRemover(FileNamePattern fileNamePattern, RollingCalendar rc) {this.fileNamePattern = fileNamePattern;this.rc = rc;this.parentClean = computeParentCleaningFlag(fileNamePattern);}//......
}    

TimeBasedArchiveRemover定义了fileNamePattern、rollingCalendar、maxHistory、totalSizeCap属性

clean

    public void clean(Instant now) {long nowInMillis = now.toEpochMilli();// for a live appender periodsElapsed is expected to be 1int periodsElapsed = computeElapsedPeriodsSinceLastClean(nowInMillis);lastHeartBeat = nowInMillis;if (periodsElapsed > 1) {addInfo("Multiple periods, i.e. " + periodsElapsed+ " periods, seem to have elapsed. This is expected at application start.");}for (int i = 0; i < periodsElapsed; i++) {int offset = getPeriodOffsetForDeletionTarget() - i;Instant instantOfPeriodToClean = rc.getEndOfNextNthPeriod(now, offset);cleanPeriod(instantOfPeriodToClean);}}public void cleanPeriod(Instant instantOfPeriodToClean) {File[] matchingFileArray = getFilesInPeriod(instantOfPeriodToClean);for (File f : matchingFileArray) {addInfo("deleting " + f);f.delete();}if (parentClean && matchingFileArray.length > 0) {File parentDir = getParentDir(matchingFileArray[0]);removeFolderIfEmpty(parentDir);}}    

clean方法主要是计算periodsElapsed,然后通过rollingCalendar获取instantOfPeriodToClean,再执行cleanPeriod方法;cleanPeriod方法则通过getFilesInPeriod获取对应的文件,然后挨个执行delete,最后再判断下parentDir是否为空,为空则删除

cleanAsynchronously

    public Future<?> cleanAsynchronously(Instant now) {ArhiveRemoverRunnable runnable = new ArhiveRemoverRunnable(now);ExecutorService executorService = context.getExecutorService();Future<?> future = executorService.submit(runnable);return future;}public class ArhiveRemoverRunnable implements Runnable {Instant now;ArhiveRemoverRunnable(Instant now) {this.now = now;}@Overridepublic void run() {clean(now);if (totalSizeCap != UNBOUNDED_TOTAL_SIZE_CAP && totalSizeCap > 0) {capTotalSize(now);}}}    

cleanAsynchronously主要是创建ArhiveRemoverRunnable,然后提交到context的executorService;ArhiveRemoverRunnable实现了Runnable接口,其run方法执行clean,对于totalSizeCap大于0的执行capTotalSize

小结

TimeBasedRollingPolicy包含了RollingPolicy及TriggeringPolicy,其rollover方法主要是委托给timeBasedFileNamingAndTriggeringPolicy获取elapsedPeriodsFileName然后去rename,对于maxHistory不是无限制的设置timeBasedFileNamingAndTriggeringPolicy的archiveRemover的maxHistory及totalSizeCap,执行其cleanAsynchronously方法;其isTriggeringEvent方法也是委托给了timeBasedFileNamingAndTriggeringPolicy。

相关文章:

聊聊logback的TimeBasedRollingPolicy

序 本文主要研究一下logback的TimeBasedRollingPolicy TimeBasedRollingPolicy public class TimeBasedRollingPolicy<E> extends RollingPolicyBase implements TriggeringPolicy<E> {static final String FNP_NOT_SET "The FileNamePattern option must…...

numpy 基础使用

NumPy是Python中科学计算的基础包。它是一个Python库&#xff0c;提供多维数组对象&#xff0c;各种派生对象&#xff08;如掩码数组和矩阵&#xff09;&#xff0c;以及用于数组快速操作的各种API&#xff0c;有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变…...

sqlite3编译脚本

../configure --hostarm --buildx86 CC/opt/sdk/gcc-arm-8.3-arm-armv5t-linux-gnueabi/bin/arm-armv5t-linux-gnueabi-gcc --prefix/opt/sdk/gcc-arm-8.3-arm-armv5t-linux-gnueabi/arm-armv5t-linux-gnueabi/sysroot/usr...

环形链表解析(c语言)c语言版本!自我解析(看了必会)

目录 1.判断一个表是否是环形链表&#xff01; 代码如下 解析如下 2.快指针的步数和慢指针的步数有什么影响&#xff08;无图解析&#xff09; 3.怎么找到环形链表的入环点 代码如下 解析如下 1.判断一个表是否是环形链表&#xff01; 代码如下 bool hasCycle(struct L…...

科技云报道:数智化升级,如何跨越数字世界与实体产业的鸿沟?

科技云报道原创。 数智化是当下商业环境下最大的确定性。 2022年&#xff0c;中国数字经济规模达50.2万亿元&#xff0c;占国内生产总值比重提升至41.5%&#xff0c;数字经济成为推动经济发展的重要引擎。从小型创业公司到跨国巨头&#xff0c;数字化转型在企业发展历程中彰显…...

Rt-Thread 移植6--多线程(KF32)

6.1 就绪列表 6.1.1 线程就绪优先级组 线程优先级表的索引对应的线程的优先级。 为了快速的找到线程在线程优先级表的插入和移出的位置&#xff0c;RT-Thread专门设计了一个线程就绪优先级组。线程就绪优先组是一个32位的整型数&#xff0c;每一个位对应一个优先级&#xff…...

HarmonyOS应用开发-首选项与后台通知管理

首选项 在移动互联网蓬勃发展的今天&#xff0c;移动应用给我们生活带来了极大的便利&#xff0c;这些便利的本质在于数据的互联互通。因此在应用的开发中数据存储占据了非常重要的位置&#xff0c;HarmonyOS应用开发也不例外。本章以HarmonyOS的首选项为例&#xff0c;介绍了…...

通过easyexcel导出数据到excel表格

这篇文章简单介绍一下怎么通过easyexcel做数据的导出&#xff0c;使用之前easyui构建的歌曲列表crud应用&#xff0c;添加一个导出按钮&#xff0c;点击的时候直接连接后端接口地址&#xff0c;在后端的接口完成数据的导出功能。 前端页面完整代码 let editingId; let request…...

Android---MVP 中 presenter 声明周期的管理

我们经常在 Android MVP 架构中的 Presenter 层做一些耗时操作&#xff0c;比如请求网络数据&#xff0c;然后根据请求后的结果刷新 View。但是&#xff0c;如果按返回结束 Activity&#xff0c;而 Presenter 依然在执行耗时操作。那么就有可能造成内存泄漏&#xff0c;严重时甚…...

Oracle中的索引碎片

索引碎片是指索引在存储空间上不连续的分布情况&#xff0c;它可能会影响到数据库性能和查询效率。索引碎片化主要由以下几个原因导致&#xff1a; 插入、更新和删除操作&#xff1a;当对表中的数据进行插入、更新或删除操作时&#xff0c;索引也需要相应地更新。这些DML操作可…...

Java必刷入门递归题×5(内附详细递归解析图)

目录 1.求N的阶乘 2.求12...N的和 3.顺序打印数字的每一位 4.求数字的每一位之和 5.求斐波拉契数列 1.求N的阶乘 &#xff08;1&#xff09;解析题目意思 比如求5的阶乘&#xff0c;符号表示就是5&#xff01;&#xff1b;所以5&#xff01;5*4*3*2*1我们下面使用简单的…...

android 闪屏图适配尺寸

不同的 Android 设备可能具有不同的屏幕尺寸和分辨率&#xff0c;因此最好提供不同尺寸的启动画面图像&#xff0c;以确保与各种设备的兼容性。 以下是 Android 启动画面图像的一些最常见尺寸&#xff1a; 320 x 480像素&#xff08;肖像&#xff09; 480 x 320像素&#xff0…...

正则表达式中(?s)与(?m)的区别

理论&#xff1a; (?m) 和 (?s) 是正则表达式中的两个模式标志&#xff0c;它们具有不同的作用&#xff1a; (?m) 多行模式标志&#xff08;也称为 “multiline” 模式&#xff09;&#xff1a; 默认情况下&#xff0c;正则表达式将整个输入字符串视为单行多行文本中使用…...

Clickhouse学习笔记(11)—— 数据一致性

使用合并树引擎时&#xff0c;无论是ReplacingMergeTree还是SummingMergeTree&#xff0c;都只能保证数据的最终一致性&#xff0c;因为数据的去重、聚合等操作会在数据合并的期间进行&#xff0c;而合并会在后台以一个不确定的时间进行&#xff0c;因此无法预先计划&#xff1…...

【uniapp】六格验证码输入框实现

效果图 代码实现 <view><view class"tips">已发送验证码至<text class"tips-phone">{{ phoneNumber }}</text></view><view class"code-input-wrap"><input class"code-input" v-model"…...

【react hook】在react hook组件中,使用Antd Table组件,columns数据异步获取,list数据更新但没有rerender解决办法

情景描述 我们有一个react组件&#xff0c;显示了一个Antd Table组件&#xff0c;设置了一个columns变量并复制给Table的columns属性&#xff0c;由于我们请求的datasource来源是异步的&#xff0c;示例伪代码如下&#xff1a; const [columns, setColumns] useState([]); /…...

ChatGPT的图识别来了

前几天ChatGPT推出了Dall-E 3功能&#xff0c;可以根据文字和描述一段话来生成一个或者一组图。 这次又来重磅了&#xff0c;图识别又来了&#xff01;换句话说&#xff0c;也即是文生图&#xff0c;图生文都可以实现了&#xff0c;一起来试试 1、解释图中的意思 &#xff0…...

java Stream编程笔记

文章目录 Stream介绍什么是 Stream&#xff1f; Stream中间操作过滤操作&#xff08;filter&#xff09;映射操作&#xff08;map&#xff09;排序操作&#xff08;sorted&#xff09;截断操作&#xff08;limit 和 skip&#xff09; Stream 的终止操作forEach 和 peek聚合操作…...

顶顶通语音识别使用说明

介绍 顶顶通语音识别软件(asrproxy)是一个对接了多种语音识别接口的语音识别系统。可私有化部署(支持中文英文和方言等&#xff0c;支持一句话识别、实时流识别、多声道录音文件识别。 原理 asrproxy内嵌了阿里达摩院的开源语音识别工具包FunASR,后续我们也会使用自有的预料…...

重磅发布 OpenAI 推出用户自定义版 ChatGPT

文章目录 重磅发布 OpenAI 推出用户自定义版 ChatGPT个人简介 重磅发布 OpenAI 推出用户自定义版 ChatGPT OpenAI 首届开发者大会 (OpenAI DevDay) 于北京时间 11 月 7 日凌晨 02:00 开始&#xff0c;大会上宣布了一系列平台更新。其中一个重要更新是用户可以创建他们自己的自定…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...

AT模式下的全局锁冲突如何解决?

一、全局锁冲突解决方案 1. 业务层重试机制&#xff08;推荐方案&#xff09; Service public class OrderService {GlobalTransactionalRetryable(maxAttempts 3, backoff Backoff(delay 100))public void createOrder(OrderDTO order) {// 库存扣减&#xff08;自动加全…...

day51 python CBAM注意力

目录 一、CBAM 模块简介 二、CBAM 模块的实现 &#xff08;一&#xff09;通道注意力模块 &#xff08;二&#xff09;空间注意力模块 &#xff08;三&#xff09;CBAM 模块的组合 三、CBAM 模块的特性 四、CBAM 模块在 CNN 中的应用 一、CBAM 模块简介 在之前的探索中…...