asyncRoot
交配かく乱クラスに対応する構成があるAsyncLoggerConfigDisruptor
とLog4jContextSelector
、相手かく乱クラスをされ、対応するコンフィギュレーショングローバル非同期ブートパラメータAsyncLoggerDisruptor
。以下の分析でありますAsyncLoggerConfigDisruptor
実装を作成して開始するために必要なかく乱コンポーネント
AsyncLoggerConfigDisruptor.start
この方法は、作成および開始するために使用されるdisruptor
インスタンス
作成かく乱のニーズをEventFactory
、ringBuffer的大小
、ThreadFactory
、ProducerType
、等待策略waitStrategy
あなたが設定する必要を作成した後ExceptionHandler
、設定しますEventHandler
。
投稿翻訳者(生産)イベント。
EventFactory
(サブ変数かどうかmutable
2つの異なるシナリオEventFactoryに対応するフィールド)。
不変工場ロジックは次のとおりです。
@Override
public Log4jEventWrapper newInstance() {
return new Log4jEventWrapper();
}
可変工場・ロジック:
public Log4jEventWrapper newInstance() {
return new Log4jEventWrapper(new MutableLogEvent());
}
私たちは、になりますLog4jEventWrapper
コンストラクタ渡されたMutableLogEvent
インスタンス。
リングバッファのサイズ
でAsyncLoggerConfig.RingBufferSize
算出した設定値。
この値は、最小構成項目以上である128 ENABLE_THREADLOCALSは、(構成項目GCの最適化)を有効にした場合、デフォルト値:デフォルト値は、二つの条件が設定され4 * 1024
、それ以外です256 * 1024
。
この構成は、システムのプロパティによって指定され、ケースの名前の異なるバージョンが矛盾構成、log4j2.asyncLoggerRingBufferSize(AsyncLogger.RingBufferSize)もまた存在します。詳細を見つけることができるここに
ThreadFactory
メインスレッドは、カスタム名である:
スレッド名の形式は: "AsyncLoggerConfig-" + FACTORY_NUMBER(インクリメント)+ " - " + threadFactoryName + " - " + THREAD_NUMBER( インクリメント)
具体例をデフォルトは:Log4j2-TF-1-AsyncLoggerConfig - 1、上記のいくつかの違い、上記の分析間違っていると??
ProducerType
マルチプロデューサー
保持ポリシーwaitStrategy
デフォルトではTimeoutBlockingWaitStrategyの10ミリ秒です。設定可能なサポートSleepingWaitStrategy
、YieldingWaitStrategy
、BlockingWaitStrategy
、BusySpinWaitStrategy
、TimeoutBlockingWaitStrategy
。
この構成は、システムのプロパティによって指定され、また、異なるバージョンの、一貫性のない設定項目名の場合があり、log4j2.asyncLoggerWaitStrategy(AsyncLogger.WaitStrategy)。
exceptionHandlerの
あなたは、設定項目名がAsyncLoggerConfig.ExceptionHandlerで、設定することができ、デフォルトはAsyncLoggerConfigDefaultExceptionHandler、プリントを使用することです:AsyncLoggerエラー処理イベントのseq = ...、値= ...を、および例外スタックを果たしました。
イベントハンドラ
本明細書で使用される場合、Log4jEventWrapperHandler RingBufferLogEventHandlerは、達成SequenceReportingEventHandlerの破砕です。
/**
* 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);これは、出力ログをトリガーします
翻訳者
EventFactory
同じ点mutable
変数または2例です。
不変:
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;
}
};
変数:
/**
* 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;
}
};
これは、イベントringBufferElement要素の割り当てや初期化に事をしています。
論理的な分析のイベントキューにTryEnqueue
- prepareEvent
- ensureImmutableは:スナップショットを作成したいので、ここでは、アプリケーションのスレッドで変更され続ける、元のLogEventに渡されたスナップショットを作成LOGEVENT
- Log4jLogEvent.makeMessageImmutable:フォーマットされたメッセージ。それ以外の場合は、参照値が不正確ログにつながるオブジェクトを変更しますので、ここでフォーマットするために必要な形式の非同期ログメッセージであるため、
- tryPublishEvent
- かく乱キューにイベントオブジェクトをリリース
イベント処理キュー
プレスコールスタックを見てください:
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行は、実際のログの書き込みが完了したイベントハンドラ、上記参照、event.loggerConfig.asyncCallAppenders(event.event)です。