CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-ch-qos-logback--logback-classic

Comprehensive SLF4J implementation providing enterprise-grade logging with flexible configuration, high performance, and extensive appender ecosystem for Java applications.

Pending
Overview
Eval results
Files

filters.mddocs/

Filters

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.

Capabilities

Core Filter Interface

Base interface and functionality for all filters.

/**
 * Core filter interface for controlling log event processing
 */
public abstract class Filter<E> extends ContextAwareBase implements LifeCycle {
    private String name;
    
    /**
     * Decide whether to accept, deny, or remain neutral about an event
     */
    public abstract FilterReply decide(E event);
    
    public String getName();
    public void setName(String name);
    
    // LifeCycle methods
    public void start();
    public void stop();
    public boolean isStarted();
}

/**
 * Filter decision enumeration
 */
public enum FilterReply {
    DENY,    // Reject the event immediately
    NEUTRAL, // Let other filters decide
    ACCEPT   // Accept the event immediately
}

/**
 * Interface for components that can have filters attached
 */
public interface FilterAttachable<E> {
    void addFilter(Filter<E> newFilter);
    void clearAllFilters();
    List<Filter<E>> getCopyOfAttachedFiltersList();
    FilterReply getFilterChainDecision(E event);
}

Level Filters

Filters based on logging levels.

/**
 * Filter that accepts or denies events based on exact level match
 */
public class LevelFilter extends Filter<ILoggingEvent> {
    Level level;
    FilterReply onMatch = FilterReply.NEUTRAL;
    FilterReply onMismatch = FilterReply.NEUTRAL;
    
    /**
     * Set the level to match against
     */
    public void setLevel(Level level);
    public Level getLevel();
    
    /**
     * Set action when level matches
     */
    public void setOnMatch(FilterReply reply);
    public FilterReply getOnMatch();
    
    /**
     * Set action when level doesn't match
     */
    public void setOnMismatch(FilterReply reply);
    public FilterReply getOnMismatch();
    
    @Override
    public FilterReply decide(ILoggingEvent event);
}

/**
 * Filter that denies events below a threshold level
 */
public class ThresholdFilter extends Filter<ILoggingEvent> {
    Level level;
    
    /**
     * Set the minimum level threshold
     */
    public void setLevel(Level level);
    public Level getLevel();
    
    @Override
    public FilterReply decide(ILoggingEvent event);
}

Usage Examples:

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

// Level filter - only accept INFO events
LevelFilter levelFilter = new LevelFilter();
levelFilter.setContext(loggerContext);
levelFilter.setLevel(Level.INFO);
levelFilter.setOnMatch(FilterReply.ACCEPT);
levelFilter.setOnMismatch(FilterReply.DENY);
levelFilter.start();

// Threshold filter - accept WARN and above
ThresholdFilter thresholdFilter = new ThresholdFilter();
thresholdFilter.setContext(loggerContext);
thresholdFilter.setLevel(Level.WARN);
thresholdFilter.start();

// Add to appender
appender.addFilter(levelFilter);

Turbo Filters

High-performance filters that operate before LoggingEvent creation.

/**
 * High-performance filter base class that operates before event creation
 */
public abstract class TurboFilter extends ContextAwareBase implements LifeCycle {
    private String name;
    
    /**
     * Decide on logging event before LoggingEvent is created
     * @param marker the marker (can be null)
     * @param logger the logger
     * @param level the level
     * @param format the message format
     * @param params message parameters
     * @param t throwable (can be null)
     */
    public abstract FilterReply decide(Marker marker, Logger logger, Level level, 
                                     String format, Object[] params, Throwable t);
    
    public String getName();
    public void setName(String name);
    
    public void start();
    public void stop();
    public boolean isStarted();
}

/**
 * Container for turbo filters with evaluation logic
 */
public final class TurboFilterList extends ArrayList<TurboFilter> {
    /**
     * Evaluate all turbo filters for an event
     */
    public FilterReply getTurboFilterChainDecision(Marker marker, Logger logger, Level level,
                                                 String format, Object[] params, Throwable t);
}

Specialized Turbo Filters

Commonly used turbo filter implementations.

/**
 * Filter duplicate messages to reduce log noise
 */
public class DuplicateMessageFilter extends TurboFilter {
    public static final int DEFAULT_CACHE_SIZE = 100;
    public static final int DEFAULT_ALLOWED_REPETITIONS = 5;
    
