복붙노트

[SPRING] Spring 부트 : Application Server 로깅을 방해하는 LoggingApplicationListener

SPRING

Spring 부트 : Application Server 로깅을 방해하는 LoggingApplicationListener

Spring Boot는 LoggingApplicationListener를 사용하여 기본 로깅 시스템을 자동으로 초기화합니다. 개발중인 응용 프로그램이 독립 실행 형 또는 독립 실행 형이면이 기능이 유용합니다.

그러나 (웹 인터페이스를 통해 런타임에) 중앙 로그 수준 관리, 비즈니스보고 등의 기능을 사용하여 통합 로깅 (log4j 사용)을 제공하는 WSO2 응용 프로그램 서버에 배포 할 웹 응용 프로그램을 개발하고 있습니다.

Spring Boot를 "있는 그대로"사용하면 모든 것을 완전히 자체적으로 기록합니다. 첫 번째 시도는 spring-boot-startter-logging을 제거하고 제공된대로 slf4j-api를 수동으로 추가하는 것이 었습니다. LoggingApplicationListener가 이제 WSO2가 제공하는 전역 logmanager 설정을 무시하고 (전역 첨부자를 종료하는 경우조차도) LoggingApplicationListener가 어느 정도 작동합니다.

내가 생각해 낸 유일한 "해결책"은 리플렉션을 통해 리스너를 제거하는 것입니다. 그러면 Spring Boot는 (글로벌 로거를 통해 로깅하고 미리 정의 된 로그 수준, 출력 형식, 애펜더 등을 오버라이드하지 않고) 정확하게 동작하도록 시작합니다.

그 "솔루션"은 다음과 같습니다.

@SpringBootApplication
public class MyApp extends SpringBootServletInitializer {

    public static void main(String... args) {
        SpringApplication.run(MyApp.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        try {
            Field appField = SpringApplicationBuilder.class.getDeclaredField("application");
            appField.setAccessible(true);
            SpringApplication app = (SpringApplication)appField.get(builder);

            Field listenersField = SpringApplication.class.getDeclaredField("listeners");
            listenersField.setAccessible(true);
            List<ApplicationListener<?>> listeners = (List<ApplicationListener<?>>) listenersField.get(app);
            for (int i = listeners.size() - 1; i >= 0; --i) {
                if (listeners.get(i) instanceof LoggingApplicationListener) {
                    listeners.remove(i);
                }
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return builder.sources(MyApp.class);
    }
}

내 연구 및 코드 분석 중에 간과 할 수도있는 내 문제에 대한 더 나은 솔루션이 있습니까?

해결법

  1. ==============================

    1.게시 해 주셔서 감사합니다. 매우 도움이됩니다. Websphere Aplication Server에서도 동일한 문제가있었습니다. 스프링 부트 컨텍스트를 초기화 한 후에 로그가 더 이상 없었습니다. 이 솔루션은 SpringBootServletInitializer의 run 메소드를 오버라이드하여 동등하지만 덜 위험합니다.

    게시 해 주셔서 감사합니다. 매우 도움이됩니다. Websphere Aplication Server에서도 동일한 문제가있었습니다. 스프링 부트 컨텍스트를 초기화 한 후에 로그가 더 이상 없었습니다. 이 솔루션은 SpringBootServletInitializer의 run 메소드를 오버라이드하여 동등하지만 덜 위험합니다.

    @Override
        protected WebApplicationContext run(SpringApplication application) {
            Collection<ApplicationListener<?>> listeners =
                    new ArrayList<>();
            for (ApplicationListener<?> listener: application.getListeners()) {
                if (!(listener instanceof LoggingApplicationListener)) {
                    listeners.add(listener);
                }
            }
            application.setListeners(listeners);
            return super.run(application);
        }
    
  2. ==============================

    2.Spring Boot 1.4 이후 LoggingSystem 자동 설정 기능을 비활성화 할 수 있습니다.

    Spring Boot 1.4 이후 LoggingSystem 자동 설정 기능을 비활성화 할 수 있습니다.

    Spring 문서의 Custom Log Configuration 섹션을 살펴 보자.

    Tomcat의 경우, 예를 들어 환경 변수 JAVA_OPTS를 설정하십시오.

    JAVA_OPTS="-Dorg.springframework.boot.logging.LoggingSystem=none"
    
  3. from https://stackoverflow.com/questions/29609996/spring-boot-loggingapplicationlistener-interfering-with-application-server-logg by cc-by-sa and MIT license