Uploaded image for project: 'logback'
  1. logback
  2. LOGBACK-271

introduce FlushableAppender

    XMLWordPrintable

Details

    • Icon: Improvement Improvement
    • Resolution: Duplicate
    • Icon: Minor Minor
    • None
    • None
    • logback-core
    • None
    • Operating System: Linux
      Platform: PC

    • 141

    Description

      Suggest a new sub-interface of Appender:

      public interface FlushableAppender<E> extends Appender<E>, java.io.Flushable
      {
      }

      Then, WriterAppender could be defined to implement FlushableAppender, with this simple implementation:

      public void flush() throws IOException

      { writer.flush(); }

      This would allow manual flushing of the appenders. This is particularly useful when buffered IO is used, obviously. It allows, for instance, to manually flush all appenders when a request has been fully processed, ensuring that we retain the benefits of buffered IO while also having the full logs after request processing.

      Here's sample code I used to get all appenders (run once after Logback configuration):

      public static Set<Appender> getAllAppenders()
      {
      ContextSelector selector = StaticLoggerBinder.SINGLETON.getContextSelector();
      LoggerContext loggerContext = selector.getLoggerContext();

      Map<String, Appender> appenders = newHashMap();

      // loop through all Loggers
      for ( Logger logger : loggerContext.getLoggerList() )
      {
      // for each logger, loop through all its appenders
      Iterator iter = logger.iteratorForAppenders();
      while ( iter.hasNext() )

      { // appenders are uniquely identified by name, so store them in the Map thus // this will overwrite the same entry in the Map many times (with the same reference) Appender appender = ( Appender ) iter.next(); appenders.put( appender.getName(), appender ); }

      }

      return newHashSet( appenders.values() );
      }

      The below bean is used in Spring, calling flush() forces all appenders to be flushed:

      public class LogbackFlushBean implements Flushable
      {
      protected final Logger log = LoggerFactory.getLogger( getClass() );

      private final Collection<FlushableAppender> flushableAppenders = newLinkedList();

      @PostConstruct
      public void loadFlushableAppenders()
      {
      for ( Appender appender : LogbackConfigurer.getAllAppenders() )
      {
      if ( appender instanceof FlushableAppender )

      { flushableAppenders.add( ( FlushableAppender ) appender ); }

      else
      {
      log.debug( "appender {} is not Flushable, skipping", appender.getName() );
      }
      }
      }

      public void flush() throws IOException
      {
      for ( FlushableAppender appender : flushableAppenders )
      {
      log.debug( "flushing appender {}", appender.getName() );
      appender.flush();
      }
      }
      }

      Attachments

        Activity

          People

            ceki Ceki Gülcü
            bruno.navert Bruno Navert
            Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: