16

We are migrating to logback from log4j for several web apps. In the shutdown of our application we currently call:

org.apache.log4j.LogManager.shutdown();

Which is supposed to flush all async logging and close all external resources (files, sockets).

Is there something similar in logback or does it somehow flush automatically on shutdown?

Mike

Mike Schall
  • 5,829
  • 4
  • 41
  • 47
  • Interesting question - I'd never really thought about this. Since you have to explicitly configure log4j to buffer output, I'd have assumed that the shutdown might only have to be called in that case. I believe that slf4j buffers by default, though. – Steve B. Sep 09 '10 at 17:07
  • 2
    logback flushes after every log statement, so there is no need for an explicit stop() call unless you are doing something funky. – David Roussel May 04 '11 at 13:45
  • 4
    @DavidRoussel That statement made me look up [Logback Appenders](http://logback.qos.ch/manual/appenders.html). Indeed: _By default, each log event is immediately flushed to the underlying output stream. This default approach is safer in the sense that logging events are not lost in case your application exits without properly closing appenders. However, for significantly increased logging throughput, you may want to set the immediateFlush property of the underlying Encoder to false . Encoders and in particular LayoutWrappingEncoder are described in a separate chapter._ – David Tonhofer Jul 25 '14 at 16:05
  • 2
    @DavidTonhofer the problem with setting immediateFlush to false is that it only flushes when the buffer is full. So if you tail the log file an action can have happened in your app but you may not see it in the logs since it's sat in a buffer waiting for a flush. For that reason I prefer to use an AsyncAppender. Ideally there would be some way to use AsyncAppender and immediateFlush=false and flush when no more async log events are pending. But that is not implemented. – David Roussel Aug 05 '14 at 22:12

4 Answers4

9

It seems that just adding <shutdownHook/> into configuration should stop the context.

From logback docs:

<configuration>
   <!-- in the absence of the class attribute, assume 
   ch.qos.logback.core.hook.DelayingShutdownHook -->
   <shutdownHook/>
  .... 
</configuration>

And from DelayingShutdownHook summary:

ShutdownHook implementation that stops the Logback context after a specified delay. The default delay is 0 ms (zero).

Sasha
  • 1,393
  • 16
  • 17
  • The problem with this approach (with zero delay) is that any logging that is done by other shutdown hooks will be lost, because logback will have been shut down before they finish. You can specify a non-zero delay, but then that actually prevents your JVM from terminating until that delay is elapsed. e.g. if I think my other shutdown hooks will have completed in 45 seconds then I could set the logback shutdown hook delay to 60s, but then my JVM will always take 60s to shut down. – Mr Weasel Feb 26 '20 at 18:55
9

Here's a simple approach:

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();
}
David Roussel
  • 5,788
  • 1
  • 30
  • 35
0

I'm not aware of an overall manager shutdown like log4j's but I close all my individual context loggers when their context is destroyed using a ServletContextListener like so:

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

Also, LoggerContext.stop() is svailable and does some of the same functions internally but I don't use it, so I can't comment on whether its better than reset or not.

Paul Gregoire
  • 9,715
  • 11
  • 67
  • 131
0

Version 1.1.10 onwards, logback takes care of stopping the current logback-classic context when the web-app is stopped or reloaded.

Here's the updated doc: https://logback.qos.ch/manual/configuration.html#webShutdownHook

Sourabh
  • 429
  • 1
  • 4
  • 11