0
# Configuration Framework
1
2
XML-based configuration processing through the Joran framework, supporting property substitution, conditional configuration, and extensible action handlers. The configuration system enables declarative setup of logging components with advanced features like variable substitution and conditional logic.
3
4
## Capabilities
5
6
### Core Configuration Classes
7
8
#### GenericXMLConfigurator
9
10
Base class for XML-based configuration with multiple input source support.
11
12
```java { .api }
13
/**
14
* Base XML configuration processor supporting multiple input sources.
15
*/
16
public abstract class GenericXMLConfigurator extends ContextAwareBase {
17
/**
18
* Configure from URL.
19
* @param url configuration file URL
20
* @throws JoranException if configuration fails
21
*/
22
public void doConfigure(URL url) throws JoranException;
23
24
/**
25
* Configure from file.
26
* @param file configuration file
27
* @throws JoranException if configuration fails
28
*/
29
public void doConfigure(File file) throws JoranException;
30
31
/**
32
* Configure from input stream.
33
* @param inputStream configuration input stream
34
* @throws JoranException if configuration fails
35
*/
36
public void doConfigure(InputStream inputStream) throws JoranException;
37
38
/**
39
* Configure from input source.
40
* @param inputSource SAX input source
41
* @throws JoranException if configuration fails
42
*/
43
public void doConfigure(InputSource inputSource) throws JoranException;
44
}
45
```
46
47
#### JoranConfigurator
48
49
Joran-based XML configurator with SAX event recording and playback.
50
51
```java { .api }
52
/**
53
* Joran-based XML configurator with advanced processing capabilities.
54
*/
55
public class JoranConfigurator extends GenericXMLConfigurator {
56
/**
57
* Configure context from URL.
58
* @param context target context
59
* @param url configuration URL
60
* @throws JoranException if configuration fails
61
*/
62
public void configure(Context context, URL url) throws JoranException;
63
64
/**
65
* Record SAX events from input stream for later processing.
66
* @param inputStream configuration input stream
67
* @return list of recorded SAX events
68
* @throws JoranException if recording fails
69
*/
70
public List<SaxEvent> recordEvents(InputStream inputStream) throws JoranException;
71
}
72
```
73
74
### Context Interface
75
76
Central configuration and service container for all logback components.
77
78
```java { .api }
79
/**
80
* Central context providing shared services and configuration.
81
*/
82
public interface Context extends PropertyContainer {
83
/**
84
* Get the status manager for diagnostic messages.
85
* @return status manager
86
*/
87
StatusManager getStatusManager();
88
89
/**
90
* Store an object by key.
91
* @param key object key
92
* @param value object to store
93
*/
94
void putObject(String key, Object value);
95
96
/**
97
* Retrieve stored object by key.
98
* @param key object key
99
* @return stored object or null
100
*/
101
Object getObject(String key);
102
103
/**
104
* Get context name.
105
* @return context name
106
*/
107
String getName();
108
109
/**
110
* Set context name.
111
* @param name context name
112
*/
113
void setName(String name);
114
115
/**
116
* Get context birth time.
117
* @return creation timestamp
118
*/
119
long getBirthTime();
120
121
/**
122
* Get configuration lock for thread safety.
123
* @return reentrant lock
124
*/
125
ReentrantLock getConfigurationLock();
126
127
/**
128
* Get scheduled executor service.
129
* @return scheduled executor
130
*/
131
ScheduledExecutorService getScheduledExecutorService();
132
133
/**
134
* Get general executor service.
135
* @return executor service
136
*/
137
ExecutorService getExecutorService();
138
139
/**
140
* Get alternate executor service.
141
* @return alternate executor
142
*/
143
ExecutorService getAlternateExecutorService();
144
145
/**
146
* Register a lifecycle component for management.
147
* @param component component to register
148
*/
149
void register(LifeCycle component);
150
151
/**
152
* Add a scheduled future for tracking.
153
* @param scheduledFuture future to track
154
*/
155
void addScheduledFuture(ScheduledFuture<?> scheduledFuture);
156
157
/**
158
* Get sequence number generator.
159
* @return sequence generator
160
*/
161
SequenceNumberGenerator getSequenceNumberGenerator();
162
}
163
```
164
165
#### ContextBase
166
167
Base implementation of Context interface with complete service management.
168
169
```java { .api }
170
/**
171
* Base context implementation with service management and lifecycle support.
172
*/
173
public class ContextBase implements Context {
174
/**
175
* Complete implementation of Context interface.
176
* Provides property storage, object registry, executor services, and lifecycle management.
177
*/
178
179
@Override
180
public StatusManager getStatusManager();
181
182
@Override
183
public void putObject(String key, Object value);
184
185
@Override
186
public Object getObject(String key);
187
188
@Override
189
public String getProperty(String key);
190
191
@Override
192
public void putProperty(String key, String value);
193
194
@Override
195
public Map<String, String> getCopyOfPropertyMap();
196
197
// ... additional Context methods
198
}
199
```
200
201
## Property System
202
203
### PropertyContainer Interface
204
205
Interface for property storage and retrieval with variable substitution support.
206
207
```java { .api }
208
/**
209
* Interface for property storage and retrieval.
210
*/
211
public interface PropertyContainer {
212
/**
213
* Get property value with variable substitution.
214
* @param key property key
215
* @return property value with variables substituted
216
*/
217
String getProperty(String key);
218
219
/**
220
* Set property value.
221
* @param key property key
222
* @param value property value
223
*/
224
void putProperty(String key, String value);
225
226
/**
227
* Get copy of all properties.
228
* @return map of all properties
229
*/
230
Map<String, String> getCopyOfPropertyMap();
231
}
232
```
233
234
### PropertyDefiner Interface
235
236
Interface for dynamic property definition and computation.
237
238
```java { .api }
239
/**
240
* Interface for defining properties dynamically.
241
*/
242
public interface PropertyDefiner extends ContextAware {
243
/**
244
* Get the computed property value.
245
* @return property value
246
*/
247
String getPropertyValue();
248
}
249
```
250
251
### Property Definers
252
253
#### ResourceExistsPropertyDefiner
254
255
Property definer that checks for resource existence.
256
257
```java { .api }
258
/**
259
* Property definer that returns "true" if a resource exists.
260
*/
261
public class ResourceExistsPropertyDefiner extends PropertyDefinerBase {
262
/**
263
* Set the resource path to check.
264
* @param resource resource path (classpath or file)
265
*/
266
public void setResource(String resource);
267
268
/**
269
* Get the resource path.
270
* @return resource path
271
*/
272
public String getResource();
273
274
/**
275
* Returns "true" if resource exists, "false" otherwise.
276
* @return "true" or "false"
277
*/
278
@Override
279
public String getPropertyValue();
280
}
281
```
282
283
#### FileExistsPropertyDefiner
284
285
Property definer that checks for file existence.
286
287
```java { .api }
288
/**
289
* Property definer that returns "true" if a file exists.
290
*/
291
public class FileExistsPropertyDefiner extends PropertyDefinerBase {
292
/**
293
* Set the file path to check.
294
* @param path file path
295
*/
296
public void setPath(String path);
297
298
/**
299
* Get the file path.
300
* @return file path
301
*/
302
public String getPath();
303
304
/**
305
* Returns "true" if file exists, "false" otherwise.
306
* @return "true" or "false"
307
*/
308
@Override
309
public String getPropertyValue();
310
}
311
```
312
313
#### CanonicalHostNamePropertyDefiner
314
315
Property definer that provides the canonical hostname.
316
317
```java { .api }
318
/**
319
* Property definer that returns the canonical hostname.
320
*/
321
public class CanonicalHostNamePropertyDefiner extends PropertyDefinerBase {
322
/**
323
* Returns the canonical hostname of the local machine.
324
* @return canonical hostname
325
*/
326
@Override
327
public String getPropertyValue();
328
}
329
```
330
331
## Action Framework
332
333
### Action Base Class
334
335
Base class for configuration actions that process XML elements.
336
337
```java { .api }
338
/**
339
* Base class for configuration actions that process XML elements.
340
*/
341
public abstract class Action implements ContextAware {
342
/**
343
* Called when element starts.
344
* @param interpreter SAX event interpreter
345
* @param name element name
346
* @param attributes element attributes
347
* @throws ActionException if action fails
348
*/
349
public abstract void begin(SaxEventInterpreter interpreter,
350
String name, Attributes attributes) throws ActionException;
351
352
/**
353
* Called when element ends.
354
* @param interpreter SAX event interpreter
355
* @param name element name
356
* @throws ActionException if action fails
357
*/
358
public abstract void end(SaxEventInterpreter interpreter,
359
String name) throws ActionException;
360
361
/**
362
* Called with element body text.
363
* @param interpreter SAX event interpreter
364
* @param body element body text
365
* @throws ActionException if action fails
366
*/
367
public void body(SaxEventInterpreter interpreter, String body) throws ActionException;
368
}
369
```
370
371
### Configuration Actions
372
373
#### PropertyAction
374
375
Action for setting context properties from XML.
376
377
```java { .api }
378
/**
379
* Action for processing <property> elements in configuration.
380
*/
381
public class PropertyAction extends Action {
382
@Override
383
public void begin(SaxEventInterpreter interpreter, String name, Attributes attributes);
384
385
@Override
386
public void end(SaxEventInterpreter interpreter, String name);
387
}
388
```
389
390
#### DefinePropertyAction
391
392
Action for defining properties using PropertyDefiner implementations.
393
394
```java { .api }
395
/**
396
* Action for processing <define> elements that create PropertyDefiners.
397
*/
398
public class DefinePropertyAction extends Action {
399
@Override
400
public void begin(SaxEventInterpreter interpreter, String name, Attributes attributes);
401
402
@Override
403
public void end(SaxEventInterpreter interpreter, String name);
404
}
405
```
406
407
## Conditional Configuration
408
409
### Conditional Processing
410
411
Support for conditional configuration using `<if>`, `<then>`, and `<else>` elements.
412
413
```java { .api }
414
/**
415
* Base class for boolean conditions in configuration.
416
*/
417
public abstract class Condition implements ContextAware {
418
/**
419
* Evaluate the condition.
420
* @return true if condition is met
421
*/
422
public abstract boolean evaluate();
423
}
424
425
/**
426
* Property wrapper for script evaluation in conditional configuration.
427
*/
428
public class PropertyWrapperForScripts {
429
/**
430
* Get property value.
431
* @param key property key
432
* @return property value
433
*/
434
public String property(String key);
435
436
/**
437
* Short form for property access.
438
* @param key property key
439
* @return property value
440
*/
441
public String p(String key);
442
443
/**
444
* Check if property is null.
445
* @param key property key
446
* @return true if null or undefined
447
*/
448
public boolean isNull(String key);
449
450
/**
451
* Check if property is defined.
452
* @param key property key
453
* @return true if defined
454
*/
455
public boolean isDefined(String key);
456
}
457
```
458
459
## Model Framework
460
461
### Configuration Model
462
463
Object representation of configuration elements for processing.
464
465
```java { .api }
466
/**
467
* Base class for configuration model elements.
468
*/
469
public class Model {
470
/**
471
* Add a sub-model as a child.
472
* @param model child model
473
*/
474
public void addSubModel(Model model);
475
476
/**
477
* Get all sub-models.
478
* @return list of child models
479
*/
480
public List<Model> getSubModels();
481
482
/**
483
* Set the XML tag name.
484
* @param tag tag name
485
*/
486
public void setTag(String tag);
487
488
/**
489
* Get the XML tag name.
490
* @return tag name
491
*/
492
public String getTag();
493
494
/**
495
* Set the body text content.
496
* @param bodyText body text
497
*/
498
public void setBodyText(String bodyText);
499
500
/**
501
* Get the body text content.
502
* @return body text
503
*/
504
public String getBodyText();
505
}
506
507
/**
508
* Model for component elements with class names.
509
*/
510
public class ComponentModel extends Model {
511
/**
512
* Set the component class name.
513
* @param className fully qualified class name
514
*/
515
public void setClassName(String className);
516
517
/**
518
* Get the component class name.
519
* @return class name
520
*/
521
public String getClassName();
522
}
523
```
524
525
## Variable Substitution
526
527
### Substitution Framework
528
529
System for resolving variables in configuration values.
530
531
```java { .api }
532
/**
533
* Utility for variable substitution in configuration values.
534
*/
535
public class OptionHelper {
536
/**
537
* Substitute variables in a string using property container.
538
* Variables are in ${variable} format.
539
* @param val string with variables
540
* @param pc property container for variable lookup
541
* @return string with variables substituted
542
*/
543
public static String substVars(String val, PropertyContainer pc);
544
545
/**
546
* Instantiate class by name with context.
547
* @param className class name to instantiate
548
* @param superClass expected superclass
549
* @param context context for dependency injection
550
* @return instantiated object
551
*/
552
public static Object instantiateByClassName(String className,
553
Class<?> superClass,
554
Context context);
555
}
556
```
557
558
## Usage Examples
559
560
### Basic XML Configuration
561
562
```xml
563
<configuration>
564
<!-- Set properties -->
565
<property name="LOG_DIR" value="/var/log/myapp" />
566
<property name="LOG_LEVEL" value="INFO" />
567
568
<!-- Define dynamic properties -->
569
<define name="HOSTNAME" class="ch.qos.logback.core.property.CanonicalHostNamePropertyDefiner" />
570
571
<!-- Configure appender -->
572
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
573
<file>${LOG_DIR}/application-${HOSTNAME}.log</file>
574
<append>true</append>
575
<encoder>
576
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
577
</encoder>
578
</appender>
579
580
<!-- Configure rolling appender -->
581
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
582
<file>${LOG_DIR}/app.log</file>
583
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
584
<fileNamePattern>${LOG_DIR}/app.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
585
<maxFileSize>100MB</maxFileSize>
586
<maxHistory>30</maxHistory>
587
<totalSizeCap>10GB</totalSizeCap>
588
</rollingPolicy>
589
<encoder>
590
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger - %msg%n</pattern>
591
</encoder>
592
</appender>
593
</configuration>
594
```
595
596
### Conditional Configuration
597
598
```xml
599
<configuration>
600
<property name="ENV" value="${ENV:-development}" />
601
602
<!-- Development configuration -->
603
<if condition='property("ENV").equals("development")'>
604
<then>
605
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
606
<encoder>
607
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
608
</encoder>
609
</appender>
610
</then>
611
</if>
612
613
<!-- Production configuration -->
614
<if condition='property("ENV").equals("production")'>
615
<then>
616
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
617
<file>/var/log/app/application.log</file>
618
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
619
<fileNamePattern>/var/log/app/application.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
620
<maxHistory>90</maxHistory>
621
</rollingPolicy>
622
<encoder>
623
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
624
</encoder>
625
</appender>
626
</then>
627
</if>
628
</configuration>
629
```
630
631
### Programmatic Configuration
632
633
```java
634
import ch.qos.logback.core.joran.JoranConfigurator;
635
import ch.qos.logback.core.Context;
636
import ch.qos.logback.core.ContextBase;
637
638
// Create context
639
Context context = new ContextBase();
640
641
// Set properties programmatically
642
context.putProperty("LOG_DIR", "/tmp/logs");
643
context.putProperty("APP_NAME", "MyApplication");
644
645
// Configure from file
646
JoranConfigurator configurator = new JoranConfigurator();
647
configurator.setContext(context);
648
649
try {
650
// Load configuration from classpath
651
URL configUrl = getClass().getResource("/logback-config.xml");
652
configurator.doConfigure(configUrl);
653
} catch (JoranException e) {
654
// Handle configuration error
655
StatusPrinter.printInCaseOfErrorsOrWarnings(context);
656
}
657
```
658
659
### Custom Property Definer
660
661
```java
662
import ch.qos.logback.core.spi.PropertyDefiner;
663
import ch.qos.logback.core.spi.ContextAwareBase;
664
665
public class EnvironmentPropertyDefiner extends ContextAwareBase implements PropertyDefiner {
666
private String variableName;
667
private String defaultValue;
668
669
@Override
670
public String getPropertyValue() {
671
String value = System.getenv(variableName);
672
if (value == null) {
673
value = System.getProperty(variableName, defaultValue);
674
}
675
return value != null ? value : defaultValue;
676
}
677
678
public void setVariableName(String variableName) {
679
this.variableName = variableName;
680
}
681
682
public void setDefaultValue(String defaultValue) {
683
this.defaultValue = defaultValue;
684
}
685
}
686
```
687
688
Usage in XML:
689
690
```xml
691
<configuration>
692
<define name="PORT" class="com.example.EnvironmentPropertyDefiner">
693
<variableName>SERVER_PORT</variableName>
694
<defaultValue>8080</defaultValue>
695
</define>
696
697
<property name="LOG_FILE" value="/var/log/app-${PORT}.log" />
698
</configuration>
699
```
700
701
## Configuration Features
702
703
### Variable Substitution
704
- `${variable}` syntax for property substitution
705
- Default values: `${variable:-default}`
706
- Nested substitution support
707
- System property and environment variable access
708
709
### Property Sources
710
- XML `<property>` elements
711
- System properties (`-Dprop=value`)
712
- Environment variables
713
- Dynamic property definers
714
- Context object store
715
716
### Conditional Logic
717
- `<if condition="...">` elements
718
- JavaScript-like expressions
719
- Property-based conditions
720
- Environment-specific configuration
721
722
### File Inclusion
723
- `<include>` elements for modular configuration
724
- Resource and file path support
725
- Conditional inclusion
726
727
### Error Handling
728
- Configuration validation
729
- Status messages for diagnostics
730
- Graceful degradation on errors