log4j2 configured with the asynchronous log asyncRoot how to use disruptor

A asyncRootconfiguration corresponding mating disruptor class is AsyncLoggerConfigDisruptorwith Log4jContextSelectorthe configuration globally asynchronous boot parameters corresponding mating disruptor class is AsyncLoggerDisruptor. The following analysis isAsyncLoggerConfigDisruptor

disruptor components needed to create and start implementation

AsyncLoggerConfigDisruptor.startThe method used to create and start the disruptorinstance
created disruptor needs EventFactory, ringBuffer的大小, ThreadFactory, ProducerType, 等待策略waitStrategy
after you create needs to be set ExceptionHandler, set EventHandler.
Posted translator (production) event.

EventFactory

Whether sub-variable ( mutablefield) corresponding to two different scenarios EventFactory.
Immutable factory logic is:

@Override
public Log4jEventWrapper newInstance() {
    return new Log4jEventWrapper();
}

Variable factory logic:

public Log4jEventWrapper newInstance() {
    return new Log4jEventWrapper(new MutableLogEvent());
}

We will be in Log4jEventWrapperthe constructor passed MutableLogEventinstance.

ringBuffer size

Is a AsyncLoggerConfig.RingBufferSizecalculated configuration values.
This value is not less than the minimum configuration item 128 , the default value is set two conditions: if the ENABLE_THREADLOCALS enabled (optimization of a configuration item GC), the default value 4 * 1024, otherwise it is 256 * 1024.
This configuration is designated by the System properties, there are also different versions of the name of the case are inconsistent configuration, log4j2.asyncLoggerRingBufferSize (AsyncLogger.RingBufferSize). Details can be found here

ThreadFactory

The main thread is custom name:
thread name format is: "AsyncLoggerConfig-" + FACTORY_NUMBER (increment) + "-" + threadFactoryName + "-" + THREAD_NUMBER ( increment)
Default practical example is: Log4j2-TF-1-AsyncLoggerConfig - 1, with some differences above, the above analysis wrong? ?

ProducerType

Multi-producer

Holding policy waitStrategy

The default is 10ms of TimeoutBlockingWaitStrategy. Support configurable SleepingWaitStrategy, YieldingWaitStrategy, BlockingWaitStrategy, BusySpinWaitStrategy, TimeoutBlockingWaitStrategy.
This configuration is designated by the System properties, there are also different versions, inconsistent configuration item name case, log4j2.asyncLoggerWaitStrategy (AsyncLogger.WaitStrategy).

ExceptionHandler

You can configure, configuration item name is AsyncLoggerConfig.ExceptionHandler, the default is to use AsyncLoggerConfigDefaultExceptionHandler, print: AsyncLogger error handling event seq = ..., value = ..., and played an exception stack.

EventHandler

As used herein, the Log4jEventWrapperHandler RingBufferLogEventHandler, is disruptor of SequenceReportingEventHandler achieved.

/**
 * EventHandler performs the work in a separate thread.
 */
private static class Log4jEventWrapperHandler implements SequenceReportingEventHandler<Log4jEventWrapper> {
    private static final int NOTIFY_PROGRESS_THRESHOLD = 50;
    private Sequence sequenceCallback;
    private int counter;

    @Override
    public void setSequenceCallback(final Sequence sequenceCallback) {
        this.sequenceCallback = sequenceCallback;
    }

    @Override
    public void onEvent(final Log4jEventWrapper event, final long sequence, final boolean endOfBatch)
            throws Exception {
        event.event.setEndOfBatch(endOfBatch);
        event.loggerConfig.asyncCallAppenders(event.event);
        event.clear();

        notifyIntermediateProgress(sequence);
    }

    /**
     * Notify the BatchEventProcessor that the sequence has progressed. Without this callback the sequence would not
     * be progressed until the batch has completely finished.
     */
    private void notifyIntermediateProgress(final long sequence) {
        if (++counter > NOTIFY_PROGRESS_THRESHOLD) {
            sequenceCallback.set(sequence);
            counter = 0;
        }
    }
}

