Java 使用logback关闭时是否需要刷新事件?

Java 使用logback关闭时是否需要刷新事件?,java,logback,Java,Logback,我们正在从log4j迁移到logback,用于几个web应用程序。在关闭应用程序时,我们当前调用: org.apache.log4j.LogManager.shutdown(); 它应该刷新所有异步日志并关闭所有外部资源(文件、套接字) logback中是否有类似的东西,或者它是否会在关机时自动刷新 Mike我不知道会出现像log4j这样的全面管理器关闭,但我会在使用ServletContextListener销毁所有单个上下文记录器的上下文时关闭它们,如下所示: ContextSelecto

我们正在从log4j迁移到logback,用于几个web应用程序。在关闭应用程序时,我们当前调用:

org.apache.log4j.LogManager.shutdown();
它应该刷新所有异步日志并关闭所有外部资源(文件、套接字)

logback中是否有类似的东西,或者它是否会在关机时自动刷新


Mike

我不知道会出现像log4j这样的全面管理器关闭,但我会在使用ServletContextListener销毁所有单个上下文记录器的上下文时关闭它们,如下所示:

ContextSelector selector = StaticLoggerBinder.getSingleton().getContextSelector();
LoggerContext context = selector.detachLoggerContext(contextName);
if (context != null) {
    Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME);
    context.reset();
} else {
    System.err.printf("No context named %s was found", contextName);
}

此外,LoggerContext.stop()是可用的,在内部执行一些相同的函数,但我不使用它,因此我无法评论它是否优于重置。

这里有一个简单的方法:

import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;

...

ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
// Check for logback implementation of slf4j
if (loggerFactory instanceof LoggerContext) {
    LoggerContext context = (LoggerContext) loggerFactory;
    context.stop();
}

似乎只需将
添加到配置中就可以停止上下文

发件人:


.... 
和来自:

在指定延迟后停止Logback上下文的ShutdownHook实现。默认延迟为0毫秒(零)


从1.1.10版开始,logback负责在web应用停止或重新加载时停止当前logback经典上下文


以下是更新后的文档:

有趣的问题-我从未真正想过这一点。因为您必须显式地将log4j配置为缓冲输出,所以我假设在这种情况下可能只需要调用shutdown。我相信默认情况下slf4j缓冲区,但是.logback在每个log语句后都会刷新,因此不需要显式的stop()调用,除非您正在做一些奇怪的事情。@Davidoussel该语句让我查找。事实上:默认情况下,每个日志事件都会立即刷新到底层输出流。这种默认方法更安全,因为在应用程序退出而没有正确关闭appender的情况下,日志记录事件不会丢失。但是,为了显著提高日志吞吐量,您可能需要将底层编码器的immediateFlush属性设置为false。编码器,特别是LayoutWrappingCoder,将在单独的一章中介绍。@DavidTonhofer将immediateFlush设置为false的问题是,它仅在缓冲区已满时进行刷新。因此,如果您跟踪日志文件,则应用程序中可能发生了一个操作,但您可能在日志中看不到它,因为它位于缓冲区中,等待刷新。因此,我更喜欢使用AsyncAppender。理想情况下,当没有更多的异步日志事件挂起时,可以使用AsyncAppender和immediateFlush=false并刷新。这种方法(零延迟)的问题是,由其他关闭钩子完成的任何日志记录都将丢失,因为在它们完成之前,logback已经被关闭。您可以指定一个非零延迟,但这实际上会阻止JVM终止,直到该延迟过去。e、 g.如果我认为我的其他关闭钩子将在45秒内完成,那么我可以将logback关闭钩子延迟设置为60秒,但是我的JVM总是需要60秒才能关闭。
<configuration>
   <!-- in the absence of the class attribute, assume 
   ch.qos.logback.core.hook.DelayingShutdownHook -->
   <shutdownHook/>
  .... 
</configuration>