Расширение log4j / slf4j Logger - PullRequest
       17

Расширение log4j / slf4j Logger

0 голосов
/ 26 октября 2018

Я нахожусь в ситуации, когда несколько потоков (из одной JVM) пишут в один и тот же файл (ведение журнала с помощью Logger). Мне нужно удалить этот файл в какой-то момент, и при следующем использовании logger будет создан файл и журнал.

Библиотека журналов синхронизирована, поэтому мне не нужно беспокоиться о одновременной регистрации в одном и том же файле.

Но ... Я хочу добавить внешнюю операцию, которая управляет этим файлом, и эта операция заключается в удалении файла, поэтому мне нужно каким-то образом синхронизировать ведение журнала (Logger) с этой операцией удаления, потому что я не хочу удалять файл во время работы регистратора.

Вещи, о которых я думал:

  1. Используйте FileChannel.lock , чтобы заблокировать файл, что также делает Logger. Я решил против этого из-за этого:

Блокировки файлов хранятся от имени всей виртуальной машины Java. Oни не подходят для управления доступом к файлу несколькими потоками в той же виртуальной машине.

Это означает, что в моем случае (та же JVM, несколько потоков) это не приведет к желаемому эффекту.

Какие у меня варианты?

Мне не хватает чего-то жизненно важного?

Возможно, есть способ сделать это, используя уже существующие вещи в Logger?

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

Кажется, вы ищете функции прокрутки и архивирования журналов. Сдвиг журнала - это общая функция Log4j и Logback (также SLF4j).

Вы можете настроить библиотеку журналов для создания нового файла журнала в зависимости от размера текущего файла или времени суток. Вы можете настроить формат имени файла для свернутого файла, а затем иметь внешний архив процесса или удалить старые свернутые файлы журнала.

Вы можете обратиться к конфигурации Log4j 2, приведенной в этом ответе.

0 голосов
/ 26 октября 2018

Уловка, которую я использовал в прошлом, когда не было никакой другой возможности (см. Предложение Саптарши Басу о прокрутке журнала https://stackoverflow.com/a/53011323/823393) - просто переименовать текущий файл журнала.

После переименования все выдающиеся журналы, которые поставлены в очередь для него, продолжают переименовываться. Обычно любые новые запросы журнала создают новый файл.

Осталось только почистить переименованный. Обычно вы можете управлять этим с помощью какого-либо внешнего процесса или просто удалять любые старые файлы журналов при каждом запуске этого процесса.

0 голосов
/ 26 октября 2018

Файловые системы обычно синхронизируются операционной системой, поэтому вы можете просто удалить файл, не беспокоясь о блокировках или чем-либо еще.В зависимости от того, как log4j блокирует файл, процесс удаления может произойти сбой, и вам нужно добавить цикл повторения.

int attempts = 3;
final File logfile = new File(theLogFilePath);
while ((attempts > 0) && logfile.exists() && !logfile.delete()) {
  --attempts;
  try {
    Thread.sleep(1000);
  } catch (InterruptedException e) {
    attempts = 0;
  }
}

Это не совсем чистый код, но то, что вы делаете, не чистов любом случае.;)

Вы довольно грубо вмешиваетесь в процесс регистрации, но так как пользователь также может удалить этот файл в любое время, log4j должен справиться с этим изящно.В худшем случае я предполагаю, что сообщение, которое должно было быть зарегистрировано, будет потеряно, но это, вероятно, не проблема, учитывая, что вы в любом случае просто удалите файл журнала.

Для более чистой реализации см. thisвопрос .

...