event.loggerConfig.asyncCallAppenders (event.event); this will trigger output log

translator

With EventFactorythe same points mutableis variable or two cases.
Immutable:

private static final EventTranslatorTwoArg<Log4jEventWrapper, LogEvent, AsyncLoggerConfig> TRANSLATOR =
        new EventTranslatorTwoArg<Log4jEventWrapper, LogEvent, AsyncLoggerConfig>() {
    @Override
    public void translateTo(final Log4jEventWrapper ringBufferElement, final long sequence,
            final LogEvent logEvent, final AsyncLoggerConfig loggerConfig) {
        ringBufferElement.event = logEvent;
        ringBufferElement.loggerConfig = loggerConfig;
    }
};

variable:

/**
 * Object responsible for passing on data to a RingBuffer event with a MutableLogEvent.
 */
private static final EventTranslatorTwoArg<Log4jEventWrapper, LogEvent, AsyncLoggerConfig> MUTABLE_TRANSLATOR =
        new EventTranslatorTwoArg<Log4jEventWrapper, LogEvent, AsyncLoggerConfig>() {
    @Override
    public void translateTo(final Log4jEventWrapper ringBufferElement, final long sequence,
            final LogEvent logEvent, final AsyncLoggerConfig loggerConfig) {
        ((MutableLogEvent) ringBufferElement.event).initFrom(logEvent);
        ringBufferElement.loggerConfig = loggerConfig;
    }
};

It is done a thing to the event ringBufferElement element assignment or initialization.

TryEnqueue into the event queue of logical analysis

  • prepareEvent
  1. ensureImmutable: LogEvent create a snapshot, passed in the original LogEvent will continue to be modified in the application thread, so here you want to create a snapshot
  2. Log4jLogEvent.makeMessageImmutable: formatted message. Because it is asynchronous log messages for the required format to format here, because otherwise it will change the object referenced values ​​lead to inaccurate log
  • tryPublishEvent
  1. Release event object to disruptor queue

The event processing queue

Look at the press call stack:

Daemon Thread [Log4j2-TF-1-AsyncLoggerConfig--1] (Suspended (breakpoint at line 37 in PatternFormatter))    
    PatternFormatter.format(LogEvent, StringBuilder) line: 37   
    PatternLayout$PatternSerializer.toSerializable(LogEvent, StringBuilder) line: 334   
    PatternLayout.toText(AbstractStringLayout$Serializer2, LogEvent, StringBuilder) line: 233   
    PatternLayout.encode(LogEvent, ByteBufferDestination) line: 218 
    PatternLayout.encode(Object, ByteBufferDestination) line: 58    
    ConsoleAppender(AbstractOutputStreamAppender<M>).directEncodeEvent(LogEvent) line: 177  
    ConsoleAppender(AbstractOutputStreamAppender<M>).tryAppend(LogEvent) line: 170  
    ConsoleAppender(AbstractOutputStreamAppender<M>).append(LogEvent) line: 161 
    AppenderControl.tryCallAppender(LogEvent) line: 156 
    AppenderControl.callAppender0(LogEvent) line: 129   
    AppenderControl.callAppenderPreventRecursion(LogEvent) line: 120    
    AppenderControl.callAppender(LogEvent) line: 84 
    AsyncLoggerConfig(LoggerConfig).callAppenders(LogEvent) line: 448   
    AsyncLoggerConfig.asyncCallAppenders(LogEvent) line: 129    
    AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(AsyncLoggerConfigDisruptor$Log4jEventWrapper, long, boolean) line: 111  
    AsyncLoggerConfigDisruptor$Log4jEventWrapperHandler.onEvent(Object, long, boolean) line: 97 
    BatchEventProcessor<T>.run() line: 129  
    Log4jThread(Thread).run() line: 748 

Log4jEventWrapperHandler.onEvent 111 lines are event.loggerConfig.asyncCallAppenders (event.event), see above EventHandler, where a real log write is completed.

Guess you like

Origin www.cnblogs.com/simoncook/p/10990208.html