Spring Boot: LoggingApplicationListener beeinträchtigt die Application Server-Protokollierung

Spring Boot initialisiert das zugrunde liegende Protokollierungssystem automatisch mit demLoggingApplicationListener. Dies ist eine nette Sache, wenn die Anwendung, die ich entwickle, isoliert oder eigenständig ausgeführt wird.

Jedoch entwickle ich eine Webanwendung, die auf dem WSO2-Anwendungsserver bereitgestellt wird und eine einheitliche Protokollierung (mit log4j) mit Funktionen wie zentraler Verwaltung der Protokollebene (zur Laufzeit über die Weboberfläche), Geschäftsberichte usw. bietet.

Wenn ich Spring Boot "so wie es ist" verwende, wird alles komplett von alleine protokolliert. Mein erster Schuss war, @ zu entfernspring-boot-starter-logging und manuell hinzufügenslf4j-api wieprovided. Dies funktioniert bis zu einem gewissen Grad, da dasLoggingApplicationListener überschreibt jetzt die von WSO2 bereitgestellten Einstellungen des globalen Protokollmanagers (und führt sogar dazu, dass globale Appender geschlossen werden).

Die einzige "Lösung", die ich mir ausgedacht habe, ist, den Hörer durch Reflektion zu entfernen. Dann verhält sich Spring Boot genau so, wie es sein sollte (Protokollierung über den globalen Protokollierer und nicht Überschreiben der vordefinierten Protokollierungsstufen, Ausgabeformate, Appender usw.)

Diese "Lösung" sieht so aus:

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

Gibt es eine bessere Lösung für mein Problem, die vielleicht weniger hacky ist, als ich es bei meiner Recherche und Code-Analyse übersehen habe?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage