0
# Appenders
1
2
Output destinations for log events including console, file, network, and specialized appenders. Appenders are responsible for writing log events to their final destinations with appropriate formatting and filtering.
3
4
## Capabilities
5
6
### Core Appender Interface
7
8
Base interface and functionality shared by all appenders.
9
10
```java { .api }
11
/**
12
* Core appender interface for writing log events
13
*/
14
public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable<E> {
15
String getName();
16
void setName(String name);
17
void doAppend(E event);
18
}
19
20
/**
21
* Base implementation providing common appender functionality
22
*/
23
public abstract class AppenderBase<E> extends ContextAwareBase implements Appender<E> {
24
protected volatile boolean started = false;
25
private String name;
26
private FilterAttachableImpl<E> fai = new FilterAttachableImpl<E>();
27
28
public String getName();
29
public void setName(String name);
30
public void start();
31
public void stop();
32
public boolean isStarted();
33
34
// Template method for actual appending
35
protected abstract void append(E eventObject);
36
37
// Filter management
38
public void addFilter(Filter<E> newFilter);
39
public void clearAllFilters();
40
public List<Filter<E>> getCopyOfAttachedFiltersList();
41
public FilterReply getFilterChainDecision(E event);
42
}
43
44
/**
45
* Interface for appenders that can have other appenders attached
46
*/
47
public interface AppenderAttachable<E> {
48
void addAppender(Appender<E> newAppender);
49
Iterator<Appender<E>> iteratorForAppenders();
50
Appender<E> getAppender(String name);
51
boolean isAttached(Appender<E> appender);
52
void detachAndStopAllAppenders();
53
boolean detachAppender(Appender<E> appender);
54
boolean detachAppender(String name);
55
}
56
```
57
58
### Console Appender
59
60
Simple console output appender for development and simple deployments.
61
62
```java { .api }
63
/**
64
* Appender that writes to System.out or System.err
65
*/
66
public class ConsoleAppender<E> extends OutputStreamAppender<E> {
67
public static final String SYSTEM_OUT = "System.out";
68
public static final String SYSTEM_ERR = "System.err";
69
70
private ConsoleTarget target = ConsoleTarget.SystemOut;
71
private boolean withJansi = false;
72
73
/**
74
* Set the console target (System.out or System.err)
75
*/
76
public void setTarget(String value);
77
public String getTarget();
78
79
/**
80
* Enable/disable JANSI for Windows console colors
81
*/
82
public boolean isWithJansi();
83
public void setWithJansi(boolean withJansi);
84
}
85
86
/**
87
* Console target enumeration
88
*/
89
public enum ConsoleTarget {
90
SystemOut("System.out"),
91
SystemErr("System.err");
92
93
public static ConsoleTarget findByName(String name);
94
}
95
```
96
97
**Usage Examples:**
98
99
```java
100
import ch.qos.logback.core.ConsoleAppender;
101
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
102
103
// Create console appender
104
ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<>();
105
appender.setContext(loggerContext);
106
appender.setName("STDOUT");
107
appender.setTarget("System.out");
108
109
// Configure encoder
110
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
111
encoder.setContext(loggerContext);
112
encoder.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
113
encoder.start();
114
115
appender.setEncoder(encoder);
116
appender.start();
117
```
118
119
### Async Appender
120
121
High-performance asynchronous logging appender that processes events in background threads.
122
123
```java { .api }
124
/**
125
* Asynchronous appender for high-performance logging
126
*/
127
public class AsyncAppender extends AsyncAppenderBase<ILoggingEvent> {
128
boolean includeCallerData = false;
129
130
/**
131
* Enable/disable caller data extraction (expensive operation)
132
*/
133
public boolean isIncludeCallerData();
134
public void setIncludeCallerData(boolean includeCallerData);
135
136
// Inherited from AsyncAppenderBase
137
public void setQueueSize(int queueSize);
138
public int getQueueSize();
139
public void setDiscardingThreshold(int discardingThreshold);
140
public int getDiscardingThreshold();
141
public void setMaxFlushTime(int maxFlushTime);
142
public int getMaxFlushTime();
143
public void setNeverBlock(boolean neverBlock);
144
public boolean isNeverBlock();
145
}
146
147
/**
148
* Base class for asynchronous appenders
149
*/
150
public abstract class AsyncAppenderBase<E> extends AppenderBase<E> implements AppenderAttachable<E> {
151
public static final int DEFAULT_QUEUE_SIZE = 256;
152
public static final int UNDEFINED = -1;
153
public static final int DEFAULT_MAX_FLUSH_TIME = 1000;
154
155
BlockingQueue<E> blockingQueue;
156
AppenderAttachableImpl<E> aai = new AppenderAttachableImpl<E>();
157
int queueSize = DEFAULT_QUEUE_SIZE;
158
int appenderCount = 0;
159
int discardingThreshold = UNDEFINED;
160
boolean neverBlock = false;
161
162
Worker worker = new Worker();
163
164
/**
165
* Set the maximum number of events in the queue
166
*/
167
public void setQueueSize(int queueSize);
168
public int getQueueSize();
169
170
/**
171
* Set threshold for discarding events when queue is full
172
*/
173
public void setDiscardingThreshold(int discardingThreshold);
174
public int getDiscardingThreshold();
175
176
/**
177
* Set maximum time to wait for queue flush on shutdown
178
*/
179
public void setMaxFlushTime(int maxFlushTime);
180
public int getMaxFlushTime();
181
182
/**
183
* Configure non-blocking behavior when queue is full
184
*/
185
public void setNeverBlock(boolean neverBlock);
186
public boolean isNeverBlock();
187
}
188
```
189
190
**Usage Examples:**
191
192
```java
193
import ch.qos.logback.classic.AsyncAppender;
194
195
// Create async appender
196
AsyncAppender asyncAppender = new AsyncAppender();
197
asyncAppender.setContext(loggerContext);
198
asyncAppender.setName("ASYNC");
199
200
// Configure queue settings
201
asyncAppender.setQueueSize(512);
202
asyncAppender.setDiscardingThreshold(20);
203
asyncAppender.setMaxFlushTime(5000);
204
asyncAppender.setNeverBlock(false);
205
asyncAppender.setIncludeCallerData(false); // For performance
206
207
// Add delegate appender
208
asyncAppender.addAppender(consoleAppender);
209
asyncAppender.start();
210
```
211
212
### File Appenders
213
214
File-based appenders with rolling policies for log file management.
215
216
```java { .api }
217
/**
218
* Base class for file-based appenders
219
*/
220
public class FileAppender<E> extends OutputStreamAppender<E> {
221
public static final long DEFAULT_BUFFER_SIZE = 8192;
222
223
protected String fileName = null;
224
private boolean append = true;
225
private boolean prudent = false;
226
227
/**
228
* Set the target file name
229
*/
230
public void setFile(String file);
231
public String getFile();
232
233
/**
234
* Configure append mode vs overwrite
235
*/
236
public void setAppend(boolean append);
237
public boolean isAppend();
238
239
/**
240
* Enable/disable prudent mode for multi-JVM safe writing
241
*/
242
public void setPrudent(boolean prudent);
243
public boolean isPrudent();
244
}
245
246
/**
247
* Rolling file appender with configurable rolling policies
248
*/
249
public class RollingFileAppender<E> extends FileAppender<E> {
250
File currentlyActiveFile;
251
TriggeringPolicy<E> triggeringPolicy;
252
RollingPolicy rollingPolicy;
253
254
/**
255
* Set the triggering policy for when to roll files
256
*/
257
public void setTriggeringPolicy(TriggeringPolicy<E> policy);
258
public TriggeringPolicy<E> getTriggeringPolicy();
259
260
/**
261
* Set the rolling policy for how to roll files
262
*/
263
public void setRollingPolicy(RollingPolicy policy);
264
public RollingPolicy getRollingPolicy();
265
}
266
```
267
268
### Output Stream Appenders
269
270
Base classes for stream-based output appenders.
271
272
```java { .api }
273
/**
274
* Base class for appenders that write to output streams
275
*/
276
public class OutputStreamAppender<E> extends AppenderBase<E> {
277
private Encoder<E> encoder;
278
private OutputStream outputStream;
279
private boolean immediateFlush = true;
280
281
/**
282
* Set the encoder for formatting events
283
*/
284
public void setEncoder(Encoder<E> encoder);
285
public Encoder<E> getEncoder();
286
287
/**
288
* Configure immediate flushing behavior
289
*/
290
public void setImmediateFlush(boolean value);
291
public boolean isImmediateFlush();
292
293
/**
294
* Set the target output stream
295
*/
296
public void setOutputStream(OutputStream outputStream);
297
protected OutputStream getOutputStream();
298
299
// Stream management
300
protected void writeOut(E event) throws IOException;
301
protected final void streamWrite(E event, OutputStream out) throws IOException;
302
protected void closeOutputStream();
303
}
304
305
/**
306
* Appender that writes to a Writer
307
*/
308
public class WriterAppender<E> extends AppenderBase<E> {
309
protected Layout<E> layout;
310
protected Writer writer;
311
private boolean immediateFlush = true;
312
313
/**
314
* Set the layout for formatting events
315
*/
316
public void setLayout(Layout<E> layout);
317
public Layout<E> getLayout();
318
319
/**
320
* Configure immediate flushing
321
*/
322
public void setImmediateFlush(boolean value);
323
public boolean isImmediateFlush();
324
325
/**
326
* Set the target writer
327
*/
328
public void setWriter(Writer writer);
329
protected Writer getWriter();
330
}
331
```
332
333
## Rolling Policies
334
335
```java { .api }
336
/**
337
* Interface for rolling policies
338
*/
339
public interface RollingPolicy extends LifeCycle {
340
void rollover() throws RolloverFailure;
341
String getActiveFileName();
342
CompressionMode getCompressionMode();
343
void setParent(FileAppender<?> appender);
344
}
345
346
/**
347
* Interface for triggering policies
348
*/
349
public interface TriggeringPolicy<E> extends LifeCycle {
350
boolean isTriggeringEvent(File activeFile, E event);
351
}
352
353
/**
354
* Size-based triggering policy
355
*/
356
public class SizeBasedTriggeringPolicy<E> extends TriggeringPolicyBase<E> {
357
public static final String DEFAULT_MAX_FILE_SIZE = "10MB";
358
FileSize maxFileSize = FileSize.valueOf(DEFAULT_MAX_FILE_SIZE);
359
360
public void setMaxFileSize(FileSize maxFileSize);
361
public FileSize getMaxFileSize();
362
}
363
364
/**
365
* Time-based rolling policy
366
*/
367
public class TimeBasedRollingPolicy<E> extends RollingPolicyBase implements TriggeringPolicy<E> {
368
static final String FNP_NOT_SET = "The FileNamePattern option must be set before using TimeBasedRollingPolicy";
369
370
FileNamePattern fileNamePattern;
371
RenameUtil renameUtil = new RenameUtil();
372
Compressor compressor;
373
374
String fileNamePatternStr;
375
int maxHistory = UNBOUNDED_HISTORY;
376
FileSize totalSizeCap = new FileSize(UNBOUNDED_TOTAL_SIZE_CAP);
377
boolean cleanHistoryOnStart = false;
378
379
public void setFileNamePattern(String fnp);
380
public String getFileNamePattern();
381
public void setMaxHistory(int maxHistory);
382
public int getMaxHistory();
383
public void setTotalSizeCap(FileSize totalSizeCap);
384
public FileSize getTotalSizeCap();
385
public void setCleanHistoryOnStart(boolean cleanHistoryOnStart);
386
public boolean isCleanHistoryOnStart();
387
}
388
```
389
390
**Usage Examples:**
391
392
```java
393
import ch.qos.logback.core.rolling.*;
394
395
// File appender with time-based rolling
396
RollingFileAppender<ILoggingEvent> fileAppender = new RollingFileAppender<>();
397
fileAppender.setContext(loggerContext);
398
fileAppender.setName("FILE");
399
fileAppender.setFile("logs/application.log");
400
401
// Time-based rolling policy
402
TimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new TimeBasedRollingPolicy<>();
403
rollingPolicy.setContext(loggerContext);
404
rollingPolicy.setFileNamePattern("logs/application.%d{yyyy-MM-dd}.%i.log.gz");
405
rollingPolicy.setMaxHistory(30);
406
rollingPolicy.setTotalSizeCap(FileSize.valueOf("1GB"));
407
rollingPolicy.setParent(fileAppender);
408
rollingPolicy.start();
409
410
// Size-based triggering
411
SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
412
triggeringPolicy.setMaxFileSize(FileSize.valueOf("100MB"));
413
triggeringPolicy.start();
414
415
fileAppender.setRollingPolicy(rollingPolicy);
416
fileAppender.setTriggeringPolicy(triggeringPolicy);
417
418
// Configure encoder
419
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
420
encoder.setContext(loggerContext);
421
encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
422
encoder.start();
423
424
fileAppender.setEncoder(encoder);
425
fileAppender.start();
426
```