Подтвердить что ты не робот

Производительность log4j

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

Сначала я подумал, что буду использовать StringBuilders, добавить журналы к ним, и задача будет сохраняться в базе данных каждые две минуты. Потому что я беспокоился о производительности системы регистрации журналов. Затем я сделал несколько тестов. Особенно с log4j.

Вот мой код:

Main.java

public static void main(String[] args) {
  Thread[] threads = new Thread[LoggerThread.threadsNumber];

  for(int i = 0; i < LoggerThread.threadsNumber; ++i){
   threads[i] = new Thread(new LoggerThread("name - " + i));
  }
  LoggerThread.startTimestamp = System.currentTimeMillis();

  for(int i = 0; i < LoggerThread.threadsNumber; ++i){
   threads[i].start();
  }

LoggerThread.java

public class LoggerThread implements Runnable{
 public static int threadsNumber = 10;
 public static long startTimestamp;
 private static int counter = 0;
 private String name;

 public LoggerThread(String name) {
  this.name = name;
 }
 private Logger log = Logger.getLogger(this.getClass());

 @Override
 public void run() {
  for(int i=0; i<10000; ++i){
   log.info(name + ": " + i);

   if(i == 9999){
    int c = increaseCounter();

    if(c == threadsNumber){
     System.out.println("Elapsed time: " + 
       (System.currentTimeMillis() - startTimestamp));
    }
   }

  }
 }

 private synchronized int increaseCounter(){
  return ++counter;
 }

}
     }

log4j.properties

log4j.logger.main.LoggerThread=debug, f
log4j.appender.f=org.apache.log4j.RollingFileAppender
log4j.appender.f.layout=org.apache.log4j.PatternLayout
log4j.appender.f.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.f.File=c:/logs/logging.log
log4j.appender.f.MaxFileSize=15000KB
log4j.appender.f.MaxBackupIndex=50

Я думаю, что это очень распространенная конфигурация для log4j. Сначала я использовал log4j 1.2.14, тогда я понял, что существует более новая версия, поэтому я переключился на 1.2.16

Вот цифры (все в миллисекундах)

LoggerThread.threadsNumber = 10

1.2.14: 4235, 4267, 4328, 4282
1.2.16: 2780, 2781, 2797, 2781

LoggerThread.threadsNumber = 100

1.2.14: 41312, 41014, 42251
1.2.16: 25606, 25729, 25922

Я думаю, что это очень быстро. Не забывайте, что: в каждом цикле метод запуска не просто регистрируется в файле, он должен конкатенировать строки (name + ": " + i) и проверить тест if (i == 9999).

Когда threadNumber равно 10, есть 100 000 loggings и если тесты и конкатенации. Когда это 100, есть 1.000.000 loggings и если тесты и конкатенации. (Я где-то читал JVM использует приложение StringBuilder для конкатенации, а не простое конкатенацию).

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

Я читал, что: "Типичная стоимость фактического каротажа составляет от 100 до 300 микросекунд". Правильно ли это? (руководство log4J)

4b9b3361

Ответ 1

Да, Log4J известен быстро, благодаря сознательным усилиям его разработчиков. См. Также раздел "Производительность" в конце этого введение в Log4J.

Ответ 2

Если производительность является проблемой, обязательно обратите особое внимание на документацию по шаблону и избегайте дорогостоящих символов преобразования, таких как C, F, L и M. Для этого требуется, чтобы shenanigans извлекали эту информацию.

Вместо C используйте c и соответствующим образом назовите свои объекты Logger, когда они созданы. Это означает, что вы не можете наследовать регистраторы от родительских классов, но неудобство переопределения регистратора стоит увеличения производительности. F, L и M не имеют простой замены для их функциональности, но хорошо сформулированные сообщения журнала должны быть очень легко найти в вашем источнике, поэтому необходимость указывать точный метод, файл и строку уменьшается.

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

private final static Logger LOG = Logger.get(MyClass.class);
...
void someMethod() {
    if (LOG.isDebugEnabled()) {
        LOG.debug("some really expensive string concatenation: " + someInstanceVariable + " a bunch of other text!");
    }
}

Функция isDebugEnabled() всегда работает в постоянное время. Сам LOG.debug() по существу выполняет проверку isDebugEnabled() в начале, но строка, переданная как параметр, должна быть полностью построена до того, как эта проверка может произойти, вызывая ненужную задержку при отключении уровня отладки.

Ответ 3

Мне не нужно беспокоиться о log4j's производительность, даже если я в большой степени регистрирую

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

Ответ 4

шея бутылки должна быть жестким диском. ваш тест показывает примерно 1 МБ/с скорость записи на диск, что на самом деле довольно плохо.

Ответ 5

Убедитесь, что у вас есть правильная стратегия ведения журнала. Это означает, что вы определяете, что нужно регистрировать и разделять на debug, trace, info, warning и error, а также некоторые другие, если они вам понадобятся. Также убедитесь, что вы даете возможность включать и выключать его, чтобы при необходимости выполнить производительность/отладку.

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

Ответ 6

Если производительность действительно вызывает беспокойство, см. slf4j: http://www.slf4j.org/manual.html

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

Но вы можете сделать что-то подобное в log4j:

if(l.isDebugEnabled()) l.debug("log entry: " + 7);

Но я думаю, что это много шаблонов, поэтому я использую slf4j

Ответ 7

Следует отметить, что log4j страдает от многочисленных запорных болей при сильном одновременном использовании.

Более подробные сведения и некоторые обходные пути в моем другом ответе: Файл настроек продукта для log4j?

Ответ 8

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

Это то, на что работают отладка и профилировщики, регистрация - последний бастион ленивых.