log4j2:注册自定义触发策略

2023-12-13

我为 log4j2 编写了一个自定义 TriggeringPolicy ,它应该按照以下建议在每个小时/天/your_interval 结束时滚动 .log 文件这个帖子.

尽管我遵循 TimeBasedTriggeringPolicy 约定(命名等),但我无法看到我的策略被实例化和使用。

解决方案由 3 个 java 文件 + 一个 maven 文件组成,可在github.
在这里您可以找到政策本身的主要内容:

@Plugin(name = "FTimeBasedTriggeringPolicy", category = "Core", printObject = true)
public class FTimeBasedTriggeringPolicy implements TriggeringPolicy {

    private final TimeBasedTriggeringPolicy timeBasedTriggeringPolicy;  
    private RollingFileManager manager;

    private FTimeBasedTriggeringPolicy(final int interval, final boolean modulate) {
        timeBasedTriggeringPolicy = TimeBasedTriggeringPolicy.createPolicy(String.valueOf(interval), String.valueOf(modulate));
        LogRotateThread.registerPolicy(this);
    }

    public void checkRollover(final LogEvent event) {
        this.manager.checkRollover(event);
    }

    @Override
    protected void finalize() throws Throwable {
        LogRotateThread.unregisterPolicy(this);
        super.finalize();
    }

    @Override
    public void initialize(final RollingFileManager manager) {
        this.manager = manager;
        timeBasedTriggeringPolicy.initialize(manager);
    }

    @Override
    public boolean isTriggeringEvent(final LogEvent event) {
        return timeBasedTriggeringPolicy.isTriggeringEvent(event);
    }

    @Override
    public String toString() {
        return "FTimeBasedTriggeringPolicy";
    }

    @PluginFactory
    public static FTimeBasedTriggeringPolicy createPolicy(
            @PluginAttribute("interval") final String interval,
            @PluginAttribute("modulate") final String modulate) {
        final int increment = Integers.parseInt(interval, 1);
        final boolean mod = Boolean.parseBoolean(modulate);
        return new FTimeBasedTriggeringPolicy(increment, mod);
    }
}

log4j2.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="RoutingLoggingConfiguration" packages="org.log4j2plugin" verbose="true">
    <Properties>
        <Property name="routing_filename">${log.path}/table-$${sd:type}.log</Property>
    </Properties>

    <Appenders>
        <Console name="STDOUT">
            <PatternLayout pattern="%d{yyyyMMddHH}{GMT+0} %m%n"/>
        </Console>

        <Routing name="Routing">
            <Routes pattern="$${sd:type}">
                <Route>
                    <RollingFile name="RollingFile-${sd:type}"
                                 fileName="${routing_filename}"
                                 filePattern="${log.path}/%d{yyyyMMdd}{GMT+0}/%d{yyyyMMddHH}{GMT+0}-${sd:type}-${hostName}.%i.log.gz">
                        <PatternLayout>
                            <Pattern>%d{yyyyMMddHH}{GMT+0},'%d{yyyy-MM-dd HH:mm:ss}{GMT+0}',%K{v}%n</Pattern>
                        </PatternLayout>
                        <Policies>
                            <FTimeBasedTriggeringPolicy interval="1"/>
                            <SizeBasedTriggeringPolicy size="64 MB"/>
                        </Policies>
                        <DefaultRolloverStrategy max="999"/>
                    </RollingFile>
                </Route>
            </Routes>
        </Routing>
    </Appenders>

    <Loggers>
        <Logger name="EventLogger" level="debug" additivity="false">
            <AppenderRef ref="Routing"/>
        </Logger>

        <Root level="warn">
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>
</Configuration>

EDIT:

在调试过程中,我了解到路由附加程序(在我的例子中由 $${sd:type} 定义)在 log4j2.xml 解析过程中是未知的。因此 - 它们的创建/初始化被及时延迟到到达目的地的第一条消息的那一刻$${sd:类型}到达。我的下一步计划是:

  • 将 StructuredDataFilter 添加到 Routes Appender
  • 在系统启动时向所有已知的人提供一条空消息$${sd:类型},一方面应该初始化 Route Appender 并导致FTimeBased触发策略将自己注册在日志旋转线程,但在其他方面 - 应该被 StructuredDataFilter 丢弃
  • allow 日志旋转线程查询已注册的FTimeBased触发策略并根据需要轮换日志

