or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

appenders.mdconfiguration.mdcore-logging.mdencoders-layouts.mdfilters.mdindex.mdnetwork-logging.mdservlet-integration.md

filters.mddocs/

0

# Filters

1

2

Event filtering mechanisms for controlling which log events are processed at various levels of the logging pipeline. Filters provide fine-grained control over log processing with minimal performance impact.

3

4

## Capabilities

5

6

### Core Filter Interface

7

8

Base interface and functionality for all filters.

9

10

```java { .api }

11

/**

12

* Core filter interface for controlling log event processing

13

*/

14

public abstract class Filter<E> extends ContextAwareBase implements LifeCycle {

15

private String name;

16

17

/**

18

* Decide whether to accept, deny, or remain neutral about an event

19

*/

20

public abstract FilterReply decide(E event);

21

22

public String getName();

23

public void setName(String name);

24

25

// LifeCycle methods

26

public void start();

27

public void stop();

28

public boolean isStarted();

29

}

30

31

/**

32

* Filter decision enumeration

33

*/

34

public enum FilterReply {

35

DENY, // Reject the event immediately

36

NEUTRAL, // Let other filters decide

37

ACCEPT // Accept the event immediately

38

}

39

40

/**

41

* Interface for components that can have filters attached

42

*/

43

public interface FilterAttachable<E> {

44

void addFilter(Filter<E> newFilter);

45

void clearAllFilters();

46

List<Filter<E>> getCopyOfAttachedFiltersList();

47

FilterReply getFilterChainDecision(E event);

48

}

49

```

50

51

### Level Filters

52

53

Filters based on logging levels.

54

55

```java { .api }

56

/**

57

* Filter that accepts or denies events based on exact level match

58

*/

59

public class LevelFilter extends Filter<ILoggingEvent> {

60

Level level;

61

FilterReply onMatch = FilterReply.NEUTRAL;

62

FilterReply onMismatch = FilterReply.NEUTRAL;

63

64

/**

65

* Set the level to match against

66

*/

67

public void setLevel(Level level);

68

public Level getLevel();

69

70

/**

71

* Set action when level matches

72

*/

73

public void setOnMatch(FilterReply reply);

74

public FilterReply getOnMatch();

75

76

/**

77

* Set action when level doesn't match

78

*/

79

public void setOnMismatch(FilterReply reply);

80

public FilterReply getOnMismatch();

81

82

@Override

83

public FilterReply decide(ILoggingEvent event);

84

}

85

86

/**

87

* Filter that denies events below a threshold level

88

*/

89

public class ThresholdFilter extends Filter<ILoggingEvent> {

90

Level level;

91

92

/**

93

* Set the minimum level threshold

94

*/

95

public void setLevel(Level level);

96

public Level getLevel();

97

98

@Override

99

public FilterReply decide(ILoggingEvent event);

100

}

101

```

102

103

**Usage Examples:**

104

105

```java

106

import ch.qos.logback.classic.filter.LevelFilter;

107

import ch.qos.logback.classic.filter.ThresholdFilter;

108

109

// Level filter - only accept INFO events

110

LevelFilter levelFilter = new LevelFilter();

111

levelFilter.setContext(loggerContext);

112

levelFilter.setLevel(Level.INFO);

113

levelFilter.setOnMatch(FilterReply.ACCEPT);

114

levelFilter.setOnMismatch(FilterReply.DENY);

115

levelFilter.start();

116

117

// Threshold filter - accept WARN and above

118

ThresholdFilter thresholdFilter = new ThresholdFilter();

119

thresholdFilter.setContext(loggerContext);

120

thresholdFilter.setLevel(Level.WARN);

121

thresholdFilter.start();

122

123

// Add to appender

124

appender.addFilter(levelFilter);

125

```

126

127

### Turbo Filters

128

129

High-performance filters that operate before LoggingEvent creation.

130

131

