log4j2:注册自定义TriggeringPolicy [英] log4j2: registering custom TriggeringPolicy

查看:613
本文介绍了log4j2:注册自定义TriggeringPolicy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为log4j2编写了一个自定义的TriggeringPolicy,它假设按照

I have written a custom TriggeringPolicy for log4j2 that is suppose to roll-over .log file at the end of every hour/day/your_interval following advices from this SO post.

尽管我遵循了TimeBasedTriggeringPolicy约定(命名等),但是我看不到我的策略已被实例化和使用.

Though I followed TimeBasedTriggeringPolicy conventions (naming, etc) I am not able to see my policy being instantiated and used.

解决方案由3个Java文件+一个maven文件组成,可从 github 获得.
在这里,您可以从策略本身中找到主要内容:

Solution comprise of 3 java files + a maven file and is available at the github.
Here you can find main lines from the policy itself:

@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文件:

The log4j2.xml file:

<?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解析期间不知道Routes追加程序(在我的情况下由$$ {sd:type}定义).因此,它们的创建/初始化时间会延迟到目的地 $$ {sd:type} 的第一条消息到达的那一刻.我的下一个计划是:

During debugging I understood that Routes appenders (defined by the $${sd:type} in my case) are not known during log4j2.xml parsing. Thus - their creation/initialization is delayed in time to the moment when the first message for destination $${sd:type} arrives. My next plan is to:

  • 向Routes附加程序添加一个StructuredDataFilter
  • 在系统启动时为所有已知的 $$ {sd:type} 提供一条空消息,一方面,该消息应初始化Route附加程序,并导致 FTimeBasedTriggeringPolicy LogRotateThread 中注册自己,但在其他方面-应该由StructuredDataFilter丢弃
  • 允许 LogRotateThread 查询已注册的 FTimeBasedTriggeringPolicy 并根据需要轮换日志
  • add a StructuredDataFilter to the Routes appender
  • provide an empty message at the system start-up to all known $${sd:type}, which on one hand should initialize Route appender and cause FTimeBasedTriggeringPolicy to register itself in the LogRotateThread, but on other - should be discarded by the StructuredDataFilter
  • allow LogRotateThread to query registered FTimeBasedTriggeringPolicy and rotate logs if needed

推荐答案

在调试时,似乎不知道Routes附加程序(在我的情况下由 $$ {sd:type} 定义)在log4j2.xml解析期间.因此,它们的创建/初始化在时间上被延迟到到达目的地$$ {sd:type}的第一条消息的时间. 因此,帖子的原始主题可以回答为注册了自定义策略,但是并不总是立即(或在.xml解析期间)".

While debugging, it appeared that Routes appenders (defined by the $${sd:type} in my case) are not known during log4j2.xml parsing. Thus, their creation/initialization is delayed in time to the moment when the first message for the destination $${sd:type} arrives. Thus, the original subject of the post could be answered as "custom policy is registered, however not always instantly (or during the .xml parse time)".

但是,最初的问题是强制.log文件在时间段结束时(以我的情况为一个小时)进行翻转.为了解决这个问题,我实现了以下算法:

The original problem, however, was to force .log files to roll-over at the end of the time period (an hour in my case). To address it, I have implemented following algorithm:

  1. 围绕TimeBasedTriggeringPolicy- FTimeBasedTriggeringPolicy 编写了一个薄包装,该封装在LogRotateThread实例化时进行注册
  2. 编写了一个简单的 LogRotateThread ,该查询每隔几分钟就会查询已注册的FTimeBasedTriggeringPolicy,并根据需要使它们轮换.log
  3. 在Routes附加程序中添加了 StructuredDataFilter ,以便它们丢弃特定消息(在我的情况下为id = SKIP)
  4. 在系统启动时为所有已知的$$ {sd:type}提供一条空消息,其中:
    一种.实例化路由追加程序,并使FTimeBasedTriggeringPolicy在LogRotateThread中注册自己.
    b.被StructuredDataFilter丢弃
  1. wrote a thin wrapper around TimeBasedTriggeringPolicy - FTimeBasedTriggeringPolicy that registers itself on instantiation at LogRotateThread
  2. wrote a simple LogRotateThread that queries registered FTimeBasedTriggeringPolicy once every few minutes and makes them rotate .log if needed
  3. added a StructuredDataFilter to the Routes appender, so that they discard specific messages (with id=SKIP in my case)
  4. provide an empty message at the system start-up to all known $${sd:type}, which:
    a. instantiate Route appender and cause FTimeBasedTriggeringPolicy to register itself in the LogRotateThread
    b. are discarded by the StructuredDataFilter

解决方案是根据Apache 2.0许可发布的,可通过 github

Solution is published under Apache 2.0 license, and is available at github

这篇关于log4j2:注册自定义TriggeringPolicy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