0
# Markers & Filtering
1
2
Marker system for adding hierarchical, filterable metadata to log events. Enables sophisticated filtering and routing based on marker taxonomy.
3
4
## Capabilities
5
6
### Marker Interface
7
8
Hierarchical markers for adding filterable metadata to log events.
9
10
```java { .api }
11
/**
12
* Marker interface for adding filterable information to log messages
13
*/
14
public interface Marker extends Serializable {
15
/** Get the marker name */
16
String getName();
17
18
/** Add parent markers to this marker */
19
Marker addParents(Marker... markers);
20
21
/** Set parent markers, replacing any existing parents */
22
Marker setParents(Marker... markers);
23
24
/** Remove a parent marker */
25
boolean remove(Marker marker);
26
27
/** Get array of parent markers */
28
Marker[] getParents();
29
30
/** Check if this marker has any parents */
31
boolean hasParents();
32
33
/** Check if this marker is an instance of the given marker (including hierarchy) */
34
boolean isInstanceOf(Marker marker);
35
36
/** Check if this marker is an instance of the named marker (including hierarchy) */
37
boolean isInstanceOf(String name);
38
39
/** Iterator over parents */
40
Iterator<Marker> iterator();
41
42
/** Check if marker contains the given marker in its hierarchy */
43
boolean contains(Marker other);
44
45
/** Check if marker contains the named marker in its hierarchy */
46
boolean contains(String name);
47
}
48
```
49
50
**Usage Examples:**
51
52
```java
53
private static final Logger logger = LogManager.getLogger();
54
55
public void demonstrateBasicMarkers() {
56
// Create markers
57
Marker networkMarker = MarkerManager.getMarker("NETWORK");
58
Marker securityMarker = MarkerManager.getMarker("SECURITY");
59
Marker databaseMarker = MarkerManager.getMarker("DATABASE");
60
61
// Use markers in logging
62
logger.info(networkMarker, "Network connection established");
63
logger.warn(securityMarker, "Invalid login attempt detected");
64
logger.error(databaseMarker, "Database connection failed");
65
66
// Markers can be used with all logging methods
67
logger.debug(networkMarker, "Network packet received: {}", packetData);
68
logger.error(securityMarker, "Security violation", exception);
69
}
70
71
// Hierarchical marker example
72
public void demonstrateMarkerHierarchy() {
73
// Create parent markers
74
Marker auditMarker = MarkerManager.getMarker("AUDIT");
75
Marker securityMarker = MarkerManager.getMarker("SECURITY");
76
77
// Create child markers
78
Marker loginMarker = MarkerManager.getMarker("LOGIN");
79
Marker accessMarker = MarkerManager.getMarker("ACCESS");
80
81
// Establish hierarchy - LOGIN and ACCESS are both types of SECURITY
82
loginMarker.addParents(securityMarker);
83
accessMarker.addParents(securityMarker);
84
85
// SECURITY is a type of AUDIT
86
securityMarker.addParents(auditMarker);
87
88
// Now LOGIN is also considered an instance of AUDIT through the hierarchy
89
logger.info(loginMarker, "User logged in"); // This log event has LOGIN, SECURITY, and AUDIT markers
90
91
// Check hierarchy
92
if (loginMarker.isInstanceOf(auditMarker)) {
93
System.out.println("Login events are audit events"); // This will print
94
}
95
96
if (loginMarker.isInstanceOf("SECURITY")) {
97
System.out.println("Login events are security events"); // This will print
98
}
99
}
100
```
101
102
### MarkerManager Factory
103
104
Factory for creating and managing Marker instances with singleton behavior.
105
106
```java { .api }
107
/**
108
* Factory for creating and managing Marker instances
109
*/
110
public final class MarkerManager {
111
/** Get or create a marker with the given name */
112
public static Marker getMarker(String name);
113
114
/** Check if a marker with the given name exists */
115
public static boolean exists(String key);
116
117
/** Clear all markers (use with caution) */
118
public static void clear();
119
120
/**
121
* Actual Marker implementation
122
*/
123
public static class Log4jMarker implements Marker {
124
// Implementation of Marker interface
125
}
126
}
127
```
128
129
**Usage Examples:**
130
131
```java
132
public class MarkerConstants {
133
// Define application markers as constants
134
public static final Marker SECURITY = MarkerManager.getMarker("SECURITY");
135
public static final Marker PERFORMANCE = MarkerManager.getMarker("PERFORMANCE");
136
public static final Marker BUSINESS = MarkerManager.getMarker("BUSINESS");
137
public static final Marker TECHNICAL = MarkerManager.getMarker("TECHNICAL");
138
139
// Hierarchical markers
140
public static final Marker LOGIN = MarkerManager.getMarker("LOGIN");
141
public static final Marker LOGOUT = MarkerManager.getMarker("LOGOUT");
142
public static final Marker ACCESS_DENIED = MarkerManager.getMarker("ACCESS_DENIED");
143
144
static {
145
// Set up marker hierarchy
146
LOGIN.addParents(SECURITY);
147
LOGOUT.addParents(SECURITY);
148
ACCESS_DENIED.addParents(SECURITY);
149
150
SECURITY.addParents(BUSINESS);
151
PERFORMANCE.addParents(TECHNICAL);
152
}
153
}
154
155
public class ApplicationService {
156
private static final Logger logger = LogManager.getLogger();
157
158
public void login(String username, String password) {
159
logger.info(MarkerConstants.LOGIN, "Login attempt for user: {}", username);
160
161
if (authenticate(username, password)) {
162
logger.info(MarkerConstants.LOGIN, "Login successful for user: {}", username);
163
} else {
164
logger.warn(MarkerConstants.ACCESS_DENIED, "Login failed for user: {}", username);
165
}
166
}
167
168
public void checkMarkerExistence() {
169
if (MarkerManager.exists("SECURITY")) {
170
logger.debug("Security marker is available");
171
}
172
173
// Get the same marker instance (singleton behavior)
174
Marker sec1 = MarkerManager.getMarker("SECURITY");
175
Marker sec2 = MarkerManager.getMarker("SECURITY");
176
assert sec1 == sec2; // Same instance
177
}
178
}
179
```
180
181
### Marker-Aware Logging
182
183
All logging methods support markers for enhanced filtering and routing.
184
185
```java { .api }
186
public interface Logger {
187
// All logging methods have marker overloads
188
void trace(Marker marker, String message);
189
void debug(Marker marker, String message);
190
void info(Marker marker, String message);
191
void warn(Marker marker, String message);
192
void error(Marker marker, String message);
193
void fatal(Marker marker, String message);
194
195
// Parameterized logging with markers
196
void trace(Marker marker, String message, Object... params);
197
void debug(Marker marker, String message, Object... params);
198
void info(Marker marker, String message, Object... params);
199
void warn(Marker marker, String message, Object... params);
200
void error(Marker marker, String message, Object... params);
201
void fatal(Marker marker, String message, Object... params);
202
203
// Exception logging with markers
204
void trace(Marker marker, String message, Throwable throwable);
205
void debug(Marker marker, String message, Throwable throwable);
206
void info(Marker marker, String message, Throwable throwable);
207
void warn(Marker marker, String message, Throwable throwable);
208
void error(Marker marker, String message, Throwable throwable);
209
void fatal(Marker marker, String message, Throwable throwable);
210
211
// Generic logging with markers
212
void log(Level level, Marker marker, String message);
213
void log(Level level, Marker marker, String message, Object... params);
214
void log(Level level, Marker marker, String message, Throwable throwable);
215
216
// Level checking with markers
217
boolean isTraceEnabled(Marker marker);
218
boolean isDebugEnabled(Marker marker);
219
boolean isInfoEnabled(Marker marker);
220
boolean isWarnEnabled(Marker marker);
221
boolean isErrorEnabled(Marker marker);
222
boolean isFatalEnabled(Marker marker);
223
boolean isEnabled(Level level, Marker marker);
224
}
225
```
226
227
**Usage Examples:**
228
229
```java
230
private static final Logger logger = LogManager.getLogger();
231
private static final Marker PERFORMANCE = MarkerManager.getMarker("PERFORMANCE");
232
private static final Marker SECURITY = MarkerManager.getMarker("SECURITY");
233
private static final Marker AUDIT = MarkerManager.getMarker("AUDIT");
234
235
public class MarkerLoggingExamples {
236
237
public void demonstrateMarkerLogging() {
238
// Basic marker logging
239
logger.info(PERFORMANCE, "Operation completed in {}ms", executionTime);
240
logger.warn(SECURITY, "Suspicious activity detected from IP: {}", clientIP);
241
logger.error(AUDIT, "Configuration change failed", exception);
242
243
// Conditional logging with markers
244
if (logger.isDebugEnabled(PERFORMANCE)) {
245
logger.debug(PERFORMANCE, "Performance metrics: {}",
246
gatherDetailedMetrics());
247
}
248
249
// Multiple markers through hierarchy
250
Marker sqlMarker = MarkerManager.getMarker("SQL");
251
sqlMarker.addParents(PERFORMANCE); // SQL operations are performance-related
252
253
logger.debug(sqlMarker, "Executing query: {}", sql);
254
// This log event will match filters for both SQL and PERFORMANCE markers
255
}
256
257
// Web request processing with markers
258
public void processWebRequest(HttpServletRequest request) {
259
Marker requestMarker = MarkerManager.getMarker("REQUEST");
260
261
logger.info(requestMarker, "Processing {} request to {}",
262
request.getMethod(), request.getRequestURI());
263
264
try {
265
String result = handleRequest(request);
266
logger.info(requestMarker, "Request processed successfully");
267
} catch (SecurityException e) {
268
logger.error(SECURITY, "Security violation in request processing", e);
269
} catch (Exception e) {
270
logger.error(requestMarker, "Request processing failed", e);
271
}
272
}
273
274
// Business logic with contextual markers
275
public void processPayment(PaymentRequest payment) {
276
Marker paymentMarker = MarkerManager.getMarker("PAYMENT");
277
paymentMarker.addParents(AUDIT); // Payment operations are auditable
278
279
logger.info(paymentMarker, "Processing payment of ${} for user {}",
280
payment.getAmount(), payment.getUserId());
281
282
if (payment.getAmount().compareTo(BigDecimal.valueOf(10000)) > 0) {
283
Marker highValueMarker = MarkerManager.getMarker("HIGH_VALUE");
284
highValueMarker.addParents(paymentMarker, SECURITY);
285
286
logger.warn(highValueMarker, "High-value payment transaction: ${}",
287
payment.getAmount());
288
}
289
290
try {
291
PaymentResult result = paymentProcessor.process(payment);
292
logger.info(paymentMarker, "Payment processed successfully: {}",
293
result.getTransactionId());
294
} catch (PaymentException e) {
295
logger.error(paymentMarker, "Payment processing failed", e);
296
}
297
}
298
}
299
```
300
301
### LogBuilder with Markers
302
303
Fluent API supports markers for complex log event construction.
304
305
```java { .api }
306
public interface LogBuilder {
307
/** Add a marker to the log event */
308
LogBuilder withMarker(Marker marker);
309
310
// All other LogBuilder methods remain the same
311
LogBuilder withThrowable(Throwable throwable);
312
LogBuilder withLocation();
313
void log(String message);
314
void log(String message, Object... params);
315
}
316
```
317
318
**Usage Examples:**
319
320
```java
321
private static final Logger logger = LogManager.getLogger();
322
private static final Marker SECURITY = MarkerManager.getMarker("SECURITY");
323
private static final Marker AUDIT = MarkerManager.getMarker("AUDIT");
324
325
public void demonstrateLogBuilderWithMarkers() {
326
// Simple marker with LogBuilder
327
logger.atError()
328
.withMarker(SECURITY)
329
.log("Security violation detected");
330
331
// Complex log event with marker, exception, and location
332
logger.atWarn()
333
.withMarker(AUDIT)
334
.withThrowable(exception)
335
.withLocation()
336
.log("Audit event failed for user {}", userId);
337
338
// Conditional marker application
339
LogBuilder builder = logger.atInfo();
340
341
if (isSecurityRelated) {
342
builder = builder.withMarker(SECURITY);
343
}
344
345
if (exception != null) {
346
builder = builder.withThrowable(exception);
347
}
348
349
builder.log("Dynamic marker application: {}", eventData);
350
351
// Multiple markers through hierarchy
352
Marker specificMarker = MarkerManager.getMarker("SQL_INJECTION");
353
specificMarker.addParents(SECURITY);
354
355
logger.atError()
356
.withMarker(specificMarker) // Includes both SQL_INJECTION and SECURITY
357
.withLocation()
358
.log("SQL injection attempt detected from {}", clientIP);
359
}
360
```
361
362
### Marker Filtering Patterns
363
364
Common patterns for using markers in filtering and routing configurations.
365
366
```java { .api }
367
// Example marker hierarchy for a web application
368
public class WebAppMarkers {
369
// Top-level categories
370
public static final Marker APPLICATION = MarkerManager.getMarker("APPLICATION");
371
public static final Marker INFRASTRUCTURE = MarkerManager.getMarker("INFRASTRUCTURE");
372
373
// Application subcategories
374
public static final Marker BUSINESS_LOGIC = MarkerManager.getMarker("BUSINESS_LOGIC");
375
public static final Marker SECURITY = MarkerManager.getMarker("SECURITY");
376
public static final Marker PERFORMANCE = MarkerManager.getMarker("PERFORMANCE");
377
378
// Infrastructure subcategories
379
public static final Marker DATABASE = MarkerManager.getMarker("DATABASE");
380
public static final Marker NETWORK = MarkerManager.getMarker("NETWORK");
381
public static final Marker CACHE = MarkerManager.getMarker("CACHE");
382
383
// Specific security markers
384
public static final Marker AUTHENTICATION = MarkerManager.getMarker("AUTHENTICATION");
385
public static final Marker AUTHORIZATION = MarkerManager.getMarker("AUTHORIZATION");
386
public static final Marker AUDIT = MarkerManager.getMarker("AUDIT");
387
388
static {
389
// Set up hierarchy
390
BUSINESS_LOGIC.addParents(APPLICATION);
391
SECURITY.addParents(APPLICATION);
392
PERFORMANCE.addParents(APPLICATION);
393
394
DATABASE.addParents(INFRASTRUCTURE);
395
NETWORK.addParents(INFRASTRUCTURE);
396
CACHE.addParents(INFRASTRUCTURE);
397
398
AUTHENTICATION.addParents(SECURITY);
399
AUTHORIZATION.addParents(SECURITY);
400
AUDIT.addParents(SECURITY);
401
}
402
}
403
```
404
405
**Usage Examples:**
406
407
```java
408
public class MarkerUsagePatterns {
409
private static final Logger logger = LogManager.getLogger();
410
411
// Service layer with business logic markers
412
@Service
413
public class OrderService {
414
415
public Order createOrder(OrderRequest request) {
416
logger.info(WebAppMarkers.BUSINESS_LOGIC,
417
"Creating order for customer {}", request.getCustomerId());
418
419
try {
420
validateOrderRequest(request);
421
Order order = processOrder(request);
422
423
logger.info(WebAppMarkers.AUDIT,
424
"Order {} created successfully", order.getId());
425
426
return order;
427
428
} catch (ValidationException e) {
429
logger.warn(WebAppMarkers.BUSINESS_LOGIC,
430
"Order validation failed", e);
431
throw e;
432
} catch (Exception e) {
433
logger.error(WebAppMarkers.BUSINESS_LOGIC,
434
"Order creation failed", e);
435
throw e;
436
}
437
}
438
439
private void validateOrderRequest(OrderRequest request) {
440
logger.debug(WebAppMarkers.BUSINESS_LOGIC,
441
"Validating order request");
442
443
// Validation with specific markers
444
if (!authService.hasPermission(request.getCustomerId())) {
445
logger.warn(WebAppMarkers.AUTHORIZATION,
446
"Customer {} lacks permission to create orders",
447
request.getCustomerId());
448
throw new AuthorizationException("Insufficient permissions");
449
}
450
}
451
}
452
453
// Data access layer with infrastructure markers
454
@Repository
455
public class OrderRepository {
456
457
public Order save(Order order) {
458
logger.debug(WebAppMarkers.DATABASE, "Saving order to database");
459
460
long startTime = System.currentTimeMillis();
461
try {
462
Order savedOrder = jdbcTemplate.save(order);
463
464
long duration = System.currentTimeMillis() - startTime;
465
if (duration > 1000) {
466
logger.warn(WebAppMarkers.PERFORMANCE,
467
"Slow database operation: {}ms", duration);
468
}
469
470
return savedOrder;
471
472
} catch (DataAccessException e) {
473
logger.error(WebAppMarkers.DATABASE,
474
"Database error saving order", e);
475
throw e;
476
}
477
}
478
}
479
480
// Security interceptor with authentication markers
481
@Component
482
public class SecurityInterceptor {
483
484
public boolean authenticate(String token) {
485
logger.debug(WebAppMarkers.AUTHENTICATION,
486
"Authenticating token");
487
488
if (isValidToken(token)) {
489
logger.info(WebAppMarkers.AUTHENTICATION,
490
"Token authentication successful");
491
return true;
492
} else {
493
logger.warn(WebAppMarkers.SECURITY,
494
"Invalid token authentication attempt");
495
return false;
496
}
497
}
498
}
499
}
500
```