programing

Spring Boot: ApplicationListener 로깅이 Application Server 로깅을 방해합니다.

topblog 2023. 7. 22. 09:09
반응형

Spring Boot: ApplicationListener 로깅이 Application Server 로깅을 방해합니다.

Spring Boot은 다음을 사용하여 기본 로깅 시스템을 자동으로 초기화합니다.LoggingApplicationListener내가 개발 중인 응용프로그램이 독립적으로 실행되거나 독립적으로 실행되는 경우 이는 좋은 일입니다.

그러나 저는 WSO2 애플리케이션 서버에 배포될 웹 애플리케이션을 개발하고 있습니다. 이 애플리케이션은 중앙 로그 수준 관리(웹 인터페이스를 통한 런타임 시), 비즈니스 보고 등의 기능을 갖춘 통합 로깅(log4j 사용)을 제공합니다.

Spring Boot를 "있는 그대로" 사용하면 모든 것이 자동으로 기록됩니다.내 첫 번째 샷은, 제거하는 것이었습니다.spring-boot-starter-logging수동으로 추가합니다.slf4j-api~하듯이provided이것은 어느 정도 효과가 있습니다, 왜냐하면LoggingApplicationListener이제 WSO2에서 제공하는 글로벌 로그 관리자의 설정을 재정의합니다(글로벌 추가 기능이 닫히기도 함).

제가 생각해낸 유일한 "해결책"은 반성을 통해 듣는 사람을 제거하는 것입니다.그런 다음 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);
    }
}

연구 및 코드 분석 과정에서 간과했을 수 있는 덜 촌스러운 문제에 대한 더 나은 해결책이 있을까요?

게시물을 올려주셔서 감사합니다. 매우 도움이 됩니다.Websphere Application Server에서도 동일한 문제가 발생했습니다. 봄 부팅 컨텍스트를 초기화한 후 로그가 더 이상 없습니다.이 솔루션은 SpringBootServlet의 실행 방법을 재정의하여 동일하지만 덜 더럽습니다.이니셜라이저:

@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);
    }

Spring Boot 1.4 이후 Logging System 자동 구성을 비활성화할 수 있습니다.

Spring 문서의 Custom Log Configuration 섹션을 확인하십시오.

를 사용하여 Spring Boot가 특정 로깅 시스템을 사용하도록 강제할 수 있습니다.org.springframework.boot.logging.LoggingSystem시스템 속성.값은 의 정규화된 클래스 이름이어야 합니다.LoggingSystem실행.또한 다음 값을 사용하여 Spring Boot의 로깅 구성을 완전히 비활성화할 수 있습니다.none.

예를 들어 Tomcat의 경우 환경 변수를 설정합니다.JAVA_OPTS:

JAVA_OPTS="-Dorg.springframework.boot.logging.LoggingSystem=none"

언급URL : https://stackoverflow.com/questions/29609996/spring-boot-loggingapplicationlistener-interfering-with-application-server-logg

반응형