我为 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触发策略并根据需要轮换日志