在调试时,似乎路由附加器(由$${sd:类型}在我的例子中)在 log4j2.xml 解析期间是未知的。因此,它们的创建/初始化会及时延迟到目的地 $${sd:type} 的第一条消息到达时。 因此,帖子的原始主题可以回答为“自定义策略已注册,但并不总是立即(或在 .xml 解析时间期间)”。

然而,最初的问题是强制 .log 文件在时间段结束时(在我的例子中是一个小时)滚动。为了解决这个问题,我实现了以下算法:

  1. 围绕 TimeBasedTriggeringPolicy 编写了一个薄包装器 -FTimeBased触发策略在 LogRotateThread 实例化时注册自身
  2. 写了一个简单的日志旋转线程每隔几分钟查询一次注册的 FTimeBasedTriggeringPolicy 并根据需要使它们轮换 .log
  3. added a 结构化数据过滤器到路由附加器,以便它们丢弃特定的消息(在我的例子中 id=SKIP )
  4. 在系统启动时向所有已知的 $${sd:type} 提供一条空消息,其中:
    A。实例化 Route Appender 并导致 FTimeBasedTriggeringPolicy 在 LogRotateThread 中注册自身
    b.被 StructuredDataFilter 丢弃

解决方案在 Apache 2.0 许可证下发布,可在以下位置获取:github

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

log4j2:注册自定义触发策略 的相关文章