```java { .api }

132

/**

133

* High-performance filter base class that operates before event creation

134

*/

135

public abstract class TurboFilter extends ContextAwareBase implements LifeCycle {

136

private String name;

137

138

/**

139

* Decide on logging event before LoggingEvent is created

140

* @param marker the marker (can be null)

141

* @param logger the logger

142

* @param level the level

143

* @param format the message format

144

* @param params message parameters

145

* @param t throwable (can be null)

146

*/

147

public abstract FilterReply decide(Marker marker, Logger logger, Level level,

148

String format, Object[] params, Throwable t);

149

150

public String getName();

151

public void setName(String name);

152

153

public void start();

154

public void stop();

155

public boolean isStarted();

156

}

157

158

/**

159

* Container for turbo filters with evaluation logic

160

*/

161

public final class TurboFilterList extends ArrayList<TurboFilter> {

162

/**

163

* Evaluate all turbo filters for an event

164

*/

165

public FilterReply getTurboFilterChainDecision(Marker marker, Logger logger, Level level,

166

String format, Object[] params, Throwable t);

167

}

168

```

169

170

### Specialized Turbo Filters

171

172

Commonly used turbo filter implementations.

173

174

```java { .api }

175

/**

176

* Filter duplicate messages to reduce log noise

177

*/

178

public class DuplicateMessageFilter extends TurboFilter {

179

public static final int DEFAULT_CACHE_SIZE = 100;

180

public static final int DEFAULT_ALLOWED_REPETITIONS = 5;

181

182

private int allowedRepetitions = DEFAULT_ALLOWED_REPETITIONS;

183

private int cacheSize = DEFAULT_CACHE_SIZE;

184

private LRUMessageCache msgCache;

185

186

/**

187

* Set number of allowed repetitions before filtering

188

*/

189

public int getAllowedRepetitions();

190

public void setAllowedRepetitions(int allowedRepetitions);

191

192

/**

193

* Set cache size for tracking messages

194

*/

195

public int getCacheSize();

196

public void setCacheSize(int cacheSize);

197

198

@Override

199

public FilterReply decide(Marker marker, Logger logger, Level level,

200

String format, Object[] params, Throwable t);

201

}

202

203

/**

204

* Filter based on MDC values

205

*/

206

public class MDCFilter extends TurboFilter {

207

String MDCKey;

208

String value;

209

FilterReply onMatch = FilterReply.NEUTRAL;

210

FilterReply onMismatch = FilterReply.NEUTRAL;

211

212

/**

213

* Set the MDC key to check

214

*/

215

public void setMDCKey(String MDCKey);

216

public String getMDCKey();

217

218

/**

219

* Set the value to match against

220

*/

221

public void setValue(String value);

222

public String getValue();

223

224

/**

225

* Set actions for match/mismatch

226

*/

227

public void setOnMatch(FilterReply reply);

228

public FilterReply getOnMatch();

229

public void setOnMismatch(FilterReply reply);

230

public FilterReply getOnMismatch();

231

232

@Override

233

public FilterReply decide(Marker marker, Logger logger, Level level,

234

String format, Object[] params, Throwable t);

235

}

236

237

/**

238

* Filter based on SLF4J markers

239

*/

240

public class MarkerFilter extends TurboFilter {

241

Marker markerToMatch;

242

FilterReply onMatch = FilterReply.NEUTRAL;

243

FilterReply onMismatch = FilterReply.NEUTRAL;

244

245

/**

246

* Set the marker to match against

247

*/

248

public void setMarker(String markerStr);

249

public String getMarker();

250

251

/**

252

* Set actions for match/mismatch

253

*/

254

public void setOnMatch(FilterReply reply);

255

public FilterReply getOnMatch();

256

public void setOnMismatch(FilterReply reply);

257

public FilterReply getOnMismatch();

258

259

@Override

260

public FilterReply decide(Marker marker, Logger logger, Level level,

261

String format, Object[] params, Throwable t);

262

}

263

264

/**

265

* Dynamic threshold filter based on MDC values

266

*/

267

public class DynamicThresholdFilter extends TurboFilter {

268

private Map<String, Level> valueLevelMap = new HashMap<String, Level>();

269

private Level defaultThreshold;

270

private String key;

271

FilterReply onHigherOrEqual = FilterReply.NEUTRAL;

272

FilterReply onLower = FilterReply.DENY;

273

274

/**

275

* Set the MDC key to use for threshold lookup

276

*/

277

public String getKey();

278

public void setKey(String key);

279

280

/**

281

* Set the default threshold when key not found in MDC

282

*/

283

public void setDefaultThreshold(Level defaultThreshold);

284

public Level getDefaultThreshold();

285

286

/**

287

* Add MDC value to level mapping

288

*/

289

public void addMDCValueLevelPair(MDCValueLevelPair mdcValueLevelPair);

290

291

/**

292

* Set actions for threshold comparison

293

*/

294

public void setOnHigherOrEqual(FilterReply reply);

295

public FilterReply getOnHigherOrEqual();

296

public void setOnLower(FilterReply reply);

297

public FilterReply getOnLower();

298

299

@Override

300

public FilterReply decide(Marker marker, Logger logger, Level level,

301

String format, Object[] params, Throwable t);

302

}

303

304

/**

305

* Reconfigure logback when configuration file changes

306

*/

307

public class ReconfigureOnChangeFilter extends TurboFilter implements ReconfigureOnChangeTask {

308

public static final long DEFAULT_REFRESH_PERIOD = 60 * 1000; // 1 minute

309

310

long refreshPeriod = DEFAULT_REFRESH_PERIOD;

311

URL mainConfigurationURL;

312

protected volatile long nextCheck;

313

ConfigurationWatchList configurationWatchList;

314

315

/**

316

* Set refresh period in milliseconds

317

*/

318

public void setRefreshPeriod(long refreshPeriod);

319

public long getRefreshPeriod();

320

321

@Override

322

public FilterReply decide(Marker marker, Logger logger, Level level,

323

String format, Object[] params, Throwable t);

324

}

325

```

