Настроить минимальный Log4j2 параллельно существующему SLF4J & Logback - PullRequest
0 голосов
/ 23 марта 2020

У нас есть более 200 микросервисов Spring Boot, использующих Logback в качестве своей среды ведения журналов по умолчанию через SLF4j в качестве API. Невозможно легко переключить это большое количество сервисов на использование Log4j2. Поэтому и для очень особого случая использования я хотел бы использовать только асинхронные функции в Log4j2.

К сожалению, автоматическая c конфигурация Log4j2 всегда конфигурирует SLF4LoggingContextFactory, который использует реализацию Logback в фоновом режиме. Мои попытки настроить Log4j2 независимо от инфраструктуры Logback, похоже, не работают.

Мои вопросы:

  1. Как мне остановить Log4j2, чтобы выполнить настройку по умолчанию? (stati c инициализатор в классе LogManager)
  2. Как можно просто настроить один регистратор асинхронным способом для отправки событий журнала через HTTP в API REST?

Я знаю, что конфигурация programmati c не рекомендуется командой Log4j2, но я мог бы пережить любые изменения в будущем. И, возможно, можно добавить API, который позволяет такие изменения без установки параметров виртуальной машины или работы с внутренними классами.

Ответы [ 2 ]

1 голос
/ 24 марта 2020

Первоначальная идея переконфигурировать Log4j2 не была хорошей, так как это нарушило бы ведение журнала для всех зависимостей, которые используют Log4j2 API для внутреннего использования. SLF4JLoggingContextFactory гарантирует, что все эти журналы будут перенаправлены на то, что настроено SLF4J (обычно Logback в случае приложения Spring Boot).

Таким образом, подсказка из комментария выше для создания нескольких экземпляров LoggingContextFactory была ведя меня в правильном направлении.

В следующем классе реализован очень простой регистратор с использованием подсистемы Log4j2, полностью независимый от остальной части приложения:

public class MyLogger {
    private static org.apache.logging.log4j.core.LoggerContext context;
    private static org.apache.logging.log4j.Logger logger;

    static {
        org.apache.logging.log4j.core.async.AsyncLoggerContextSelector selector = new org.apache.logging.log4j.core.async.AsyncLoggerContextSelector();
        org.apache.logging.log4j.core.impl.Log4jContextFactory factory = new org.apache.logging.log4j.core.impl.Log4jContextFactory(selector);
        context = factory.getContext(MyLogger.class.getName(), null,null, true);
        logger = context.getLogger("MyLogger");
    }

    public static void info(String message) {
        logger.info(message);
    }
}

Хорошо, что что все зависимости, использующие Log4j2 в качестве своей среды ведения журналов, будут по-прежнему использовать SLF4LoggingContextFactory, и, следовательно, все журналы отправляются в подсистему Logback. Только специальные логгеры, созданные моим экземпляром Log4jContextFactory, будут использовать бэкэнд Log4j2.

Я знаю, что это зависит от внутренних API-интерфейсов Log4j2, но поскольку он заключен в класс MyLogger, любой изменения внутренних API могут быть скрыты.

0 голосов
/ 23 марта 2020

SLF4JLoggerContextFactory является частью log4j-to-slf4j, которая направляет все вызовы Log4j API в SLF4J. В настоящее время нет способа сообщить Log4j, что для некоторых произвольных вызовов журналирования следует использовать другую реализацию. Хотя Log4j может обнаруживать несколько реализаций, он не предоставляет logi c для выбора более одного.

Если у вас есть только один вариант использования, почему проблема заключается в переключении этой одной службы на использование Log4j 2? Это не должно требовать изменений кода.

...