    private int allowedRepetitions = DEFAULT_ALLOWED_REPETITIONS;
    private int cacheSize = DEFAULT_CACHE_SIZE;
    private LRUMessageCache msgCache;
    
    /**
     * Set number of allowed repetitions before filtering
     */
    public int getAllowedRepetitions();
    public void setAllowedRepetitions(int allowedRepetitions);
    
    /**
     * Set cache size for tracking messages
     */
    public int getCacheSize();
    public void setCacheSize(int cacheSize);
    
    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level, 
                            String format, Object[] params, Throwable t);
}

/**
 * Filter based on MDC values
 */
public class MDCFilter extends TurboFilter {
    String MDCKey;
    String value;
    FilterReply onMatch = FilterReply.NEUTRAL;
    FilterReply onMismatch = FilterReply.NEUTRAL;
    
    /**
     * Set the MDC key to check
     */
    public void setMDCKey(String MDCKey);
    public String getMDCKey();
    
    /**
     * Set the value to match against
     */
    public void setValue(String value);
    public String getValue();
    
    /**
     * Set actions for match/mismatch
     */
    public void setOnMatch(FilterReply reply);
    public FilterReply getOnMatch();
    public void setOnMismatch(FilterReply reply);
    public FilterReply getOnMismatch();
    
    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level,
                            String format, Object[] params, Throwable t);
}

/**
 * Filter based on SLF4J markers
 */
public class MarkerFilter extends TurboFilter {
    Marker markerToMatch;
    FilterReply onMatch = FilterReply.NEUTRAL;
    FilterReply onMismatch = FilterReply.NEUTRAL;
    
    /**
     * Set the marker to match against
     */
    public void setMarker(String markerStr);
    public String getMarker();
    
    /**
     * Set actions for match/mismatch  
     */
    public void setOnMatch(FilterReply reply);
    public FilterReply getOnMatch();
    public void setOnMismatch(FilterReply reply);
    public FilterReply getOnMismatch();
    
    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level,
                            String format, Object[] params, Throwable t);
}

/**
 * Dynamic threshold filter based on MDC values
 */
public class DynamicThresholdFilter extends TurboFilter {
    private Map<String, Level> valueLevelMap = new HashMap<String, Level>();
    private Level defaultThreshold;
    private String key;
    FilterReply onHigherOrEqual = FilterReply.NEUTRAL;
    FilterReply onLower = FilterReply.DENY;
    
    /**
     * Set the MDC key to use for threshold lookup
     */
    public String getKey();
    public void setKey(String key);
    
    /**
     * Set the default threshold when key not found in MDC
     */
    public void setDefaultThreshold(Level defaultThreshold);
    public Level getDefaultThreshold();
    
    /**
     * Add MDC value to level mapping
     */
    public void addMDCValueLevelPair(MDCValueLevelPair mdcValueLevelPair);
    
    /**
     * Set actions for threshold comparison
     */
    public void setOnHigherOrEqual(FilterReply reply);
    public FilterReply getOnHigherOrEqual();
    public void setOnLower(FilterReply reply);
    public FilterReply getOnLower();
    
    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level,
                            String format, Object[] params, Throwable t);
}

/**
 * Reconfigure logback when configuration file changes
 */
public class ReconfigureOnChangeFilter extends TurboFilter implements ReconfigureOnChangeTask {
    public static final long DEFAULT_REFRESH_PERIOD = 60 * 1000; // 1 minute
    
    long refreshPeriod = DEFAULT_REFRESH_PERIOD;
    URL mainConfigurationURL;
    protected volatile long nextCheck;
    ConfigurationWatchList configurationWatchList;
    
    /**
     * Set refresh period in milliseconds
     */
    public void setRefreshPeriod(long refreshPeriod);
    public long getRefreshPeriod();
    
    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level,
                            String format, Object[] params, Throwable t);
}

Boolean Expression Evaluators

Advanced filtering using boolean expressions.

/**
 * Base interface for event evaluators
 */
public interface EventEvaluator<E> extends ContextAware, LifeCycle {
    /**
     * Evaluate whether an event matches criteria
     */
    boolean evaluate(E event) throws EvaluationException;
    
    String getName();
    void setName(String name);
}

/**
 * Evaluator based on SLF4J markers
 */
