Class AsyncDisruptorAppender<Event extends DeferredProcessingAware,Listener extends AppenderListener<Event>>

java.lang.Object
ch.qos.logback.core.spi.ContextAwareBase
ch.qos.logback.core.UnsynchronizedAppenderBase<Event>
net.logstash.logback.appender.AsyncDisruptorAppender<Event,Listener>
Type Parameters:
Event - type of event (ILoggingEvent or IAccessEvent).
All Implemented Interfaces:
Appender<Event>, ContextAware, FilterAttachable<Event>, LifeCycle
Direct Known Subclasses:
AbstractLogstashTcpSocketAppender, DelegatingAsyncDisruptorAppender

public abstract class AsyncDisruptorAppender<Event extends DeferredProcessingAware,Listener extends AppenderListener<Event>> extends UnsynchronizedAppenderBase<Event>
An asynchronous appender that uses an LMAX Disruptor RingBuffer as the interthread data exchange mechanism (as opposed to a BlockingQueue used by logback's AsyncAppender).

See the LMAX Disruptor documentation for more information about the advantages of using a RingBuffer over a BlockingQueue.

The behavior of the appender when the RingBuffer is full and the event cannot be published is controlled by the appendTimeout configuration parameter. By default the appender drops the event immediately, and emits a warning message every droppedWarnFrequency consecutive dropped events. It can also be configured to wait until some space is available, with or without timeout.

A single handler thread will be used to handle the actual handling of the event.

Subclasses must implement createEventHandler() to provide a EventHandler to define the logic that executes in the handler thread. For example, DelegatingAsyncDisruptorAppender will delegate appending of the event to another appender in the handler thread.

By default, child threads created by this appender will be daemon threads, and therefore allow the JVM to exit gracefully without needing to explicitly shut down the appender. Note that in this case, it is possible for appended log events to not be handled (if the child thread has not had a chance to process them yet). By setting setDaemon(boolean) to false, you can change this behavior. When false, child threads created by this appender will not be daemon threads, and therefore will prevent the JVM from shutting down until the appender is explicitly shut down. Set this to false if you want to ensure that every log event prior to shutdown is handled.

  • Field Details

    • APPENDER_NAME_FORMAT

      protected static final String APPENDER_NAME_FORMAT
      See Also:
    • THREAD_INDEX_FORMAT

      protected static final String THREAD_INDEX_FORMAT
      See Also:
    • DEFAULT_THREAD_NAME_FORMAT

      public static final String DEFAULT_THREAD_NAME_FORMAT
      See Also:
    • DEFAULT_RING_BUFFER_SIZE

      public static final int DEFAULT_RING_BUFFER_SIZE
      See Also:
    • DEFAULT_PRODUCER_TYPE

      public static final com.lmax.disruptor.dsl.ProducerType DEFAULT_PRODUCER_TYPE
    • DEFAULT_WAIT_STRATEGY

      public static final com.lmax.disruptor.WaitStrategy DEFAULT_WAIT_STRATEGY
    • DEFAULT_DROPPED_WARN_FREQUENCY

      public static final int DEFAULT_DROPPED_WARN_FREQUENCY
      See Also:
    • listeners

      protected final List<Listener extends AppenderListener<Event>> listeners
      These listeners will be notified when certain events occur on this appender.
  • Constructor Details

    • AsyncDisruptorAppender

      public AsyncDisruptorAppender()
  • Method Details

    • start

      public void start()
      Specified by:
      start in interface LifeCycle
      Overrides:
      start in class UnsynchronizedAppenderBase<Event extends DeferredProcessingAware>
    • stop

      public void stop()
      Specified by:
      stop in interface LifeCycle
      Overrides:
      stop in class UnsynchronizedAppenderBase<Event extends DeferredProcessingAware>
    • createEventHandler

      protected abstract com.lmax.disruptor.EventHandler<AsyncDisruptorAppender.LogEvent<Event>> createEventHandler()
      Create the EventHandler to process events as they become available from the RingBuffer. This method is invoked when the appender is started by start() and a new Disruptor is initialized.
      Returns:
      a EventHandler instance.
    • isRingBufferEmpty

      protected boolean isRingBufferEmpty()
      Test whether the ring buffer is empty or not
      Returns:
      true if the ring buffer is empty, false otherwise
    • append

      protected void append(Event event)
      Specified by:
      append in class UnsynchronizedAppenderBase<Event extends DeferredProcessingAware>
    • prepareForDeferredProcessing

      protected void prepareForDeferredProcessing(Event event)
    • calculateThreadName

      protected String calculateThreadName()
    • getThreadNameFormatParams

      protected List<Object> getThreadNameFormatParams()
    • fireAppenderStarted

      protected void fireAppenderStarted()
    • fireAppenderStopped

      protected void fireAppenderStopped()
    • fireEventAppended

      protected void fireEventAppended(Event event, long durationInNanos)
    • fireEventAppendFailed

      protected void fireEventAppendFailed(Event event, Throwable reason)
    • safelyFireEvent

      protected void safelyFireEvent(Consumer<Listener> callback)
    • setEventFactory

      protected void setEventFactory(AsyncDisruptorAppender.LogEventFactory<Event> eventFactory)
    • getEventTranslator

      protected com.lmax.disruptor.EventTranslatorOneArg<AsyncDisruptorAppender.LogEvent<Event>,Event> getEventTranslator()
    • setEventTranslator

      protected void setEventTranslator(com.lmax.disruptor.EventTranslatorOneArg<AsyncDisruptorAppender.LogEvent<Event>,Event> eventTranslator)
    • getDisruptor

      protected com.lmax.disruptor.dsl.Disruptor<AsyncDisruptorAppender.LogEvent<Event>> getDisruptor()
    • getThreadNameFormat

      public String getThreadNameFormat()
    • setThreadNameFormat

      public void setThreadNameFormat(String threadNameFormat)
      Pattern used by the to set the handler thread names. Defaults to "logback-appender-%1$s-%2$d".

      If you change the threadFactory, then this value may not be honored.

      The string is a format pattern understood by Formatter.format(String, Object...). Formatter.format(String, Object...) is used to construct the actual thread name prefix. The first argument (%1$s) is the string appender name. The second argument (%2$d) is the numerical thread index. Other arguments can be made available by subclasses.

      Parameters:
      threadNameFormat - the thread name format pattern
    • getRingBufferSize

      public int getRingBufferSize()
      Returns the maximum number of events allowed in the queue.
      Returns:
      the size of the ring buffer
    • setRingBufferSize

      public void setRingBufferSize(int ringBufferSize)
      Sets the size of the RingBuffer. Must be a positive power of 2. Defaults to 8192.

      If the handler thread is not as fast as the producing threads, then the RingBuffer will eventually fill up, at which point events will be dropped or the producing threads are blocked depending on appendTimeout.

      Parameters:
      ringBufferSize - the maximum number of entries in the queue.
    • getProducerType

      public com.lmax.disruptor.dsl.ProducerType getProducerType()
      Get the ProducerType configured for the Disruptor.
      Returns:
      the ProducerType.
    • setProducerType

      @Deprecated public void setProducerType(com.lmax.disruptor.dsl.ProducerType producerType)
      Deprecated.
      ProducerType will be fixed to MULTI in future release and this method removed without any replacement.
      The ProducerType to use to configure the Disruptor. By default this is ProducerType.MULTI. Can be set to ProducerType.SINGLE for increase performance if (and only if) only one thread will ever be appending to this appender.

      WARNING: unexpected behavior may occur if this parameter is set to ProducerType.SINGLE and multiple threads are appending to this appender.

      Parameters:
      producerType - the type of producer
    • getWaitStrategy

      public com.lmax.disruptor.WaitStrategy getWaitStrategy()
    • setWaitStrategy

      public void setWaitStrategy(com.lmax.disruptor.WaitStrategy waitStrategy)
    • setWaitStrategyType

      public void setWaitStrategyType(String waitStrategyType)
    • getAppendRetryFrequency

      public Duration getAppendRetryFrequency()
    • setAppendRetryFrequency

      public void setAppendRetryFrequency(Duration appendRetryFrequency)
    • getAppendTimeout

      public Duration getAppendTimeout()
    • setAppendTimeout

      public void setAppendTimeout(Duration appendTimeout)
    • setShutdownGracePeriod

      public void setShutdownGracePeriod(Duration shutdownGracePeriod)
    • getShutdownGracePeriod

      public Duration getShutdownGracePeriod()
    • getThreadFactory

      public ThreadFactory getThreadFactory()
    • setThreadFactory

      public void setThreadFactory(ThreadFactory threadFactory)
    • getDroppedWarnFrequency

      public int getDroppedWarnFrequency()
    • setDroppedWarnFrequency

      public void setDroppedWarnFrequency(int droppedWarnFrequency)
    • isDaemon

      public boolean isDaemon()
    • setDaemon

      public void setDaemon(boolean useDaemonThread)
    • addListener

      public void addListener(Listener listener)
    • removeListener

      public void removeListener(Listener listener)
    • isAddDefaultStatusListener

      public boolean isAddDefaultStatusListener()
    • setAddDefaultStatusListener

      public void setAddDefaultStatusListener(boolean addDefaultStatusListener)