0
# Asynchronous Logging
1
2
Log4j Core provides high-performance asynchronous logging capabilities using the LMAX Disruptor framework. Async logging significantly reduces the latency impact of logging on application threads by processing log events in background threads.
3
4
## Capabilities
5
6
### Async Logger
7
8
High-performance asynchronous logger implementation that inherits all Logger functionality while processing events asynchronously.
9
10
```java { .api }
11
/**
12
* Asynchronous logger implementation using LMAX Disruptor
13
* Inherits all methods from Logger but processes events asynchronously
14
*/
15
public class AsyncLogger extends Logger {
16
/**
17
* Constructor for AsyncLogger
18
* @param context Logger context
19
* @param name Logger name
20
* @param messageFactory Message factory
21
* @param asyncLoggerConfigDisruptor Disruptor for async processing
22
*/
23
protected AsyncLogger(LoggerContext context, String name, MessageFactory messageFactory,
24
AsyncLoggerConfigDisruptor asyncLoggerConfigDisruptor);
25
26
/**
27
* Check if this logger supports flow tracing
28
* @return true if flow tracing is supported
29
*/
30
public boolean isFlowTracingSupported();
31
32
// All logging methods inherited from Logger:
33
// void debug(String message);
34
// void info(String message);
35
// void warn(String message);
36
// void error(String message);
37
// etc.
38
}
39
```
40
41
### Async Logger Context
42
43
Logger context specifically designed for asynchronous logging operations.
44
45
```java { .api }
46
/**
47
* Logger context for async loggers with specialized configuration
48
*/
49
public class AsyncLoggerContext extends LoggerContext {
50
/**
51
* Create AsyncLoggerContext
52
* @param name Context name
53
*/
54
public AsyncLoggerContext(String name);
55
56
/**
57
* Create AsyncLoggerContext with configuration source
58
* @param name Context name
59
* @param externalContext External context object
60
* @param configLocn Configuration location
61
*/
62
public AsyncLoggerContext(String name, Object externalContext, String configLocn);
63
64
/**
65
* Create AsyncLoggerContext with configuration source URI
66
* @param name Context name
67
* @param externalContext External context object
68
* @param configLocn Configuration location URI
69
*/
70
public AsyncLoggerContext(String name, Object externalContext, URI configLocn);
71
72
/**
73
* Check if async loggers are supported in this context
74
* @return true if async loggers are supported
75
*/
76
public boolean hasAsyncLoggers();
77
78
/**
79
* Set whether to include location information in async logging
80
* @param includeLocation true to include location info
81
*/
82
public void setIncludeLocation(boolean includeLocation);
83
}
84
```
85
86
### Async Logger Config
87
88
Configuration class for async logger behavior and settings.
89
90
```java { .api }
91
/**
92
* Configuration for async logger with specialized async handling
93
*/
94
public class AsyncLoggerConfig extends LoggerConfig {
95
/**
96
* Create AsyncLoggerConfig
97
*/
98
public AsyncLoggerConfig();
99
100
/**
101
* Create AsyncLoggerConfig with name and level
102
* @param name Logger name
103
* @param level Logger level
104
* @param additive Additivity flag
105
*/
106
public AsyncLoggerConfig(String name, Level level, boolean additive);
107
108
/**
109
* Process log event asynchronously
110
* @param event LogEvent to process
111
*/
112
protected void processLogEvent(LogEvent event);
113
114
/**
115
* Handle async queue full condition
116
* @param event LogEvent that couldn't be queued
117
* @return EventRoute indicating how to handle the event
118
*/
119
protected EventRoute handleQueueFull(LogEvent event);
120
}
121
```
122
123
### Async Logger Context Selector
124
125
Context selector for choosing async logger contexts.
126
127
```java { .api }
128
/**
129
* Context selector that creates AsyncLoggerContext instances
130
*/
131
public class AsyncLoggerContextSelector implements ContextSelector {
132
/**
133
* Get logger context for the calling context
134
* @param fqcn Fully qualified class name
135
* @param loader ClassLoader
136
* @param currentContext Use current context flag
137
* @param externalContext External context object
138
* @return LoggerContext instance
139
*/
140
public LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext, Object externalContext);
141
142
/**
143
* Get logger context for specific parameters
144
* @param fqcn Fully qualified class name
145
* @param loader ClassLoader
146
* @param currentContext Use current context flag
147
* @param configLocation Configuration location
148
* @return LoggerContext instance
149
*/
150
public LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext, URI configLocation);
151
152
/**
153
* Get all logger contexts
154
* @return List of all LoggerContext instances
155
*/
156
public List<LoggerContext> getLoggerContexts();
157
158
/**
159
* Remove logger context
160
* @param context LoggerContext to remove
161
*/
162
public void removeContext(LoggerContext context);
163
164
/**
165
* Check if context selector supports async loggers
166
* @return true if async loggers are supported
167
*/
168
public boolean hasAsyncLoggers();
169
}
170
```
171
172
**Usage Examples:**
173
174
```java
175
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
176
import org.apache.logging.log4j.core.selector.ContextSelector;
177
178
// Set async logger context selector
179
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
180
181
// Get async context
182
AsyncLoggerContextSelector selector = new AsyncLoggerContextSelector();
183
LoggerContext context = selector.getContext("com.example.MyClass",
184
MyClass.class.getClassLoader(), false, null);
185
186
// Check if context supports async loggers
187
boolean supportsAsync = selector.hasAsyncLoggers(); // true
188
```
189
190
## Queue Full Policies
191
192
Policies for handling situations when the async logging queue becomes full.
193
194
### Async Queue Full Policy Interface
195
196
```java { .api }
197
/**
198
* Policy interface for handling full async queues
199
*/
200
public interface AsyncQueueFullPolicy {
201
/**
202
* Get event route when queue is full
203
* @param backgroundThreadId ID of background thread
204
* @param level Log level of the event
205
* @return EventRoute indicating how to handle the event
206
*/
207
EventRoute getRoute(long backgroundThreadId, Level level);
208
209
/**
210
* Event route enumeration
211
*/
212
enum EventRoute {
213
/** Synchronously process the event in caller thread */
214
SYNCHRONOUS,
215
/** Enqueue the event (may block) */
216
ENQUEUE,
217
/** Discard the event */
218
DISCARD
219
}
220
}
221
```
222
223
### Default Async Queue Full Policy
224
225
```java { .api }
226
/**
227
* Default policy that processes events synchronously when queue is full
228
*/
229
public class DefaultAsyncQueueFullPolicy implements AsyncQueueFullPolicy {
230
/**
231
* Create default policy
232
*/
233
public DefaultAsyncQueueFullPolicy();
234
235
/**
236
* Returns SYNCHRONOUS route for all events when queue is full
237
* @param backgroundThreadId Background thread ID
238
* @param level Log level
239
* @return Always returns EventRoute.SYNCHRONOUS
240
*/
241
public EventRoute getRoute(long backgroundThreadId, Level level);
242
}
243
```
244
245
### Discarding Async Queue Full Policy
246
247
```java { .api }
248
/**
249
* Policy that discards events based on level when queue is full
250
*/
251
public class DiscardingAsyncQueueFullPolicy implements AsyncQueueFullPolicy {
252
/**
253
* Create discarding policy with threshold level
254
* @param thresholdLevel Minimum level to keep (higher levels discarded)
255
*/
256
public DiscardingAsyncQueueFullPolicy(Level thresholdLevel);
257
258
/**
259
* Create discarding policy with default INFO threshold
260
*/
261
public DiscardingAsyncQueueFullPolicy();
262
263
/**
264
* Return route based on level threshold
265
* @param backgroundThreadId Background thread ID
266
* @param level Log level
267
* @return DISCARD for levels below threshold, SYNCHRONOUS for others
268
*/
269
public EventRoute getRoute(long backgroundThreadId, Level level);
270
271
/**
272
* Get threshold level
273
* @return Current threshold level
274
*/
275
public Level getThresholdLevel();
276
}
277
```
278
279
**Usage Examples:**
280
281
```java
282
import org.apache.logging.log4j.core.async.*;
283
284
// Set default queue full policy (process synchronously)
285
System.setProperty("log4j2.AsyncQueueFullPolicy",
286
"org.apache.logging.log4j.core.async.DefaultAsyncQueueFullPolicy");
287
288
// Set discarding policy to discard DEBUG and TRACE when queue full
289
System.setProperty("log4j2.AsyncQueueFullPolicy",
290
"org.apache.logging.log4j.core.async.DiscardingAsyncQueueFullPolicy");
291
System.setProperty("log4j2.DiscardThreshold", "INFO");
292
293
// Programmatic policy usage
294
AsyncQueueFullPolicy policy = new DiscardingAsyncQueueFullPolicy(Level.WARN);
295
EventRoute route = policy.getRoute(Thread.currentThread().getId(), Level.DEBUG);
296
// Returns EventRoute.DISCARD for DEBUG level
297
```
298
299
## Configuration for Async Logging
300
301
### System Properties
302
303
Key system properties for configuring async logging behavior:
304
305
```java { .api }
306
/**
307
* Important system properties for async logging configuration
308
*/
309
public class AsyncLoggerSystemProperties {
310
// Ring buffer size for async loggers (default: 256 * 1024)
311
public static final String ASYNC_LOGGER_RING_BUFFER_SIZE = "log4j2.asyncLoggerRingBufferSize";
312
313
// Wait strategy for async loggers (default: Sleep)
314
public static final String ASYNC_LOGGER_WAIT_STRATEGY = "log4j2.asyncLoggerWaitStrategy";
315
316
// Thread name strategy for async loggers
317
public static final String ASYNC_LOGGER_THREAD_NAME_STRATEGY = "log4j2.asyncLoggerThreadNameStrategy";
318
319
// Whether to include location information (default: false)
320
public static final String ASYNC_LOGGER_INCLUDE_LOCATION = "log4j2.includeLocation";
321
322
// Queue full policy class name
323
public static final String ASYNC_QUEUE_FULL_POLICY = "log4j2.AsyncQueueFullPolicy";
324
325
// Discard threshold level for DiscardingAsyncQueueFullPolicy
326
public static final String DISCARD_THRESHOLD = "log4j2.DiscardThreshold";
327
328
// Timeout for async logger shutdown (default: 3000ms)
329
public static final String ASYNC_LOGGER_TIMEOUT = "log4j2.asyncLoggerTimeout";
330
}
331
```
332
333
**Usage Examples:**
334
335
```java
336
// Configure async logging via system properties
337
System.setProperty("log4j2.asyncLoggerRingBufferSize", "1048576"); // 1MB buffer
338
System.setProperty("log4j2.asyncLoggerWaitStrategy", "Block");
339
System.setProperty("log4j2.includeLocation", "false");
340
System.setProperty("log4j2.asyncLoggerTimeout", "5000");
341
342
// Available wait strategies:
343
// - "Sleep" (default) - CPU-friendly but higher latency
344
// - "Yield" - Lower latency but higher CPU usage
345
// - "Block" - Lowest latency but blocks threads
346
// - "Spin" - Lowest latency but highest CPU usage
347
```
348
349
### Mixed Sync/Async Configuration
350
351
You can configure some loggers to be async while others remain synchronous:
352
353
**XML Configuration Example:**
354
```xml
355
<?xml version="1.0" encoding="UTF-8"?>
356
<Configuration status="WARN">
357
<Appenders>
358
<Console name="Console" target="SYSTEM_OUT">
359
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
360
</Console>
361
<File name="File" fileName="application.log">
362
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
363
</File>
364
</Appenders>
365
<Loggers>
366
<!-- Async logger for high-volume package -->
367
<AsyncLogger name="com.example.highvolume" level="INFO" additivity="false">
368
<AppenderRef ref="File"/>
369
</AsyncLogger>
370
371
<!-- Regular synchronous logger -->
372
<Logger name="com.example.critical" level="WARN" additivity="false">
373
<AppenderRef ref="Console"/>
374
</Logger>
375
376
<!-- Async root logger -->
377
<AsyncRoot level="INFO">
378
<AppenderRef ref="Console"/>
379
</AsyncRoot>
380
</Loggers>
381
</Configuration>
382
```
383
384
## Performance Considerations
385
386
### Thread Safety
387
Async loggers are fully thread-safe and can be called concurrently from multiple threads without external synchronization.
388
389
### Memory Usage
390
The ring buffer size directly affects memory usage. Larger buffers provide better throughput but consume more memory.
391
392
### Location Information
393
Including location information (class, method, line number) significantly impacts performance in async logging and should be disabled for maximum throughput.
394
395
### Queue Full Behavior
396
Choose queue full policies based on your application's priorities:
397
- **DefaultAsyncQueueFullPolicy**: Guarantees no log loss but may impact latency
398
- **DiscardingAsyncQueueFullPolicy**: Maintains low latency but may lose low-priority log events