log4j2: расположение для установки системного свойства Log4jContextSelector для асинхронного ведения журнала

Я пытаюсь настроить асинхронное ведение журнала (по соображениям производительности) в веб-методах REST, которые в настоящее время выполняются на сервере профилей liberty.

для этого я установил следующее свойство:

System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");

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

я попробовал (a) в конструкторе для класса, содержащего все остальные веб-методы b) в фильтре метод doFilter, вызываемый до Метода REST c) в методе init фильтра (d) в самом методе REST

ни одно из этих местоположений не работает последовательно.

может ли кто-нибудь предложить объяснение этого поведения и, если возможно, предложенный способ устранения проблемы.

EDIT: похоже, что log4j инициализируется до вызова setProperty. Поэтому мне нужно настроить свойство через профиль liberty.

4 ответов


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

Добавить файл с именем log4j2.component.properties в вашем classpath. Это можно сделать в большинстве проектов maven или gradle, сохранив его в src/main/resources.

это файл просто . Задайте значение для селектора контекста, добавив в файл следующую строку.

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

Log4j попытается прочитать систему сначала собственность. Если системное свойство имеет значение null, то оно будет возвращаться к значениям, хранящимся в этом файле по умолчанию.

код, который выполняет эту настройку, находится по адресу Log4jContextFactory.java: 91.

File Location


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

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

public class MainClass {
    // NOTE: Nothing can appear before this initializer
    // NOTE: This initializer must be in the class that contains your entry point
    static {
        System.setProperty("Log4jContextSelector",
            "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
    }

    public static void main(final String[] args) {
        // Do anything you want to here
    }
}

согласно спецификации Java, статическая инициализация происходит в том порядке, в котором она объявлена. Следовательно,System.setProperty вызов гарантированно произойдет до инициализации Log4j.


поэтому, по-видимому, мне нужно было добавить строку в jvm.файл параметров

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

jvm.файл опций находится здесь:

${server.config.dir}/jvm.options

и этот каталог можно найти по ссылке:

http://www-01.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.wlp.doc/ae/rwlp_dirs.html?cp=SSEQTP_8.5.5%2F1-3-11-0-2-0

в моем случае это: C:\eclipse\runtime\usr\servers\serverName


Log4j был инициализирован перед вызовом метода main. Поэтому он не может выбрать свойство Log4jContextSelector из системы и по умолчанию работает синхронно.

чтобы проверить то же самое: удалите зависимость disruptor, если ваш проект все еще идет вверх, то он не становится асинхронным.

Если вы добавляете свойство через-DLog4jContextSelector=org.апаш.лесозаготовительный.к log4j.ядро.асинхронный.AsyncLoggerContextSelector после удаления проекта disruptor не пойдет вверх.

Если вы используете tomcat, добавьте системные свойства в catalina.свойства. И не забудьте использовать immediateFlush= "false".