public class OnMarkerEvaluator extends EventEvaluatorBase<ILoggingEvent> {
    String markerStr;
    Marker marker;
    
    /**
     * Set the marker to evaluate against
     */
    public String getMarker();
    public void setMarker(String markerStr);
    
    @Override
    public boolean evaluate(ILoggingEvent event) throws EvaluationException;
}

/**
 * Evaluator that matches ERROR level events
 */
public class OnErrorEvaluator extends EventEvaluatorBase<ILoggingEvent> {
    @Override
    public boolean evaluate(ILoggingEvent event);
}

/**
 * Evaluator based on exception matching
 */
public class ExceptionMatchEvaluator extends EventEvaluatorBase<ILoggingEvent> {
    String exceptionClassName;
    
    /**
     * Set the exception class name to match
     */
    public String getExceptionClassName();
    public void setExceptionClassName(String exceptionClassName);
    
    @Override
    public boolean evaluate(ILoggingEvent event);
}

Usage Examples

Complex Filter Chain

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

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

// Add turbo filters to context (evaluated first)
DuplicateMessageFilter dupFilter = new DuplicateMessageFilter();
dupFilter.setContext(context);
dupFilter.setAllowedRepetitions(3);
dupFilter.setCacheSize(200);
dupFilter.start();
context.addTurboFilter(dupFilter);

// MDC-based filtering
MDCFilter mdcFilter = new MDCFilter();
mdcFilter.setContext(context);
mdcFilter.setMDCKey("env");
mdcFilter.setValue("production");
mdcFilter.setOnMatch(FilterReply.ACCEPT);
mdcFilter.setOnMismatch(FilterReply.DENY);
mdcFilter.start();
context.addTurboFilter(mdcFilter);

// Add regular filter to appender
ThresholdFilter appenderFilter = new ThresholdFilter();
appenderFilter.setContext(context);
appenderFilter.setLevel(Level.WARN);
appenderFilter.start();
appender.addFilter(appenderFilter);

Dynamic Threshold Based on User

// Different log levels for different users
DynamicThresholdFilter dynFilter = new DynamicThresholdFilter();
dynFilter.setContext(context);
dynFilter.setKey("userId");
dynFilter.setDefaultThreshold(Level.WARN);

// Admin users get DEBUG level
MDCValueLevelPair adminPair = new MDCValueLevelPair();
adminPair.setValue("admin");
adminPair.setLevel(Level.DEBUG);
dynFilter.addMDCValueLevelPair(adminPair);

// Developer users get INFO level
MDCValueLevelPair devPair = new MDCValueLevelPair();
devPair.setValue("developer");
devPair.setLevel(Level.INFO);
dynFilter.addMDCValueLevelPair(devPair);

dynFilter.start();
context.addTurboFilter(dynFilter);

// In application code:
MDC.put("userId", "admin");
logger.debug("This will be logged for admin users");
MDC.put("userId", "regular");
logger.debug("This will NOT be logged for regular users");

Marker-Based Filtering

import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

// Create markers
Marker PERFORMANCE = MarkerFactory.getMarker("PERFORMANCE");
Marker SECURITY = MarkerFactory.getMarker("SECURITY");

// Filter for performance logs only
MarkerFilter perfFilter = new MarkerFilter();
perfFilter.setContext(context);
perfFilter.setMarker("PERFORMANCE");
perfFilter.setOnMatch(FilterReply.ACCEPT);
perfFilter.setOnMismatch(FilterReply.DENY);
perfFilter.start();

// Add to specific appender
performanceAppender.addFilter(perfFilter);

// Usage in code
logger.info(PERFORMANCE, "Operation completed in {}ms", duration);
logger.warn(SECURITY, "Failed login attempt from {}", ipAddress);

Configuration File Auto-Reload

// Enable automatic reconfiguration on file changes
ReconfigureOnChangeFilter reconfFilter = new ReconfigureOnChangeFilter();
reconfFilter.setContext(context);
reconfFilter.setRefreshPeriod(30000); // Check every 30 seconds
reconfFilter.start();
context.addTurboFilter(reconfFilter);

// Logback will automatically reload when logback.xml changes

Install with Tessl CLI

npx tessl i tessl/maven-ch-qos-logback--logback-classic

docs

appenders.md

configuration.md

core-logging.md

encoders-layouts.md

filters.md

index.md

network-logging.md

servlet-integration.md

tile.json