2014-10-24 3 views
1

Я написал пользовательскую 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 и вращать журналы при необходимости

ответ

1

При отладке, оказалась, что Маршруты appenders (определяемый $$ {сд: типа} в моем случае) не известен во log4j2.xml разбора. Таким образом, их создание/инициализация задерживается во времени до момента поступления первого сообщения для адресата $$ {sd: type}. Таким образом, на оригинальную тему сообщения можно ответить, так как «пользовательская политика зарегистрирована, но не всегда мгновенно (или во время разбора XML-времени)».

Первоначальная проблема, однако, заключалась в том, чтобы заставить файлы .log файлов перевернуться в конце периода времени (час в моем случае). Для решения этой проблемы, я реализовал следующий алгоритм:

  1. написал тонкую оболочку вокруг TimeBasedTriggeringPolicy - FTimeBasedTriggeringPolicy, который регистрирует себя на конкретизации в LogRotateThread
  2. написал простые LogRotateThread что запросы зарегистрированного FTimeBasedTriggeringPolicy один раз каждые несколько минут и заставляет их вращаться.войти в случае необходимости
  3. добавил StructuredDataFilter к Appender маршрутов, так что они отбрасывать отдельные сообщения (с идентификатором = SKIP в моем случае)
  4. обеспечивают пустое сообщение на старте системы до всех известных $$ { sd: type}, которые:
    a. создать экземпляр приложения маршрута и заставить FTimeBasedTriggeringPolicy зарегистрироваться в LogRotateThread
    b. отбрасываются StructuredDataFilter

Решение опубликована под Apache 2.0 лицензии, а также на сайте github

Смежные вопросы