0
# Pattern Processing
1
2
Flexible pattern-based formatting system with conversion chains, color support, and extensible converter framework for custom log formatting. Pattern processing enables sophisticated log message formatting with placeholder substitution and conditional formatting.
3
4
## Capabilities
5
6
### PatternLayoutBase
7
8
Base class for pattern-based layouts with pattern compilation and conversion chain management.
9
10
```java { .api }
11
/**
12
* Base class for pattern-based layouts with conversion chain support.
13
*/
14
public abstract class PatternLayoutBase<E> extends LayoutBase<E> {
15
/**
16
* Set the conversion pattern.
17
* @param pattern conversion pattern with placeholders
18
*/
19
public void setPattern(String pattern);
20
21
/**
22
* Get the conversion pattern.
23
* @return conversion pattern
24
*/
25
public String getPattern();
26
27
/**
28
* Set post-compile processor for pattern customization.
29
* @param postCompileProcessor processor for post-compilation customization
30
*/
31
public void setPostCompileProcessor(PostCompileProcessor<E> postCompileProcessor);
32
33
@Override
34
public void start();
35
36
@Override
37
public void stop();
38
}
39
```
40
41
### Converter Framework
42
43
#### Converter Base Class
44
45
Base class for all pattern converters in the conversion chain.
46
47
```java { .api }
48
/**
49
* Base class for pattern converters that transform events into text.
50
*/
51
public abstract class Converter<E> implements ContextAware {
52
private Converter<E> next;
53
54
/**
55
* Write the conversion result to the string builder.
56
* @param buf string builder to write to
57
* @param event event to convert
58
*/
59
public abstract void write(StringBuilder buf, E event);
60
61
/**
62
* Set the next converter in the chain.
63
* @param next next converter
64
*/
65
public void setNext(Converter<E> next);
66
67
/**
68
* Get the next converter in the chain.
69
* @return next converter
70
*/
71
public Converter<E> getNext();
72
}
73
```
74
75
#### FormattingConverter
76
77
Converter with formatting options like width, alignment, and truncation.
78
79
```java { .api }
80
/**
81
* Converter with formatting capabilities (width, alignment, truncation).
82
*/
83
public abstract class FormattingConverter<E> extends Converter<E> {
84
private FormatInfo formatInfo;
85
86
/**
87
* Convert event to string (implemented by subclasses).
88
* @param event event to convert
89
* @return converted string
90
*/
91
public abstract String convert(E event);
92
93
/**
94
* Set formatting information.
95
* @param formatInfo formatting options
96
*/
97
public void setFormattingInfo(FormatInfo formatInfo);
98
99
/**
100
* Get formatting information.
101
* @return formatting options
102
*/
103
public FormatInfo getFormattingInfo();
104
105
@Override
106
public void write(StringBuilder buf, E event);
107
}
108
```
109
110
#### CompositeConverter
111
112
Converter that can wrap child converters for complex formatting scenarios.
113
114
```java { .api }
115
/**
116
* Converter that wraps child converters for composite formatting.
117
*/
118
public abstract class CompositeConverter<E> extends DynamicConverter<E> {
119
private Converter<E> childConverter;
120
121
/**
122
* Set the child converter.
123
* @param child child converter to wrap
124
*/
125
public void setChildConverter(Converter<E> child);
126
127
/**
128
* Get the child converter.
129
* @return child converter
130
*/
131
public Converter<E> getChildConverter();
132
133
@Override
134
public void start();
135
}
136
```
137
138
#### LiteralConverter
139
140
Converter for static text in patterns.
141
142
```java { .api }
143
/**
144
* Converter for literal text in patterns.
145
*/
146
public class LiteralConverter<E> extends Converter<E> {
147
private String literal;
148
149
/**
150
* Set the literal text.
151
* @param literal text to output
152
*/
153
public void setLiteral(String literal);
154
155
/**
156
* Get the literal text.
157
* @return literal text
158
*/
159
public String getLiteral();
160
161
@Override
162
public void write(StringBuilder buf, E event);
163
}
164
```
165
166
### Formatting Support
167
168
#### FormatInfo
169
170
Class containing formatting information for converters.
171
172
```java { .api }
173
/**
174
* Formatting information for converters (width, alignment, truncation).
175
*/
176
public class FormatInfo {
177
public int min; // Minimum width
178
public int max; // Maximum width
179
public boolean leftPad; // Left padding flag
180
public boolean leftTruncate; // Left truncation flag
181
182
/**
183
* Create format info with specified parameters.
184
* @param min minimum width
185
* @param max maximum width
186
* @param leftPad true for left padding
187
* @param leftTruncate true for left truncation
188
*/
189
public FormatInfo(int min, int max, boolean leftPad, boolean leftTruncate);
190
191
/**
192
* Check if formatting is identity (no formatting applied).
193
* @return true if no formatting
194
*/
195
public boolean isIdentity();
196
}
197
```
198
199
## Color Support
200
201
### Color Converters
202
203
ANSI color support for console output with various color options.
204
205
```java { .api }
206
/**
207
* Base class for foreground color converters.
208
*/
209
public abstract class ForegroundCompositeConverterBase<E> extends CompositeConverter<E> {
210
/**
211
* Get the ANSI color code for this converter.
212
* @return ANSI color code
213
*/
214
protected abstract String getForegroundColorCode();
215
216
@Override
217
protected String transform(E event, String in);
218
}
219
220
// Specific color converters
221
public class BlackCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
222
public class RedCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
223
public class GreenCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
224
public class YellowCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
225
public class BlueCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
226
public class MagentaCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
227
public class CyanCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
228
public class WhiteCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
229
public class GrayCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
230
231
// Bold color variants
232
public class BoldRedCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
233
public class BoldGreenCompositeConverter<E> extends ForegroundCompositeConverterBase<E> { }
234
// ... additional bold variants
235
```
236
237
#### ANSIConstants
238
239
ANSI escape sequence constants for color formatting.
240
241
```java { .api }
242
/**
243
* ANSI escape sequences for console colors.
244
*/
245
public class ANSIConstants {
246
public static final String ESC_START = "\033[";
247
public static final String ESC_END = "m";
248
public static final String BOLD = "1;";
249
public static final String NORMAL = "0;";
250
251
// Color codes
252
public static final String BLACK = "30";
253
public static final String RED = "31";
254
public static final String GREEN = "32";
255
public static final String YELLOW = "33";
256
public static final String BLUE = "34";
257
public static final String MAGENTA = "35";
258
public static final String CYAN = "36";
259
public static final String WHITE = "37";
260
public static final String DEFAULT = "39";
261
262
// Reset
263
public static final String RESET = ESC_START + "0" + ESC_END;
264
}
265
```
266
267
## Pattern Parsing
268
269
### Parser and Compiler
270
271
Framework for parsing pattern strings into converter chains.
272
273
```java { .api }
274
/**
275
* Parser for converting pattern strings into node trees.
276
*/
277
public class Parser<E> {
278
/**
279
* Parse pattern string into node tree.
280
* @return root node of parsed pattern
281
* @throws ScanException if parsing fails
282
*/
283
public Node parse() throws ScanException;
284
285
/**
286
* Set context for the parser.
287
* @param context context for error reporting
288
*/
289
public void setContext(Context context);
290
}
291
292
/**
293
* Compiler for converting node trees into converter chains.
294
*/
295
public class Compiler<E> {
296
/**
297
* Compile node tree into converter chain.
298
* @param head root node
299
* @param converterMap map of converter classes
300
* @return head of converter chain
301
*/
302
public Converter<E> compile(Node head, Map<String, String> converterMap);
303
304
/**
305
* Set context for the compiler.
306
* @param context context for error reporting
307
*/
308
public void setContext(Context context);
309
}
310
```
311
312
### Pattern Syntax Tree
313
314
Node classes representing parsed pattern elements.
315
316
```java { .api }
317
/**
318
* Base class for pattern syntax tree nodes.
319
*/
320
public class Node {
321
private Node next;
322
private Object value;
323
324
/**
325
* Set the next node in the chain.
326
* @param next next node
327
*/
328
public void setNext(Node next);
329
330
/**
331
* Get the next node.
332
* @return next node
333
*/
334
public Node getNext();
335
336
/**
337
* Set the node value.
338
* @param value node value
339
*/
340
public void setValue(Object value);
341
342
/**
343
* Get the node value.
344
* @return node value
345
*/
346
public Object getValue();
347
}
348
349
/**
350
* Node for literal text.
351
*/
352
public class LiteralNode extends Node { }
353
354
/**
355
* Node for simple conversion keywords.
356
*/
357
public class SimpleKeywordNode extends Node { }
358
359
/**
360
* Node for composite conversion keywords with options.
361
*/
362
public class CompositeNode extends Node {
363
private List<String> options;
364
365
/**
366
* Set conversion options.
367
* @param options list of option strings
368
*/
369
public void setOptions(List<String> options);
370
371
/**
372
* Get conversion options.
373
* @return list of options
374
*/
375
public List<String> getOptions();
376
}
377
```
378
379
## Utility Classes
380
381
### ConverterUtil
382
383
Utility methods for working with converter chains.
384
385
```java { .api }
386
/**
387
* Utility methods for converter chain management.
388
*/
389
public class ConverterUtil {
390
/**
391
* Set context on all converters in the chain.
392
* @param context context to set
393
* @param head head of converter chain
394
*/
395
public static <E> void setContextForConverters(Context context, Converter<E> head);
396
397
/**
398
* Start all converters in the chain.
399
* @param head head of converter chain
400
*/
401
public static <E> void startConverters(Converter<E> head);
402
403
/**
404
* Find tail converter in the chain.
405
* @param head head of converter chain
406
* @return tail converter
407
*/
408
public static <E> Converter<E> findTail(Converter<E> head);
409
}
410
```
411
412
## Usage Examples
413
414
### Basic Pattern Layout
415
416
```java
417
import ch.qos.logback.core.pattern.PatternLayoutBase;
418
419
public class SimplePatternLayout<E> extends PatternLayoutBase<E> {
420
@Override
421
public String doLayout(E event) {
422
// Use the compiled converter chain to format the event
423
StringBuilder sb = new StringBuilder();
424
if (head != null) {
425
head.write(sb, event);
426
}
427
return sb.toString();
428
}
429
}
430
431
// Configure and use
432
SimplePatternLayout<LoggingEvent> layout = new SimplePatternLayout<>();
433
layout.setContext(context);
434
layout.setPattern("%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n");
435
layout.start();
436
```
437
438
### Custom Converter Implementation
439
440
```java
441
import ch.qos.logback.core.pattern.FormattingConverter;
442
443
public class HostnameConverter<E> extends FormattingConverter<E> {
444
private static final String HOSTNAME = getHostname();
445
446
@Override
447
public String convert(E event) {
448
return HOSTNAME;
449
}
450
451
private static String getHostname() {
452
try {
453
return InetAddress.getLocalHost().getHostName();
454
} catch (UnknownHostException e) {
455
return "unknown";
456
}
457
}
458
}
459
460
// Register and use in pattern
461
Map<String, String> converterMap = new HashMap<>();
462
converterMap.put("hostname", HostnameConverter.class.getName());
463
464
// Pattern: "%d{yyyy-MM-dd HH:mm:ss} [%hostname] %msg%n"
465
```
466
467
### Color Pattern for Console
468
469
```java
470
import ch.qos.logback.core.pattern.color.*;
471
472
// Create pattern with colors
473
String colorPattern = "%black(%d{HH:mm:ss.SSS}) " +
474
"%highlight(%-5level) " +
475
"%cyan(%logger{36}) - " +
476
"%msg%n";
477
478
PatternLayoutBase<LoggingEvent> layout = new PatternLayoutBase<LoggingEvent>() {
479
@Override
480
public String doLayout(LoggingEvent event) {
481
StringBuilder sb = new StringBuilder();
482
if (head != null) {
483
head.write(sb, event);
484
}
485
return sb.toString();
486
}
487
};
488
489
layout.setContext(context);
490
layout.setPattern(colorPattern);
491
layout.start();
492
```
493
494
### Conditional Formatting Converter
495
496
```java
497
import ch.qos.logback.core.pattern.CompositeConverter;
498
499
public class LevelColorConverter<E> extends CompositeConverter<E> {
500
@Override
501
protected String transform(E event, String in) {
502
if (event instanceof LoggingEvent) {
503
LoggingEvent loggingEvent = (LoggingEvent) event;
504
Level level = loggingEvent.getLevel();
505
506
String colorCode;
507
switch (level.toString()) {
508
case "ERROR":
509
colorCode = ANSIConstants.RED;
510
break;
511
case "WARN":
512
colorCode = ANSIConstants.YELLOW;
513
break;
514
case "INFO":
515
colorCode = ANSIConstants.GREEN;
516
break;
517
case "DEBUG":
518
colorCode = ANSIConstants.CYAN;
519
break;
520
default:
521
colorCode = ANSIConstants.DEFAULT;
522
}
523
524
return ANSIConstants.ESC_START + colorCode + ANSIConstants.ESC_END +
525
in + ANSIConstants.RESET;
526
}
527
return in;
528
}
529
}
530
```
531
532
### Dynamic Pattern Configuration
533
534
```java
535
import ch.qos.logback.core.pattern.parser.Parser;
536
import ch.qos.logback.core.pattern.parser.Compiler;
537
538
public class DynamicPatternLayout<E> extends LayoutBase<E> {
539
private String pattern;
540
private Converter<E> head;
541
private Map<String, String> converterMap;
542
543
public void updatePattern(String newPattern) {
544
this.pattern = newPattern;
545
recompile();
546
}
547
548
private void recompile() {
549
try {
550
Parser<E> parser = new Parser<>(pattern);
551
parser.setContext(getContext());
552
Node head = parser.parse();
553
554
Compiler<E> compiler = new Compiler<>();
555
compiler.setContext(getContext());
556
this.head = compiler.compile(head, converterMap);
557
558
ConverterUtil.setContextForConverters(getContext(), this.head);
559
ConverterUtil.startConverters(this.head);
560
561
} catch (Exception e) {
562
addError("Failed to compile pattern: " + pattern, e);
563
}
564
}
565
566
@Override
567
public String doLayout(E event) {
568
if (head == null) {
569
return "";
570
}
571
572
StringBuilder sb = new StringBuilder();
573
head.write(sb, event);
574
return sb.toString();
575
}
576
577
public void setConverterMap(Map<String, String> converterMap) {
578
this.converterMap = converterMap;
579
}
580
}
581
```
582
583
### Pattern with Options
584
585
```java
586
// Custom converter that accepts options
587
public class TruncateConverter<E> extends FormattingConverter<E> {
588
private int maxLength = 50;
589
private String suffix = "...";
590
591
@Override
592
public void start() {
593
List<String> options = getOptionList();
594
if (options != null && !options.isEmpty()) {
595
try {
596
maxLength = Integer.parseInt(options.get(0));
597
if (options.size() > 1) {
598
suffix = options.get(1);
599
}
600
} catch (NumberFormatException e) {
601
addError("Invalid truncate length: " + options.get(0));
602
}
603
}
604
super.start();
605
}
606
607
@Override
608
public String convert(E event) {
609
String message = event.toString();
610
if (message.length() <= maxLength) {
611
return message;
612
}
613
return message.substring(0, maxLength - suffix.length()) + suffix;
614
}
615
}
616
617
// Usage in pattern: "%truncate{30,…}(%msg)"
618
```
619
620
## Common Pattern Elements
621
622
### Standard Conversion Words
623
- `%d{pattern}` - Date/time formatting
624
- `%p` or `%level` - Log level
625
- `%t` or `%thread` - Thread name
626
- `%c{length}` or `%logger{length}` - Logger name
627
- `%m` or `%msg` - Message
628
- `%n` - Line separator
629
- `%r` - Milliseconds since start
630
- `%F` - File name
631
- `%L` - Line number
632
- `%M` - Method name
633
634
### Formatting Options
635
- `%20logger` - Right-pad to 20 characters
636
- `%-20logger` - Left-pad to 20 characters
637
- `%.30logger` - Truncate to 30 characters
638
- `%.-30logger` - Truncate from left to 30 characters
639
- `%20.30logger` - Pad to 20, truncate at 30
640
641
### Color Support
642
- `%black()`, `%red()`, `%green()`, `%yellow()`, `%blue()`, `%magenta()`, `%cyan()`, `%white()`
643
- `%boldRed()`, `%boldGreen()`, etc.
644
- `%highlight()` - Level-based coloring
645
646
The pattern processing framework provides powerful and flexible formatting capabilities with excellent extensibility for custom formatting requirements.