随机推荐

  • WhatsApp Business API 未向手机发送 /message 端点或测试消息

    我已经设置了 WhatsApp Business 来测试他们用于发送消息的新 WhatsApp API 我已按照入门指南进行操作 但在尝试发送邮件时遇到了问题测试消息到我的手机 我测试了使用业务设置中的测试消息调用发送消息 如指南中所示 并
  • 一个变量有两种类型

    我需要从 TypeScript 读取一个 JSON 对象 它有一个变量名称prop两种类型中的哪一种Identifier or Expression到 C TypeScript 可以有一个具有多种类型的变量 具有联合类型功能 例如 prop
  • 如何忽略第一个小数点后的第一个值(如果它是 0),否则如果大于 0,则取它?

    我的值如下 decimal val 1 100 现在我想做的是 如果我在第一个小数点值后有 0 那么我只想取 1 1 并忽略其余部分 如果我有 1 11 那么我想取整个 1 11 这就是我的想法 将十进制转换为字符串 按点分割字符串 检查长
  • TOMCAT 6 SSL 错误:别名无法识别密钥条目

    我正在尝试在收到 CA 后配置密钥库 我收到了一份中级 CA 和一份 CA 我已使用此命令导入它们 keytool delete alias tomcat keystore B1i keystore keytool import alias
  • 接口与抽象类[重复]

    这个问题在这里已经有答案了 在C 中 什么时候应该使用接口 什么时候应该使用抽象类 什么可能是决定因素 更新 C 8 0 新功能 从 C 8 0 开始 接口可以定义成员的默认实现 包括属性 在接口中定义属性的默认实现很少见 因为接口可能不定
  • Div 的高度不及其浮动子元素的总高度

    好吧 我在理解 float 属性的行为方面确实遇到了问题 该页面宽 750 像素 为了将其保持在屏幕中央 我使用了以下代码 div align center div align left style width 100 stuff div
  • 为 JPanel 提供基于百分比的宽度

    制作一个最简单的方法是什么JPanel占据其父容器的固定百分比 按宽度 当其父容器的宽度发生变化时 其宽度应该更新 我尝试使用Box createHorizontalStrut 但是当宽度改变时 它不会更新JPanel的父容器发生变化 你想
  • 如何解决“CastError:对于模型“任务”的路径“_id”处的值“未定义”(类型字符串),转换为 ObjectId 失败”? [复制]

    这个问题在这里已经有答案了 我对 Node JS 还是个新手 我正在尝试使用 Node JS 和 Mongo DB 制作一个图书目录 每次我按删除按钮删除一本书时 都会显示此错误 CastError Cast to ObjectId fai
  • 间歇性 MySQL 服务器已消失错误

    我一直在绞尽脑汁试图找出导致脚本间歇性错误的原因 错误是 SQLSTATE HY000 一般错误 2006 MySQL 服务器已经消失 下面的脚本是一个函数的一部分 该函数执行curl 从 JSON 响应中获取一些值 然后将它们写入表中 我
  • PDO错误处理[重复]

    这个问题在这里已经有答案了 从有关管间的教程中 我了解了一些有关执行 PDO 查询的知识 本教程使用了 try catch 查询的结构基本上如下 try dbh new PDO mysql host hostname dbname dbna
  • 捕获正在运行的进程的 FlashWindowEx 事件

    我有一个已经在运行的应用程序 它时不时地触发 FlashWindowEx 事件 Windows 7 图标闪烁 我想捕捉这个事件 但我似乎找不到任何关于如何捕捉的好信息 我的想法是事情会是这样的 使用 Process GetProcesses
  • Ajax 日历扩展器结束日期

    我正在使用 ajax 日历扩展器作为 起始日期 和 截止日期 文本框 我必须禁用 截止日期 之前的日期或小于所选 起始日期 的日期 我可以看到很多帖子使用range validation 如何在不向用户发送任何消息的情况下禁用日期 首先添加
  • Silverlight 中的 Lync 错误:客户端不受信任

    当我尝试在 Silverlight 应用程序中加载 Lync 控件时 出现错误 客户端不受信任 当我在没有相应的 Web 项目的情况下调试 Silverlight 应用程序时 不会出现此错误 这是生成错误的代码 LyncClient l L
  • 为什么 python 不能从 python 函数中调用 Javascript() ?

    我使用了建议的代码从 iPython Notebook 下载 CSV动态构建 JavaScript 代码 并在从 Jupyter Notebook 调用时使用 Python 中的 Javascript 将其传递到浏览器 代码效果很好 如果我
  • 丢失了我的密钥库,只有 SHA1

    我不小心删除了我的keystore文件 现在我无法在 Google Play 中更新我的应用程序 我只有其中的 SHA1 指纹 我想知道是否有办法创建一个新的密钥库并在那里插入该 SHA1 代码 这样我就可以使用密钥库再次管理我的应用程序
  • 如何根据张量流中的某些谓词从队列中过滤张量?

    如何使用谓词函数过滤存储在队列中的数据 例如 假设我们有一个存储特征和标签张量的队列 我们 只需要那些满足谓词的张量 我尝试了以下实现但没有成功 feature label queue dequeue if predicate featur
  • C++ 传递函数指针

    我有以下功能 static void p 我想将指向 p 的函数指针传递给函数 x void x void ptr 我正在尝试以下操作 但它不起作用 x ptr 注意 x 和 p 属于不同的类 我收到以下编译错误 invalid conve
  • 如果一个字段已填满,是否可以禁用另一个字段的输入?

    如果另一个字段包含 MS Dynamics AX 2012 中的数据 我想禁用表字段的输入 更新1 如果 Field1 有输入 Field2 和 Field3 必须为空 字段1 字段2 字段3 客户编号 身份证号 1 0000000001
  • Flutter - Android 在发布模式下不请求许可 - 自动拒绝

    在一周内我不再问这个问题之后 我就来了 我一直在尝试解决Android没有权限的问题 我用 Flutter 开发了这个应用程序 并将其上传到 Play 商店进行开放测试 但是 在发布模式下 它永远不会请求许可 只是从来没有 控制台 logc
  • log4j2:注册自定义触发策略

    我为 log4j2 编写了一个自定义 TriggeringPolicy 它应该按照以下建议在每个小时 天 your interval 结束时滚动 log 文件这个帖子 尽管我遵循 TimeBasedTriggeringPolicy 约定 命