Spring boot Spring正在重置我的日志配置-如何解决这个问题?

Spring boot Spring正在重置我的日志配置-如何解决这个问题?,spring-boot,logback,Spring Boot,Logback,我有一个Spring批处理工作,负责处理传入的客户文件。其中一个要求是日志记录是为了将客户运行的每个作业的日志文件分开 在应用程序的main中,我处理命令行参数,然后从中动态创建FileAppender My logback.xml: <configuration> <appender name="Console" class="ch.qos.logback.core.ConsoleAppender"> <encoder>

我有一个Spring批处理工作,负责处理传入的客户文件。其中一个要求是日志记录是为了将客户运行的每个作业的日志文件分开

在应用程序的main中,我处理命令行参数,然后从中动态创建FileAppender

My logback.xml:

<configuration>
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="Console" />
    </root>
</configuration>
从EventPublishingRunListener:

几次呼叫后,再登录ApplicationListener:

在LogbackLoggingSystem和AbstractLoggingSystem中:

点击上面最后一个else,并调用重新初始化:

@Override
protected void reinitialize() {
    getLoggerContext().reset();
    loadConfiguration(getSelfInitializationConfig(), null);
}
在上下文中调用reset可以重置所有内容。问题是,深入研究loadConfiguration方法也会将reset方法调用为日志上下文

关于如何绕过Spring重置我的日志配置,有什么想法吗


仅供参考,我使用的是Spring的4.1.4.RELEASE版本。

这听起来像是将日志配置的自定义推迟到LoggingApplicationListener运行后才开始工作

LoggingApplicationListener执行初始化以响应ApplicationEnvironmentPreparedEvent,其顺序为Ordered.HIGHEST_priority+11。为防止覆盖自定义配置,您可以将自定义逻辑封装在SmartApplicationListener中,该SmartApplicationListener响应同一事件,但顺序较低,以便在记录ApplicationListener后运行:


这个问题与Spring或Spring批处理无关,都与Spring引导有关。答案100%正确。谢谢你,安迪。我有完全相同的问题,但这个解决方案不适合我。我自己已经找到了同样的潜在解决方案,但由于某种原因,我的听众从来没有机会听ApplicationEnvironmentPreparedEvent和其他人的演讲。例如,如果我向supportsEventType添加一个断点,则调用它的全部内容是:ContextRefreshedEvent、EmbeddedServletContainerInitializedEvent、ApplicationReadyEvent和ContextClosedEvent。ApplicationEnvironmentPreparedEvent应该比所有其他事件都早,它从不触发我的侦听器。有人知道为什么吗?我刚知道为什么我的情况下它不起作用。我在应用程序类中使用@Import注册了侦听器,而不是在SpringApplicationBuilder中直接调用侦听器方法。因此,我的侦听器没有及时注册许多事件,包括ApplicationEnvironmentPreparedEvent。我想知道这种行为是否是预期的和记录的,或者它是否是一个bug。是的,这是预期的@在刷新应用程序上下文之前不会处理导入。True。而且它实际上是有文件记录的
try {
    // Create and configure the environment
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    configureEnvironment(environment, args);
    for (SpringApplicationRunListener runListener : runListeners) {
        runListener.environmentPrepared(environment);
    }

    ...
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
    publishEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args,
        environment));
}

private void publishEvent(SpringApplicationEvent event) {
    this.multicaster.multicastEvent(event);
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
    if (event instanceof ApplicationStartedEvent) {
        onApplicationStartedEvent((ApplicationStartedEvent) event);
    }
    else if (event instanceof ApplicationEnvironmentPreparedEvent) {
        onApplicationPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
    }
}

private void onApplicationPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
    if (this.loggingSystem == null) {
        this.loggingSystem = LoggingSystem.get(event.getSpringApplication()
            .getClassLoader());
    }
    initialize(event.getEnvironment(), event.getSpringApplication().getClassLoader());
}

protected void initialize(ConfigurableEnvironment environment, ClassLoader classLoader) {
    if (System.getProperty(PID_KEY) == null) {
        System.setProperty(PID_KEY, new ApplicationPid().toString());
    }
    initializeEarlyLoggingLevel(environment);
    initializeSystem(environment, this.loggingSystem);
    initializeFinalLoggingLevels(environment, this.loggingSystem);
}

private void initializeSystem(ConfigurableEnvironment environment,
        LoggingSystem system) {
    LogFile logFile = LogFile.get(environment);
    String logConfig = environment.getProperty(CONFIG_PROPERTY);
    if (StringUtils.hasLength(logConfig)) {
        try {
            ResourceUtils.getURL(logConfig).openStream().close();
            system.initialize(logConfig, logFile);
        }
        catch (Exception ex) {
            this.logger.warn("Logging environment value '" + logConfig
                + "' cannot be opened and will be ignored "
                + "(using default location instead)");
            system.initialize(null, logFile);
        }
    }
    else {
        system.initialize(null, logFile);
    }
}
@Override
public void initialize(String configLocation, LogFile logFile) {
    getLogger(null).getLoggerContext().getTurboFilterList().remove(FILTER);
    super.initialize(configLocation, logFile);
}

@Override
public void initialize(String configLocation, LogFile logFile) {
    if (StringUtils.hasLength(configLocation)) {
        // Load a specific configuration
        configLocation = SystemPropertyUtils.resolvePlaceholders(configLocation);
        loadConfiguration(configLocation, logFile);
    }
    else {
        String selfInitializationConfig = getSelfInitializationConfig();
        if (selfInitializationConfig == null) {
            // No self initialization has occurred, use defaults
            loadDefaults(logFile);
        }
        else if (logFile != null) {
            // Self initialization has occurred but the file has changed, reload
            loadConfiguration(selfInitializationConfig, logFile);
        }
        else {
            reinitialize();
        }
    }
}
@Override
protected void reinitialize() {
    getLoggerContext().reset();
    loadConfiguration(getSelfInitializationConfig(), null);
}
public class CustomLoggingConfigurationApplicationListener implements
    SmartApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {    
        // Customise the logging configuration
    }   

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 12;
    }

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType);
    }

    @Override
    public boolean supportsSourceType(Class<?> sourceType) {
        return true;
    }

}
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class)
                .listeners(new CustomLoggingConfigurationApplicationListener())
                .run(args);
    }
}