Как подключиться к ловушкам завершения работы с Log4j2?

Log4j2 также использует завершающие перехватчики для завершения его обслуживания. Но, конечно, я хочу регистрироваться на протяжении всего жизненного цикла моего приложения - включение включено. С Log4j это не проблема. Теперь это кажется невозможным. Регистрация отключается, пока мое приложение все еще работает над этим. Кто-нибудь надеется на меня?

С уважением Мартин

Ответ 1

Начиная с версии 2.0-beta9, это теперь настраивается в xml

<configuration ... shutdownHook="disable">

Учитывая, что теперь он отключен, мне нужно вручную отключить систему ведения журнала в конце моего отключения. Однако я не смог найти средства для внешнего интерфейса, только во внутреннем api

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.LoggerContext;
...

public static void main(String[] args) {
    final AnnotationConfigApplicationContext springContext = new AnnotationConfigApplicationContext(AppConfig.class)

    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            //shutdown application
            LOG.info("Shutting down spring context");
            springContext.close();

            //shutdown log4j2
            if( LogManager.getContext() instanceof LoggerContext ) {
                logger.info("Shutting down log4j2");
                Configurator.shutdown((LoggerContext)LogManager.getContext());
            } else
                logger.warn("Unable to shutdown log4j2");
        }
    });

    //more application initialization
}

Ответ 2

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

В первой версии Log4j предоставлял API для ручного вызова процедуры выключения. По причинам, о которых мы не знаем, он был удален из второй версии. Теперь правильный способ сделать это (в соответствии с отсутствующей документацией) состоит в том, чтобы обеспечить вашу собственную реализацию интерфейса ShutdownCallbackRegistry, который отвечает за процедуру выключения.

Предлагаемое решение

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

Вы можете найти полное решение и инструкции по GitHub/DjDCH/Log4j-StaticShutdown и использовать его в своих собственных проектах. В принципе, в конце вам нужно только сделать что-то подобное в своем приложении:

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            // Do your usual shutdown stuff here that need logging
        } finally {
            // Shutdown Log4j 2 manually
            StaticShutdownCallbackRegistry.invoke();
        }
    }
}));

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