326

327

### Boolean Expression Evaluators

328

329

Advanced filtering using boolean expressions.

330

331

```java { .api }

332

/**

333

* Base interface for event evaluators

334

*/

335

public interface EventEvaluator<E> extends ContextAware, LifeCycle {

336

/**

337

* Evaluate whether an event matches criteria

338

*/

339

boolean evaluate(E event) throws EvaluationException;

340

341

String getName();

342

void setName(String name);

343

}

344

345

/**

346

* Evaluator based on SLF4J markers

347

*/

348

public class OnMarkerEvaluator extends EventEvaluatorBase<ILoggingEvent> {

349

String markerStr;

350

Marker marker;

351

352

/**

353

* Set the marker to evaluate against

354

*/

355

public String getMarker();

356

public void setMarker(String markerStr);

357

358

@Override

359

public boolean evaluate(ILoggingEvent event) throws EvaluationException;

360

}

361

362

/**

363

* Evaluator that matches ERROR level events

364

*/

365

public class OnErrorEvaluator extends EventEvaluatorBase<ILoggingEvent> {

366

@Override

367

public boolean evaluate(ILoggingEvent event);

368

}

369

370

/**

371

* Evaluator based on exception matching

372

*/

373

public class ExceptionMatchEvaluator extends EventEvaluatorBase<ILoggingEvent> {

374

String exceptionClassName;

375

376

/**

377

* Set the exception class name to match

378

*/

379

public String getExceptionClassName();

380

public void setExceptionClassName(String exceptionClassName);

381

382

@Override

383

public boolean evaluate(ILoggingEvent event);

384

}

385

```

386

387

## Usage Examples

388

389

### Complex Filter Chain

