Spring boot 记录失败时停止Spring引导应用程序(log4j2)

Spring boot 记录失败时停止Spring引导应用程序(log4j2),spring-boot,security,logging,log4j2,Spring Boot,Security,Logging,Log4j2,我有一个标准的springbootmicro服务,它使用Log4j2进行所有日志记录 我想优雅地关闭spring boot应用程序,以防日志记录失败(例如,磁盘已满)。有没有办法设置它 参考资料: -->这个问题没有回答这个具体的问题。 -->阅读FailoverAppender的文档,我不确定这是否符合要求。我想您需要做的是通过其他机制检测剩余磁盘,而不是依赖记录器来检测它。 Spring boot actuator用于提供许多指标,包括内存和磁盘。它使外部服务能够通过HTTP端点从正在运行的

我有一个标准的springbootmicro服务,它使用Log4j2进行所有日志记录

我想优雅地关闭spring boot应用程序,以防日志记录失败(例如,磁盘已满)。有没有办法设置它

参考资料: -->这个问题没有回答这个具体的问题。
-->阅读FailoverAppender的文档,我不确定这是否符合要求。

我想您需要做的是通过其他机制检测剩余磁盘,而不是依赖记录器来检测它。 Spring boot actuator用于提供许多指标,包括内存和磁盘。它使外部服务能够通过HTTP端点从正在运行的实例获取度量

查看执行器如何在此处获得磁盘空间: 表明该机制很简单:

@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
    long diskFreeInBytes = this.path.getUsableSpace();
    if (diskFreeInBytes >= this.threshold.toBytes()) {
        builder.up();
    }
    else {
        logger.warn(LogMessage.format("Free disk space below threshold. Available: %d bytes (threshold: %s)",
                diskFreeInBytes, this.threshold));
        builder.down();
    }
    builder.withDetail("total", this.path.getTotalSpace()).withDetail("free", diskFreeInBytes)
            .withDetail("threshold", this.threshold.toBytes()).withDetail("exists", this.path.exists());
}
在主应用程序类中,您可以使用如上所示的相同机制定期检查磁盘空间,如果磁盘空间低于特定阈值,则关闭应用程序上下文。关闭应用程序可能是这样的:

int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
@Override
public int getExitCode() {
        // return the error code
        return 0;
    }
});

 
System.exit(exitCode);

每个Appender都由Log4j 2中的Appender控件包装。AppenderControl捕获Appender抛出的任何异常。它的默认行为是将错误处理程序附加到Appender并调用其error()方法。当该方法返回时,它将检查属性“ignoreExceptions”是否为false(默认为true),如果为false,它将重新显示异常

理想情况下,您可以实现自己的错误处理程序,但编写代码的人(我)忘了将其设置为可配置的。看


FailoverAppender设计用于包装一个appender,然后在发生错误时故障转移到另一个appender。这要求在目标appender上将ignoreExceptions设置为false。您可以复制FailoverAppender来创建自己的自定义追加器,在错误发生时执行关闭。

Spring boot附带一个执行器,该执行器具有(默认情况下禁用)
关闭
端点。 基本上,启用此端点后,可以通过JMX或HTTP关闭spring引导应用程序。到目前为止,这是我所知道的优雅地关闭spring boot应用程序的最佳方式

这个端点的源代码是可用的,您可以很容易地看到它在应用程序上下文上调用了
close
方法


现在回答您的问题,我从未使用过log4j2,但作为一个想法,您可以创建自己的appender,它将包装分配给记录器的真实appender,它可以捕获异常并调用
close
方法(在这种情况下,它还必须维护对应用程序上下文的引用)或者通过JMX调用
shutdown
端点。这可以“补充”@rgoers提供的答案,他从log4j2的角度解决了这个问题。

感谢您的评论。但是,日志记录失败可能不仅仅是因为磁盘错误。我只举磁盘已满为例