0
# Rolling Policies
1
2
Advanced file management with time-based and size-based rolling, compression support, and cleanup policies for log file rotation and archival. Rolling policies enable automatic log file management to prevent disk space issues and maintain organized log archives.
3
4
## Capabilities
5
6
### RollingPolicy Interface
7
8
Core interface defining how and when log files are rolled over.
9
10
```java { .api }
11
/**
12
* Interface for defining file rollover behavior.
13
* Rolling policies determine when and how log files are rotated.
14
*/
15
public interface RollingPolicy extends LifeCycle {
16
/**
17
* Perform the rollover operation.
18
* @throws RolloverFailure if rollover cannot be completed
19
*/
20
void rollover() throws RolloverFailure;
21
22
/**
23
* Get the name of the currently active log file.
24
* @return active file name
25
*/
26
String getActiveFileName();
27
28
/**
29
* Get the compression mode for archived files.
30
* @return compression mode (NONE, GZ, ZIP)
31
*/
32
CompressionMode getCompressionMode();
33
34
/**
35
* Set the parent file appender.
36
* @param appender the file appender using this policy
37
*/
38
void setParent(FileAppender<?> appender);
39
}
40
```
41
42
### TriggeringPolicy Interface
43
44
Interface for determining when rollover should occur.
45
46
```java { .api }
47
/**
48
* Interface for determining when file rollover should be triggered.
49
*/
50
public interface TriggeringPolicy<E> extends LifeCycle {
51
/**
52
* Check if the given event should trigger a rollover.
53
* @param activeFile the current active log file
54
* @param event the current event being logged
55
* @return true if rollover should occur
56
*/
57
boolean isTriggeringEvent(File activeFile, E event);
58
}
59
```
60
61
### RollingFileAppender
62
63
File appender with rolling capability that coordinates rolling and triggering policies.
64
65
```java { .api }
66
/**
67
* File appender with automatic rolling support.
68
* Combines RollingPolicy and TriggeringPolicy for complete file management.
69
*/
70
public class RollingFileAppender<E> extends FileAppender<E> {
71
private RollingPolicy rollingPolicy;
72
private TriggeringPolicy<E> triggeringPolicy;
73
74
/**
75
* Set the rolling policy.
76
* @param policy the rolling policy to use
77
*/
78
public void setRollingPolicy(RollingPolicy policy);
79
80
/**
81
* Get the current rolling policy.
82
* @return the rolling policy
83
*/
84
public RollingPolicy getRollingPolicy();
85
86
/**
87
* Set the triggering policy.
88
* @param policy the triggering policy to use
89
*/
90
public void setTriggeringPolicy(TriggeringPolicy<E> policy);
91
92
/**
93
* Get the current triggering policy.
94
* @return the triggering policy
95
*/
96
public TriggeringPolicy<E> getTriggeringPolicy();
97
98
/**
99
* Force an immediate rollover.
100
* @throws RolloverFailure if rollover fails
101
*/
102
public void rollover() throws RolloverFailure;
103
104
@Override
105
protected void append(E eventObject);
106
107
@Override
108
public void start();
109
110
@Override
111
public void stop();
112
}
113
```
114
115
### RollingPolicyBase
116
117
Base implementation providing common rolling policy functionality.
118
119
```java { .api }
120
/**
121
* Base class for rolling policies with common configuration options.
122
*/
123
public abstract class RollingPolicyBase extends ContextAwareBase implements RollingPolicy {
124
protected FileAppender<?> parent;
125
protected String fileNamePattern;
126
protected int maxHistory = 0;
127
protected FileSize totalSizeCap = new FileSize(0);
128
protected boolean cleanHistoryOnStart = false;
129
130
/**
131
* Set the file name pattern for rolled files.
132
* Pattern supports date/time tokens and integer tokens.
133
* @param fnp file name pattern (e.g., "app.%d{yyyy-MM-dd}.log")
134
*/
135
public void setFileNamePattern(String fnp);
136
137
/**
138
* Get the file name pattern.
139
* @return file name pattern
140
*/
141
public String getFileNamePattern();
142
143
/**
144
* Set maximum number of archive files to keep.
145
* @param maxHistory maximum history count (0 = no limit)
146
*/
147
public void setMaxHistory(int maxHistory);
148
149
/**
150
* Get the maximum history count.
151
* @return maximum history count
152
*/
153
public int getMaxHistory();
154
155
/**
156
* Set total size cap for all archive files.
157
* @param totalSizeCap maximum total size of archives
158
*/
159
public void setTotalSizeCap(FileSize totalSizeCap);
160
161
/**
162
* Get the total size cap.
163
* @return total size cap
164
*/
165
public FileSize getTotalSizeCap();
166
167
/**
168
* Enable cleaning old archives on startup.
169
* @param cleanHistoryOnStart true to clean on start
170
*/
171
public void setCleanHistoryOnStart(boolean cleanHistoryOnStart);
172
173
/**
174
* Check if clean history on start is enabled.
175
* @return true if enabled
176
*/
177
public boolean isCleanHistoryOnStart();
178
179
/**
180
* Set the parent file appender.
181
* @param appender the parent appender
182
*/
183
public void setParent(FileAppender<?> appender);
184
185
/**
186
* Get the parent file appender.
187
* @return the parent appender
188
*/
189
public FileAppender<?> getParent();
190
}
191
```
192
193
### TimeBasedRollingPolicy
194
195
Time-based rolling policy supporting date/time patterns and size-based splitting.
196
197
```java { .api }
198
/**
199
* Rolling policy based on time patterns with optional size-based splitting.
200
* Supports daily, hourly, or custom time-based rollover with compression.
201
*/
202
public class TimeBasedRollingPolicy<E> extends RollingPolicyBase
203
implements TriggeringPolicy<E> {
204
private FileSize maxFileSize;
205
206
/**
207
* Set maximum file size for size-based splitting within time periods.
208
* @param maxFileSize maximum size before splitting (e.g., "10MB")
209
*/
210
public void setMaxFileSize(FileSize maxFileSize);
211
212
/**
213
* Get the maximum file size.
214
* @return maximum file size
215
*/
216
public FileSize getMaxFileSize();
217
218
/**
219
* Perform time-based rollover.
220
* Creates archive file based on time pattern and starts new active file.
221
*/
222
@Override
223
public void rollover() throws RolloverFailure;
224
225
/**
226
* Check if rollover should be triggered based on time or size.
227
* @param activeFile current active file
228
* @param event current event
229
* @return true if rollover needed
230
*/
231
@Override
232
public boolean isTriggeringEvent(File activeFile, E event);
233
234
/**
235
* Get compression mode based on file name pattern.
236
* @return NONE, GZ, or ZIP based on pattern extension
237
*/
238
@Override
239
public CompressionMode getCompressionMode();
240
241
@Override
242
public String getActiveFileName();
243
244
@Override
245
public void start();
246
247
@Override
248
public void stop();
249
}
250
```
251
252
### SizeAndTimeBasedRollingPolicy
253
254
Combined size and time-based rolling with multiple files per time period.
255
256
```java { .api }
257
/**
258
* Rolling policy combining time-based and size-based strategies.
259
* Creates multiple files per time period when size limits are exceeded.
260
*/
261
public class SizeAndTimeBasedRollingPolicy<E> extends TimeBasedRollingPolicy<E> {
262
/**
263
* Inherits all methods from TimeBasedRollingPolicy.
264
* Adds intelligence to create multiple files per time period based on size.
265
*/
266
267
@Override
268
public void rollover() throws RolloverFailure;
269
270
@Override
271
public boolean isTriggeringEvent(File activeFile, E event);
272
}
273
```
274
275
### FixedWindowRollingPolicy
276
277
Rolling policy that maintains a fixed window of numbered log files.
278
279
```java { .api }
280
/**
281
* Rolling policy that maintains a fixed number of numbered backup files.
282
* Files are renamed in sequence (app.1.log, app.2.log, etc.).
283
*/
284
public class FixedWindowRollingPolicy extends RollingPolicyBase {
285
private int minIndex = 1;
286
private int maxIndex = 7;
287
288
/**
289
* Set the minimum index for backup files.
290
* @param minIndex minimum index (usually 1)
291
*/
292
public void setMinIndex(int minIndex);
293
294
/**
295
* Get the minimum index.
296
* @return minimum index
297
*/
298
public int getMinIndex();
299
300
/**
301
* Set the maximum index for backup files.
302
* @param maxIndex maximum index (determines number of backup files)
303
*/
304
public void setMaxIndex(int maxIndex);
305
306
/**
307
* Get the maximum index.
308
* @return maximum index
309
*/
310
public int getMaxIndex();
311
312
/**
313
* Perform fixed window rollover.
314
* Renames existing files and compresses oldest if needed.
315
*/
316
@Override
317
public void rollover() throws RolloverFailure;
318
319
@Override
320
public String getActiveFileName();
321
322
@Override
323
public CompressionMode getCompressionMode();
324
325
@Override
326
public void start();
327
}
328
```
329
330
### SizeBasedTriggeringPolicy
331
332
Triggering policy that rolls over when file size exceeds a threshold.
333
334
```java { .api }
335
/**
336
* Triggering policy based on file size.
337
* Triggers rollover when active file exceeds specified size.
338
*/
339
public class SizeBasedTriggeringPolicy<E> extends TriggeringPolicyBase<E> {
340
private FileSize maxFileSize = new FileSize(10 * 1024 * 1024); // 10MB default
341
342
/**
343
* Set the maximum file size before triggering rollover.
344
* @param maxFileSize maximum size (e.g., "10MB", "1GB")
345
*/
346
public void setMaxFileSize(FileSize maxFileSize);
347
348
/**
349
* Get the maximum file size.
350
* @return maximum file size
351
*/
352
public FileSize getMaxFileSize();
353
354
/**
355
* Check if file size exceeds threshold.
356
* @param activeFile current active file
357
* @param event current event (not used for size-based triggering)
358
* @return true if file size exceeds maxFileSize
359
*/
360
@Override
361
public boolean isTriggeringEvent(File activeFile, E event);
362
363
@Override
364
public void start();
365
}
366
```
367
368
### TriggeringPolicyBase
369
370
Base class for triggering policies.
371
372
```java { .api }
373
/**
374
* Base class for triggering policies with lifecycle support.
375
*/
376
public abstract class TriggeringPolicyBase<E> extends ContextAwareBase
377
implements TriggeringPolicy<E> {
378
private boolean started = false;
379
380
/**
381
* Start the triggering policy.
382
*/
383
public void start();
384
385
/**
386
* Stop the triggering policy.
387
*/
388
public void stop();
389
390
/**
391
* Check if the policy is started.
392
* @return true if started
393
*/
394
public boolean isStarted();
395
}
396
```
397
398
## Helper Classes
399
400
### CompressionMode Enum
401
402
Enumeration of supported compression types.
403
404
```java { .api }
405
/**
406
* Supported compression modes for archived log files.
407
*/
408
public enum CompressionMode {
409
/**
410
* No compression.
411
*/
412
NONE,
413
414
/**
415
* Gzip compression (.gz extension).
416
*/
417
GZ,
418
419
/**
420
* ZIP compression (.zip extension).
421
*/
422
ZIP
423
}
424
```
425
426
### FileNamePattern
427
428
Helper class for parsing and working with file name patterns.
429
430
```java { .api }
431
/**
432
* Utility for working with file name patterns containing date/time tokens.
433
*/
434
public class FileNamePattern {
435
/**
436
* Convert object to string using the pattern.
437
* @param o object to convert (usually Date or Integer)
438
* @return formatted string
439
*/
440
public String convert(Object o);
441
442
/**
443
* Convert pattern to regular expression.
444
* @return regex pattern for matching files
445
*/
446
public String toRegex();
447
448
/**
449
* Check if pattern contains integer token converter.
450
* @return true if pattern has integer tokens
451
*/
452
public boolean hasIntegerTokenConverter();
453
454
/**
455
* Get the integer token converter.
456
* @return integer token converter, or null
457
*/
458
public IntegerTokenConverter getIntegerTokenConverter();
459
460
/**
461
* Parse date from filename using pattern.
462
* @param file file to parse
463
* @return parsed date, or null if no match
464
*/
465
public Date parseFilename(File file);
466
}
467
```
468
469
### RolloverFailure Exception
470
471
Exception thrown when rollover operations fail.
472
473
```java { .api }
474
/**
475
* Exception thrown when rollover operations cannot be completed.
476
*/
477
public class RolloverFailure extends Exception {
478
/**
479
* Create exception with message.
480
* @param msg error message
481
*/
482
public RolloverFailure(String msg);
483
484
/**
485
* Create exception with message and cause.
486
* @param msg error message
487
* @param cause underlying cause
488
*/
489
public RolloverFailure(String msg, Throwable cause);
490
}
491
```
492
493
## Usage Examples
494
495
### Time-Based Daily Rolling
496
497
```java
498
import ch.qos.logback.core.rolling.RollingFileAppender;
499
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
500
501
// Create rolling file appender
502
RollingFileAppender<Object> appender = new RollingFileAppender<>();
503
appender.setContext(context);
504
appender.setFile("application.log");
505
506
// Configure time-based rolling policy
507
TimeBasedRollingPolicy<Object> rollingPolicy = new TimeBasedRollingPolicy<>();
508
rollingPolicy.setContext(context);
509
rollingPolicy.setParent(appender);
510
rollingPolicy.setFileNamePattern("application.%d{yyyy-MM-dd}.log");
511
rollingPolicy.setMaxHistory(30); // Keep 30 days
512
rollingPolicy.setCleanHistoryOnStart(true);
513
rollingPolicy.start();
514
515
// Set policies on appender
516
appender.setRollingPolicy(rollingPolicy);
517
appender.setTriggeringPolicy(rollingPolicy); // TimeBasedRollingPolicy implements both
518
appender.setEncoder(encoder);
519
appender.start();
520
```
521
522
### Size and Time-Based Rolling with Compression
523
524
```java
525
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
526
import ch.qos.logback.core.util.FileSize;
527
528
RollingFileAppender<Object> appender = new RollingFileAppender<>();
529
appender.setContext(context);
530
appender.setFile("application.log");
531
532
// Combined size and time-based policy
533
SizeAndTimeBasedRollingPolicy<Object> policy = new SizeAndTimeBasedRollingPolicy<>();
534
policy.setContext(context);
535
policy.setParent(appender);
536
policy.setFileNamePattern("application.%d{yyyy-MM-dd}.%i.log.gz"); // .gz for compression
537
policy.setMaxFileSize(new FileSize(100 * 1024 * 1024)); // 100MB per file
538
policy.setMaxHistory(60); // Keep 60 days
539
policy.setTotalSizeCap(new FileSize(20 * 1024 * 1024 * 1024L)); // 20GB total
540
policy.start();
541
542
appender.setRollingPolicy(policy);
543
appender.setTriggeringPolicy(policy);
544
appender.setEncoder(encoder);
545
appender.start();
546
```
547
548
### Fixed Window Rolling with Size Trigger
549
550
```java
551
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
552
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
553
554
RollingFileAppender<Object> appender = new RollingFileAppender<>();
555
appender.setContext(context);
556
appender.setFile("application.log");
557
558
// Fixed window rolling policy
559
FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy();
560
rollingPolicy.setContext(context);
561
rollingPolicy.setParent(appender);
562
rollingPolicy.setFileNamePattern("application.%i.log.zip"); // ZIP compression
563
rollingPolicy.setMinIndex(1);
564
rollingPolicy.setMaxIndex(10); // Keep 10 backup files
565
rollingPolicy.start();
566
567
// Size-based triggering policy
568
SizeBasedTriggeringPolicy<Object> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
569
triggeringPolicy.setContext(context);
570
triggeringPolicy.setMaxFileSize(new FileSize(50 * 1024 * 1024)); // 50MB
571
triggeringPolicy.start();
572
573
appender.setRollingPolicy(rollingPolicy);
574
appender.setTriggeringPolicy(triggeringPolicy);
575
appender.setEncoder(encoder);
576
appender.start();
577
```
578
579
### Hourly Rolling with Size Limits
580
581
```java
582
TimeBasedRollingPolicy<Object> hourlyPolicy = new TimeBasedRollingPolicy<>();
583
hourlyPolicy.setContext(context);
584
hourlyPolicy.setParent(appender);
585
hourlyPolicy.setFileNamePattern("application.%d{yyyy-MM-dd-HH}.log");
586
hourlyPolicy.setMaxFileSize(new FileSize(10 * 1024 * 1024)); // 10MB max per hour
587
hourlyPolicy.setMaxHistory(24 * 7); // Keep one week (24 hours × 7 days)
588
hourlyPolicy.start();
589
```
590
591
### Custom Rolling Policy
592
593
```java
594
import ch.qos.logback.core.rolling.RollingPolicyBase;
595
596
public class CustomRollingPolicy extends RollingPolicyBase {
597
private String customPattern;
598
599
@Override
600
public void rollover() throws RolloverFailure {
601
// Custom rollover logic
602
String activeFile = getActiveFileName();
603
String archiveFile = generateArchiveFileName();
604
605
try {
606
// Rename current file
607
Files.move(Paths.get(activeFile), Paths.get(archiveFile));
608
609
// Optionally compress
610
if (getCompressionMode() != CompressionMode.NONE) {
611
compressFile(archiveFile);
612
}
613
614
// Clean old files if needed
615
cleanupOldFiles();
616
617
} catch (IOException e) {
618
throw new RolloverFailure("Failed to rollover", e);
619
}
620
}
621
622
@Override
623
public String getActiveFileName() {
624
return parent.getFile();
625
}
626
627
@Override
628
public CompressionMode getCompressionMode() {
629
if (fileNamePattern != null && fileNamePattern.endsWith(".gz")) {
630
return CompressionMode.GZ;
631
} else if (fileNamePattern != null && fileNamePattern.endsWith(".zip")) {
632
return CompressionMode.ZIP;
633
}
634
return CompressionMode.NONE;
635
}
636
637
private String generateArchiveFileName() {
638
// Custom archive file name generation
639
return String.format("app-%d.log", System.currentTimeMillis());
640
}
641
642
private void compressFile(String fileName) throws IOException {
643
// Custom compression logic
644
}
645
646
private void cleanupOldFiles() {
647
// Custom cleanup logic based on maxHistory
648
}
649
650
public void setCustomPattern(String customPattern) {
651
this.customPattern = customPattern;
652
}
653
}
654
```
655
656
## File Name Patterns
657
658
File name patterns support various tokens:
659
660
### Date/Time Tokens
661
- `%d{yyyy-MM-dd}` - Date format (daily rolling)
662
- `%d{yyyy-MM-dd-HH}` - Hour format (hourly rolling)
663
- `%d{yyyy-MM-dd-HH-mm}` - Minute format
664
- `%d{yyyy-ww}` - Week-based rolling
665
666
### Integer Tokens
667
- `%i` - Integer index for size-based splitting within time periods
668
669
### Compression Detection
670
- `.gz` extension - Automatic gzip compression
671
- `.zip` extension - Automatic ZIP compression
672
673
### Examples
674
- `app.%d{yyyy-MM-dd}.log` - Daily files: app.2023-12-01.log
675
- `app.%d{yyyy-MM-dd}.%i.log.gz` - Daily with size splitting: app.2023-12-01.0.log.gz
676
- `app.%i.log.zip` - Fixed window with ZIP: app.1.log.zip, app.2.log.zip
677
678
## Best Practices
679
680
1. **Choose Appropriate Strategy**: Time-based for regular intervals, size-based for volume control
681
2. **Set Limits**: Always configure maxHistory and totalSizeCap to prevent disk overflow
682
3. **Use Compression**: Enable compression for long-term storage efficiency
683
4. **Monitor Performance**: Large files and frequent rolling can impact performance
684
5. **Test Rollover**: Verify rollover behavior in development environments
685
6. **Cleanup on Start**: Enable cleanHistoryOnStart for consistent archive management