390

391

```java

392

import ch.qos.logback.classic.turbo.*;

393

import ch.qos.logback.classic.filter.*;

394

395

LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();

396

397

// Add turbo filters to context (evaluated first)

398

DuplicateMessageFilter dupFilter = new DuplicateMessageFilter();

399

dupFilter.setContext(context);

400

dupFilter.setAllowedRepetitions(3);

401

dupFilter.setCacheSize(200);

402

dupFilter.start();

403

context.addTurboFilter(dupFilter);

404

405

// MDC-based filtering

406

MDCFilter mdcFilter = new MDCFilter();

407

mdcFilter.setContext(context);

408

mdcFilter.setMDCKey("env");

409

mdcFilter.setValue("production");

410

mdcFilter.setOnMatch(FilterReply.ACCEPT);

411

mdcFilter.setOnMismatch(FilterReply.DENY);

412

mdcFilter.start();

413

context.addTurboFilter(mdcFilter);

414

415

// Add regular filter to appender

416

ThresholdFilter appenderFilter = new ThresholdFilter();

417

appenderFilter.setContext(context);

418

appenderFilter.setLevel(Level.WARN);

419

appenderFilter.start();

420

appender.addFilter(appenderFilter);

421

```

422

423

### Dynamic Threshold Based on User

424

425

```java

426

// Different log levels for different users

427

DynamicThresholdFilter dynFilter = new DynamicThresholdFilter();

428

dynFilter.setContext(context);

429

dynFilter.setKey("userId");

430

dynFilter.setDefaultThreshold(Level.WARN);

431

432

// Admin users get DEBUG level

433

MDCValueLevelPair adminPair = new MDCValueLevelPair();

434

adminPair.setValue("admin");

435

adminPair.setLevel(Level.DEBUG);

436

dynFilter.addMDCValueLevelPair(adminPair);

437

438

// Developer users get INFO level

439

MDCValueLevelPair devPair = new MDCValueLevelPair();

440

devPair.setValue("developer");

441

devPair.setLevel(Level.INFO);

442

dynFilter.addMDCValueLevelPair(devPair);

443

444

dynFilter.start();

445

context.addTurboFilter(dynFilter);

446

447

// In application code:

448

MDC.put("userId", "admin");

449

logger.debug("This will be logged for admin users");

450

MDC.put("userId", "regular");

451

logger.debug("This will NOT be logged for regular users");

452

```

453

454

### Marker-Based Filtering

455

456

```java

457

import org.slf4j.Marker;

458

import org.slf4j.MarkerFactory;

459

460

// Create markers

461

Marker PERFORMANCE = MarkerFactory.getMarker("PERFORMANCE");

462

Marker SECURITY = MarkerFactory.getMarker("SECURITY");

463

464

// Filter for performance logs only

465

MarkerFilter perfFilter = new MarkerFilter();

466

perfFilter.setContext(context);

467

perfFilter.setMarker("PERFORMANCE");

468

perfFilter.setOnMatch(FilterReply.ACCEPT);

469

perfFilter.setOnMismatch(FilterReply.DENY);

470

perfFilter.start();

471

472

// Add to specific appender

473

performanceAppender.addFilter(perfFilter);

474

475

// Usage in code

476

logger.info(PERFORMANCE, "Operation completed in {}ms", duration);

477

logger.warn(SECURITY, "Failed login attempt from {}", ipAddress);

478

```

479

480

### Configuration File Auto-Reload

481

482

```java

483

// Enable automatic reconfiguration on file changes

484

ReconfigureOnChangeFilter reconfFilter = new ReconfigureOnChangeFilter();

485

reconfFilter.setContext(context);

486

reconfFilter.setRefreshPeriod(30000); // Check every 30 seconds

487

reconfFilter.start();

488

context.addTurboFilter(reconfFilter);

489

490

// Logback will automatically reload when logback.xml changes

491

```