Я написал пользовательскую TriggeringPolicy для log4j2, которая, предположительно, перевернет файл .log в конце каждого часа/дня/вашего_интервала, следуя советам от this SO post.log4j2: регистрация пользовательских TriggeringPolicy
Хотя я следовал соглашениям 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:
Во время отладки я понял, что Маршруты appenders (определяется $$ {sd: type} в моем случае) не известны при анализе log4j2.xml. Таким образом - их создание/инициализация задерживается во времени до момента поступления первого сообщения для адресата $$ {sd: type}. Мой следующий план заключается в следующем:
- добавить StructuredDataFilter к маршрутам Appender
- обеспечивает пустое сообщение на старте системы до всех известных $$ {сд: тип}, которые, с одной стороны, должны инициализация маршрута Appender и вызвать FTimeBasedTriggeringPolicy зарегистрировать себя в LogRotateThread, а на другой - должны быть отброшены StructuredDataFilter
- позволяют LogRotateThread для запроса зарегистрировано FTimeBasedTriggeringPolicy и вращать журналы при необходимости