当前位置: 首页 > 知识库问答 >
问题:

Log4j2:注册自定义TriggeringPolicy

廖令
2023-03-14

我已经为log4j2编写了一个自定义触发策略,该策略将被回滚。在每小时/天/你的工作时间间隔结束时,按照本SO帖子的建议记录文件。

虽然我遵循基于时间的触发策略约定(命名等),但我无法看到我的策略被实例化和使用。

解决方案由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>

编辑:

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

  • 在路由附件中添加结构数据过滤器
  • 在系统启动时为所有已知的${sd: type}提供一个空消息,一方面应该初始化Route appender并使FTimeBasedTriggeringPolicy在LogRotateThread中注册,但另一方面-应该被结构数据过滤器丢弃
  • 允许LogRotateThread查询已注册的FTimeBasedTriggeringPolicy并在需要时旋转日志

共有1个答案

傅志诚
2023-03-14

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

然而,最初的问题是强迫。要在时间段结束时滚动的日志文件(在我的情况下是一个小时)。为了解决这个问题,我实现了以下算法:

  1. 围绕基于时间的TriggeringPolicy(FTimeBasedTriggeringPolicy)编写了一个精简的包装器,它在LogRotateThread的实例化中注册自己
  2. 编写了一个简单的LogRotateThread,每隔几分钟查询一次注册的FTimeBasedTriggeringPolicy,并使其循环。如果需要,记录日志
  3. 在Routes appender中添加了一个StructuredDataFilter,这样它们就可以丢弃特定的消息(在我的例子中,id=SKIP)
  4. 在系统启动时向所有已知的$${sd:type}提供一条空html" target="_blank">消息,该消息:
    a.实例化路由附加器,并使FTimeBasedTriggeringPolicy在LogRotateThread中注册自己。
    b.被StructuredDataFilter丢弃

该解决方案以Apache 2.0许可证发布,可在github上获得

 类似资料:
  • 我是新来的Laravel。我有两种不同的用户类型:老师和学生。教师在网站注册表格中注册账户,但学生注册由windows应用程序提供。所以我必须为这个应用程序提供一个API。默认Laravel认证是足够的教师注册,但我可以使用相同的AuthController API注册?我不需要视图或重定向到网站。

  • 我想注册一个Avro模式,它在模式注册表上引用另一个Avro模式。 首先,我注册了以下基本Avro模式: 如果我尝试注册以下Avro架构,该架构引用“客户端”属性中的基本架构,则操作失败并出现错误422 这个问题似乎与指定自定义类型字段有关。 任何想法如何添加自定义类型,同时注册相关的模式在模式注册表?

  • 本文向大家介绍WordPress 注册自定义帖子类型,包括了WordPress 注册自定义帖子类型的使用技巧和注意事项,需要的朋友参考一下 示例 假设您有一个图书馆网站,并且想要一个名为Books的自定义帖子类型。可以注册为 如此简单,您现在就注册了一个自定义帖子类型。 该代码段可以放在主题functions.php文件中,也可以放在插件结构中。

  • 我创建一个自定义注册表单在wordpress买我有以下错误,我似乎找不到什么导致他们。 注意:未定义的变量:new_user在第219行的 /Applications/MAMP/htdocs/****/wp-内容/插件/护理匹配/carematch.php 注意:未定义的变量:错误 /Applications/MAMP/htdocs/****/wp-内容/插件/护理匹配/carematch.php

  • 问题内容: 我想在定义类时注册一个类的实例。理想情况下,以下代码可以解决问题。 不幸的是,此代码生成错误。 发生的事情是在我尝试实例化a的行上,但装饰器尚未返回,因此它不存在。 是否使用元类解决了这个问题? 问题答案: 是的,元类可以做到这一点。元类的方法返回该类,因此只需在返回之前注册该类。 前面的示例在Python 2.x中有效。在Python 3.x中,的定义略有不同(虽然未更改,但未显示-