Log4j: синхронизируется ли он для многопоточных вызовов? - PullRequest
17 голосов
/ 18 февраля 2012

Мы столкнулись с интересной проблемой, которую мы заметили во время стресс-тестирования нашей системы.Мы очень сильно используем log4j (в JBOSS) для нашей регистрации.Вот наивный пример некоторой регистрации, которую мы ведем

void someFunction()
{
Log.info("entered some function");
...

Log.info("existed some function");
}

Теперь интересная вещь, которую мы заметили, состоит в том, что если мы запустим 100 потоков для этой функции;вызовы Log.info () блокируются для каждого потока. Это означает, что поток 2 ожидает, пока поток 1 завершит вызов "Log.info".В случае резьбы 100;в конечном итоге он ждет довольно долго .. Мы используем собственный файловый регистратор.

Это известная проблема?

Ответы [ 5 ]

12 голосов
/ 18 февраля 2012

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

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

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

2 голосов
/ 20 февраля 2012

Да, log4j использует многопоточную синхронизацию.И не идеально, иногда.

Мы испытали некоторое снижение производительности, вызванное конфликтом для блокировок log4j и даже взаимоблокировками с использованием сложного метода toString ().

См. https://issues.apache.org/bugzilla/show_bug.cgi?id=24159 иhttps://issues.apache.org/bugzilla/show_bug.cgi?id=41214#c38, например.

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

Я полагаю, это одна из причин выхода из системысуществование и переключиться на собственный менеджер журналов начиная с JBoss AS 6.

2 голосов
/ 18 февраля 2012

То, что вам может понадобиться, - асинхронное ведение журнала , смотрите эту статью о том, как этого добиться:

Асинхронное ведение журнала с log4j

Также рассмотрите возможность использования правильных уровней журнала.Операторы entered... и exi(s)ted... обычно должны регистрироваться на уровне TRACE, что может быть полезно при отладке (затем настройте log4j на запись также на уровне TRACE).В производственных условиях вы можете указать log4j вести журнал только с уровня INFO или DEBUG, что исключает ненужные действия журнала.

См. Также этот вопрос о производительности log4j:

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

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

Другие уже предложили вам альтернативы, я копался в исходном коде и действительно есть раздел synchronized:

public void info(Object message) {
    if(repository.isDisabled(Level.INFO_INT))
       return;
    if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel()))
       forcedLog(FQCN, Level.INFO, message, null);
}

...

protected void forcedLog(String fqcn, Priority level, Object message, Throwable t) {
    callAppenders(new LoggingEvent(fqcn, this, level, message, t));
}

...

public void callAppenders(LoggingEvent event) {
    int writes = 0;

    for(Category c = this; c != null; c=c.parent) {
        // Protected against simultaneous call to addAppender, removeAppender,...
        synchronized(c) {
            if(c.aai != null) {
                writes += c.aai.appendLoopOnAppenders(event);
            }
            if(!c.additive) {
                break;
            }
        }
    }

    if(writes == 0) {
        repository.emitNoAppenderWarning(this);
    }
}
0 голосов
/ 21 октября 2012

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

...