Оптимизация записи на диск для Java Logger - PullRequest
1 голос
/ 01 февраля 2011

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

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

Спасибо.

Ответы [ 6 ]

2 голосов
/ 01 февраля 2011

Ожидается потеря производительности на 5-10% при полном ведении журнала отладки.Это кажется приемлемым для наших клиентов.

Если код для генерации части контента для выхода из системы дорог, рассмотрите возможность использования простого теста, подобного этому, чтобы избежать выполнения этого кода при отключенной отладке:

if (log.isLoggable(Level.FINEST)) {
  // code to generate the log entry
}

Вы также можете создать java.util.logging.MemoryHandler и отправить файл в регулярный интервал.

1 голос
/ 30 октября 2012

Pexus недавно выпустила пакет ведения журнала производительности с открытым исходным кодом - PerfLog, который также включает в себя регистратор приложений на основе java.util.logging. * API. Он включает опцию для асинхронного ведения журнала с использованием Common J Work Manager, который доступен во всех контейнерах J2EE (1.4+) Для получения дополнительной информации см .: http://www.pexus.com/perflog

1 голос
/ 03 февраля 2012

Хороший ответ Йохена Бедерсдорфа, а just4log - это система, которая сделает это автоматически для вас - с помощью постобработки.Поэтому вам не придется портить свой код с помощью операторов if вокруг операторов log.

0 голосов
/ 03 февраля 2012

Вы должны проверить Logback . Те же авторы, что и log4j, если я не ошибаюсь.

Основываясь на нашей предыдущей работе над log4j, внутренние компоненты logback были переписан для выполнения примерно в десять раз быстрее на определенных критических пути выполнения. Компоненты logback не только быстрее, они имеют меньший объем памяти.

0 голосов
/ 01 февраля 2011

Используйте более современную библиотеку журналов, такую ​​как log4j или slf4j , которые поддерживают асинхронные / буферизованные приложения.

В log4j вы можете использовать AsyncAppender (который обеспечивает возможность буферизации) и подключить к нему FileAppender:

AsyncAppender будет собирать отправленные ему события и затем отправлять их всем прикрепленным к нему приложениям.Это.Вы можете прикрепить несколько приложений к AsyncAppender.

AsyncAppender использует отдельный поток для обслуживания событий в своем буфере.

Таким образом, события записываются на диск в контролируемомтаким образом, и ваши потоки, выполняющие реальную работу, не связаны с дисковым вводом-выводом.

Или, как более простой вариант, подумайте, действительно ли вам нужен полный вывод журналов при запуске этой программы.Часто бывает слишком сложно запускать приложение в рабочей среде с регистрацией на уровне DEBUG.

0 голосов
/ 01 февраля 2011

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

Если вы хотите еще больше контроля, вы можете реализовать свой собственный appender. Предполагая, что вы хотите добавить файл, вы можете переопределить подпрограмму append для FileAppender .

Например,

public class BatchingFileAppender extends FileAppender {
   private List<LoggingEvent> batch = new LinkedList<LoggingEvent>;
   public static final int BATCH_SIZE = 10;


   @Override
   protected void append(LoggingEvent event) {
       batch.add(event);

       // you can even optionally push ever 10'th or so messages to file
       if (batch.size() == BATCH_SIZE) {
           appendBatch();
       }
   }

   @Override
   protected void reset() {
       appendBatch();
   }

   @Override
   protected void closeWriter() {
       appendBatch();
   } 

   private void appendBatch() {
       for(LoggingEvent event : batch) {
           super.append(event);
       }
       batch.clear();
   }

}
...