Файлы журнала не переносятся с помощью log4j 1.2.17 и java8u162 - PullRequest
0 голосов
/ 28 мая 2018

Мы столкнулись с проблемой в производственной среде, где в некоторых ситуациях файлы журнала не переносятся.Мы используем Log4j версии 1.2.17 вместе с apache.commons-logging.Пользовательский appender создается для пролонгации файлов.Appender расширяет FileAppender из Log4j.Вот алгоритм метода subAppend (событие LoggingEvent):

long n = System.currentTimeMillis();
// Has the time come to roll the log file?
if (n >= nextCheck)
{
 now.setTime(n);
    nextCheck = rc.getNextCheckMillis(now);

    rollOver();
    reachedMaxSize = false;

 else
 {
     File f = new File(getFile());

     // Has the log file has exceeded its maximum size?
     if (!reachedMaxSize && f.length() > maxFileSize)
     {
         // Log file has reached it maximum size.
         reachedMaxSize = true;

         // Log one last message to the file stating the max has been reached.
         LoggingEvent exeededEvent = new LoggingEvent(
                      getClass().getName(),
                      Logger.getLogger(getClass().getName()),
                      Priority.ERROR,
                      "Maximum log file size has been reached ("+maxFileSize/1024+"KB)",
                      null);
       super.subAppend(exeededEvent);
     }

 // If the log has not reached its max size, write it. Otherwise,
 // send log event to stdout.
 if (!reachedMaxSize)
 {
     super.subAppend(event);
 }
 else
 {
     System.out.println(event.getRenderedMessage());
 }

Вот файл Log4j.properties

log4j.rootLogger=INFO,RCFLog

log4j.appender.RCFLog=com.ge.medit.util.logging.MaxFileSizeRollingFileAppender
log4j.appender.RCFLog.File=runtime/logs/rcf.log
log4j.appender.RCFLog.DatePattern=yyyyMMdd'_'{0}
log4j.appender.RCFLog.Encoding=UTF-8
log4j.appender.RCFLog.Append=true

log4j.appender.ConsoleLog=org.apache.log4j.ConsoleAppender
log4j.appender.ConsoleLog.layout=org.apache.log4j.PatternLayout
log4j.appender.ConsoleLog.layout.ConversionPattern=%p [%t] %c{1}: %m%n

log4j.appender.RCFLog.layout=org.apache.log4j.PatternLayout
log4j.appender.RCFLog.layout.ConversionPattern=@%d{yyyyMMdd HH:mm:ss.SSS}@ %p {%t} %c{1}: %m%n

log4j.logger.GUIEVT=INFO

Согласно наблюдению, в системе произошло изменение даты,Дата была установлена ​​за 3 месяца до текущей даты.

Current Date- 10th May 2018
nextCheck - 11th May 2018 00:00
Changed Date- 10th March 2018
No backup is created as a condition at line 3 failed.

Через 12 часов 11 мая дата была изменена на текущую дату.К этому времени временная метка файла была изменена на 10 марта.Так как RollOver не было, следующая проверка была еще 11 мая 2018 года 00:00.Но 12 мая в 00:00 файл должен был быть перенесен в соответствии с условием в строке 3, и должен был быть создан новый файл, которого не было.Кроме того, файл достиг максимального размера.С тех пор не было никаких журналов, пока система не была перезагружена.

Версия Java java8u162 .Хотя я не смог найти ни одного сообщения, в котором говорилось бы, связано ли это с java.

Тот же сценарий, который я пытался воспроизвести в тестовой среде, но там все работает, как ожидалось.

Есть кто-нибудькогда-нибудь сталкивался с такой проблемой с Log4j?Пожалуйста, поделитесь своими мнениями.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Я получил причину, по которой файлы не были скопированы.Было несколько изменений даты.Было отмечено, что дата была сначала изменена на 10/05/2036, а затем позднее изменена на 2021 и вернулась к 10/03/2018, после чего мы окончательно изменили дату на текущую дату 05/05/2018.

Итак, когда дата была изменена на будущую дату 10/05/2036.Дата следующей проверки была обновлена ​​до 05.05.2036.Опять же, когда дата была изменена обратно на текущую дату, то вышеупомянутое, если условие не выполнено (сейчас (11/05/2018> = 11/05/2036). Таким образом, резервное копирование будет выполняться только тогда, когда дата будет изменена на 11/05 /2036 или более.

Необходимо изменить условие if (n> = nextCheck) на if if (n> = nextCheck || nextCheck - n> TimeConstants.MILLISECONDS_PER_DAY. Это изменение еще не проверено.

Спасибо @ Марк Брамник за быстрый ответ.

0 голосов
/ 28 мая 2018

Я считаю, что лучший способ - это просто отладить код, log4j можно отлаживать, как и любой другой код, без этого мы можем только строить догадки.

Я вижу из ваших конфигураций, что вы используете com.ge.medit.util.logging.MaxFileSizeRollingFileAppender, который не является стандартным приложением для прокрутки файлов в log4j (возможно, пользовательским приложением вашей компании, которое может содержать ошибки).

Если вы не можете отладить его, я могу предоставить только пару советов, которые, надеюсь, могут помочь.

  1. Модифицируйте appender и используйте org.apache.log4j.helpers.LogLog, чтобы напечатать некоторую информацию о работе самого appender, это похоже на «вход в систему в log4j» - что-то, что идет в System.out / System.ошибка в зависимости от уровня серьезности

  2. Обычно пролонгация (см. функцию «ролловер») осуществляется в виде серии «переименований» файлов.Я однажды видел (опять же, только предположение), что этот метод будет работать, только если:

    • у вас есть разрешения на файлы
    • ваше приложение обладает единственным дескриптором файла (особенно актуально)для ОС Windows).

Отладку легко отследить, поскольку технически переименование, вероятно, выполняется с помощью java.io.File#renameTo, который возвращает true / false в зависимости от того, имеет ли операция переименованияудалось или не удалось.

Чтобы смоделировать эту ситуацию, вы можете развернуть «скрытый» код, который просто «заполняет» журнал сообщениями (вы можете использовать JMX, внутренний веб-сервлет / обработчик сообщений - все, что выхотите, но внутри он может содержать множество сообщений журнала (фальшивых) в цикле, что-то вроде этого:

class MyHiddenMBean {
    Logger logger = ...
    public void doLogManyTimes(int times) {
         for(int i = 0; i < times; i++) {
             logger.info("Artificial Logging Message : " + i);
         }
    } 
}

Вы сразу достигнете максимальный файл (конечно, вы можете поместить его намеренно смехотворно маленькиммоделировать быстрее) и тогда вы сможете понять, почему renameTo не работает

...