Class AsyncLogger
- java.lang.Object
-
- org.apache.logging.log4j.spi.AbstractLogger
-
- org.apache.logging.log4j.core.Logger
-
- org.apache.logging.log4j.core.async.AsyncLogger
-
- All Implemented Interfaces:
com.lmax.disruptor.EventTranslatorVararg<RingBufferLogEvent>
,java.io.Serializable
,Logger
,ExtendedLogger
,LocationAwareLogger
,Supplier<LoggerConfig>
public class AsyncLogger extends Logger implements com.lmax.disruptor.EventTranslatorVararg<RingBufferLogEvent>
AsyncLogger is a logger designed for high throughput and low latency logging. It does not perform any I/O in the calling (application) thread, but instead hands off the work to another thread as soon as possible. The actual logging is performed in the background thread. It uses LMAX Disruptor for inter-thread communication.To use AsyncLogger, specify the System property
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
before you obtain a Logger, and all Loggers returned by LogManager.getLogger will be AsyncLoggers.Note that for performance reasons, this logger does not include source location by default. You need to specify
includeLocation="true"
in the configuration or any %class, %location or %line conversion patterns in your log4j.xml configuration will produce either a "?" character or no output at all.For best performance, use AsyncLogger with the RandomAccessFileAppender or RollingRandomAccessFileAppender, with immediateFlush=false. These appenders have built-in support for the batching mechanism used by the Disruptor library, and they will flush to disk at the end of each batch. This means that even with immediateFlush=false, there will never be any items left in the buffer; all log events will all be written to disk in a very efficient manner.
- See Also:
- Serialized Form
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) class
AsyncLogger.TranslatorType
-
Nested classes/interfaces inherited from class org.apache.logging.log4j.core.Logger
Logger.LoggerProxy, Logger.PrivateConfig
-
-
Field Summary
Fields Modifier and Type Field Description private static Clock
CLOCK
private static ContextDataInjector
CONTEXT_DATA_INJECTOR
private boolean
includeLocation
private static StatusLogger
LOGGER
private AsyncLoggerDisruptor
loggerDisruptor
private NanoClock
nanoClock
private static ThreadNameCachingStrategy
THREAD_NAME_CACHING_STRATEGY
private java.lang.ThreadLocal<RingBufferLogEventTranslator>
threadLocalTranslator
private AsyncLogger.TranslatorType
threadLocalTranslatorType
private AsyncLogger.TranslatorType
varargTranslatorType
-
Fields inherited from class org.apache.logging.log4j.core.Logger
privateConfig
-
Fields inherited from class org.apache.logging.log4j.spi.AbstractLogger
CATCHING_MARKER, DEFAULT_FLOW_MESSAGE_FACTORY_CLASS, DEFAULT_MESSAGE_FACTORY_CLASS, ENTRY_MARKER, EXCEPTION_MARKER, EXIT_MARKER, FLOW_MARKER, logBuilder, name, THROWING_MARKER
-
-
Constructor Summary
Constructors Constructor Description AsyncLogger(LoggerContext context, java.lang.String name, MessageFactory messageFactory, AsyncLoggerDisruptor loggerDisruptor)
Constructs anAsyncLogger
with the specified context, name and message factory.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
actualAsyncLog(RingBufferLogEvent event)
This method is called by the EventHandler that processes the RingBufferLogEvent in a separate thread.private java.lang.StackTraceElement
calcLocationIfRequested(java.lang.String fqcn)
Returns the caller location if requested,null
otherwise.private RingBufferLogEventTranslator
getCachedTranslator()
private static StringMap
getContextData(RingBufferLogEvent event)
(package private) NanoClock
getNanoClock()
private AsyncLogger.TranslatorType
getTranslatorType()
private void
handleRingBufferFull(java.lang.StackTraceElement location, java.lang.String fqcn, Level level, Marker marker, Message msg, java.lang.Throwable thrown)
private void
handleRingBufferFull(RingBufferLogEventTranslator translator)
private void
initTranslator(RingBufferLogEventTranslator translator, java.lang.String fqcn, java.lang.StackTraceElement location, Level level, Marker marker, Message message, java.lang.Throwable thrown)
private void
initTranslator(RingBufferLogEventTranslator translator, java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
private void
initTranslatorThreadValues(RingBufferLogEventTranslator translator)
private boolean
isReused(Message message)
void
log(Level level, Marker marker, java.lang.String fqcn, java.lang.StackTraceElement location, Message message, java.lang.Throwable throwable)
void
logMessage(java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Logs a message at the specified level.(package private) void
logMessageInCurrentThread(java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
LOG4J2-471: prevent deadlock when RingBuffer is full and object being logged calls Logger.log() from its toString() methodprivate void
logWithThreadLocalTranslator(java.lang.String fqcn, java.lang.StackTraceElement location, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Enqueues the specified log event data for logging in a background thread.private void
logWithThreadLocalTranslator(java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Enqueues the specified log event data for logging in a background thread.private void
logWithVarargTranslator(java.lang.String fqcn, java.lang.StackTraceElement location, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Enqueues the specified log event data for logging in a background thread.private void
logWithVarargTranslator(java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Enqueues the specified log event data for logging in a background thread.private void
onPropertiesPresent(RingBufferLogEvent event, java.util.List<Property> properties)
private void
publish(RingBufferLogEventTranslator translator)
void
translateTo(RingBufferLogEvent event, long sequence, java.lang.Object... args)
protected void
updateConfiguration(Configuration newConfig)
Associates this Logger with a new Configuration.-
Methods inherited from class org.apache.logging.log4j.core.Logger
addAppender, addFilter, equals, filterCount, get, getAppenders, getContext, getFilters, getLevel, getParent, hashCode, isAdditive, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, isEnabled, removeAppender, requiresLocation, setAdditive, setLevel, toString, writeReplace
-
Methods inherited from class org.apache.logging.log4j.spi.AbstractLogger
always, atDebug, atError, atFatal, atInfo, atLevel, atTrace, atWarn, catching, catching, catching, catchingMsg, checkMessageFactory, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, debug, enter, enter, enter, enter, enter, entry, entry, entry, entryMsg, entryMsg, entryMsg, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, error, exit, exit, exit, exit, exitMsg, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, fatal, getMessageFactory, getName, getRecursionDepth, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, info, isDebugEnabled, isDebugEnabled, isEnabled, isEnabled, isErrorEnabled, isErrorEnabled, isFatalEnabled, isFatalEnabled, isInfoEnabled, isInfoEnabled, isTraceEnabled, isTraceEnabled, isWarnEnabled, isWarnEnabled, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, log, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logIfEnabled, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, logMessage, printf, printf, throwing, throwing, throwing, throwingMsg, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, trace, traceEntry, traceEntry, traceEntry, traceEntry, traceEntry, traceExit, traceExit, traceExit, traceExit, traceExit, traceExit, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn, warn
-
-
-
-
Field Detail
-
LOGGER
private static final StatusLogger LOGGER
-
CLOCK
private static final Clock CLOCK
-
CONTEXT_DATA_INJECTOR
private static final ContextDataInjector CONTEXT_DATA_INJECTOR
-
THREAD_NAME_CACHING_STRATEGY
private static final ThreadNameCachingStrategy THREAD_NAME_CACHING_STRATEGY
-
threadLocalTranslator
private final java.lang.ThreadLocal<RingBufferLogEventTranslator> threadLocalTranslator
-
loggerDisruptor
private final AsyncLoggerDisruptor loggerDisruptor
-
includeLocation
private volatile boolean includeLocation
-
nanoClock
private volatile NanoClock nanoClock
-
threadLocalTranslatorType
private final AsyncLogger.TranslatorType threadLocalTranslatorType
-
varargTranslatorType
private final AsyncLogger.TranslatorType varargTranslatorType
-
-
Constructor Detail
-
AsyncLogger
public AsyncLogger(LoggerContext context, java.lang.String name, MessageFactory messageFactory, AsyncLoggerDisruptor loggerDisruptor)
Constructs anAsyncLogger
with the specified context, name and message factory.- Parameters:
context
- context of this loggername
- name of this loggermessageFactory
- message factory of this loggerloggerDisruptor
- helper class that logging can be delegated to. This object owns the Disruptor.
-
-
Method Detail
-
updateConfiguration
protected void updateConfiguration(Configuration newConfig)
Description copied from class:Logger
Associates this Logger with a new Configuration. This method is not exposed through the public API.There are two ways this could be used to guarantee all threads are aware of changes to config.
- Synchronize this method. Accessors don't need to be synchronized as Java will treat all variables within a synchronized block as volatile.
- Declare the variable volatile. Option 2 is used here as the performance cost is very low and it does a better job at documenting how it is used.
- Overrides:
updateConfiguration
in classLogger
- Parameters:
newConfig
- The new Configuration.
-
getNanoClock
NanoClock getNanoClock()
-
getCachedTranslator
private RingBufferLogEventTranslator getCachedTranslator()
-
logMessage
public void logMessage(java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Description copied from interface:ExtendedLogger
Logs a message at the specified level. It is the responsibility of the caller to ensure the specified level is enabled.- Specified by:
logMessage
in interfaceExtendedLogger
- Overrides:
logMessage
in classLogger
- Parameters:
fqcn
- The fully qualified class name of the logger entry point, used to determine the caller class and method when location information needs to be logged.level
- The logging Level to check.marker
- A Marker or null.message
- The Message.thrown
- the exception to log, including its stack trace.
-
log
public void log(Level level, Marker marker, java.lang.String fqcn, java.lang.StackTraceElement location, Message message, java.lang.Throwable throwable)
-
getTranslatorType
private AsyncLogger.TranslatorType getTranslatorType()
-
isReused
private boolean isReused(Message message)
-
logWithThreadLocalTranslator
private void logWithThreadLocalTranslator(java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Enqueues the specified log event data for logging in a background thread.This re-uses a
RingBufferLogEventTranslator
instance cached in aThreadLocal
to avoid creating unnecessary objects with each event.- Parameters:
fqcn
- fully qualified name of the callerlevel
- level at which the caller wants to log the messagemarker
- message markermessage
- the log messagethrown
- aThrowable
ornull
-
logWithThreadLocalTranslator
private void logWithThreadLocalTranslator(java.lang.String fqcn, java.lang.StackTraceElement location, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Enqueues the specified log event data for logging in a background thread.This re-uses a
RingBufferLogEventTranslator
instance cached in aThreadLocal
to avoid creating unnecessary objects with each event.- Parameters:
fqcn
- fully qualified name of the callerlocation
- the Location of the caller.level
- level at which the caller wants to log the messagemarker
- message markermessage
- the log messagethrown
- aThrowable
ornull
-
publish
private void publish(RingBufferLogEventTranslator translator)
-
handleRingBufferFull
private void handleRingBufferFull(RingBufferLogEventTranslator translator)
-
initTranslator
private void initTranslator(RingBufferLogEventTranslator translator, java.lang.String fqcn, java.lang.StackTraceElement location, Level level, Marker marker, Message message, java.lang.Throwable thrown)
-
initTranslator
private void initTranslator(RingBufferLogEventTranslator translator, java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
-
initTranslatorThreadValues
private void initTranslatorThreadValues(RingBufferLogEventTranslator translator)
-
calcLocationIfRequested
private java.lang.StackTraceElement calcLocationIfRequested(java.lang.String fqcn)
Returns the caller location if requested,null
otherwise.- Parameters:
fqcn
- fully qualified caller name.- Returns:
- the caller location if requested,
null
otherwise.
-
logWithVarargTranslator
private void logWithVarargTranslator(java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Enqueues the specified log event data for logging in a background thread.This creates a new varargs Object array for each invocation, but does not store any non-JDK classes in a
ThreadLocal
to avoid memory leaks in web applications (see LOG4J2-1172).- Parameters:
fqcn
- fully qualified name of the callerlevel
- level at which the caller wants to log the messagemarker
- message markermessage
- the log messagethrown
- aThrowable
ornull
-
logWithVarargTranslator
private void logWithVarargTranslator(java.lang.String fqcn, java.lang.StackTraceElement location, Level level, Marker marker, Message message, java.lang.Throwable thrown)
Enqueues the specified log event data for logging in a background thread.This creates a new varargs Object array for each invocation, but does not store any non-JDK classes in a
ThreadLocal
to avoid memory leaks in web applications (see LOG4J2-1172).- Parameters:
fqcn
- fully qualified name of the callerlocation
- location of the caller.level
- level at which the caller wants to log the messagemarker
- message markermessage
- the log messagethrown
- aThrowable
ornull
-
translateTo
public void translateTo(RingBufferLogEvent event, long sequence, java.lang.Object... args)
- Specified by:
translateTo
in interfacecom.lmax.disruptor.EventTranslatorVararg<RingBufferLogEvent>
-
logMessageInCurrentThread
void logMessageInCurrentThread(java.lang.String fqcn, Level level, Marker marker, Message message, java.lang.Throwable thrown)
LOG4J2-471: prevent deadlock when RingBuffer is full and object being logged calls Logger.log() from its toString() method- Parameters:
fqcn
- fully qualified caller namelevel
- log levelmarker
- optional markermessage
- log messagethrown
- optional exception
-
handleRingBufferFull
private void handleRingBufferFull(java.lang.StackTraceElement location, java.lang.String fqcn, Level level, Marker marker, Message msg, java.lang.Throwable thrown)
-
actualAsyncLog
public void actualAsyncLog(RingBufferLogEvent event)
This method is called by the EventHandler that processes the RingBufferLogEvent in a separate thread. Merges the contents of the configuration map into the contextData, after replacing any variables in the property values with the StrSubstitutor-supplied actual values.- Parameters:
event
- the event to log
-
onPropertiesPresent
private void onPropertiesPresent(RingBufferLogEvent event, java.util.List<Property> properties)
-
getContextData
private static StringMap getContextData(RingBufferLogEvent event)
-
-