CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apache-logging-log4j--log4j-api

The logging API of the Log4j project providing a comprehensive and flexible logging framework for Java applications.

Pending
Overview
Eval results
Files

markers.mddocs/

Markers & Filtering

Marker system for adding hierarchical, filterable metadata to log events. Enables sophisticated filtering and routing based on marker taxonomy.

Capabilities

Marker Interface

Hierarchical markers for adding filterable metadata to log events.

/**
 * Marker interface for adding filterable information to log messages
 */
public interface Marker extends Serializable {
    /** Get the marker name */
    String getName();
    
    /** Add parent markers to this marker */
    Marker addParents(Marker... markers);
    
    /** Set parent markers, replacing any existing parents */
    Marker setParents(Marker... markers);
    
    /** Remove a parent marker */
    boolean remove(Marker marker);
    
    /** Get array of parent markers */
    Marker[] getParents();
    
    /** Check if this marker has any parents */
    boolean hasParents();
    
    /** Check if this marker is an instance of the given marker (including hierarchy) */
    boolean isInstanceOf(Marker marker);
    
    /** Check if this marker is an instance of the named marker (including hierarchy) */
    boolean isInstanceOf(String name);
    
    /** Iterator over parents */
    Iterator<Marker> iterator();
    
    /** Check if marker contains the given marker in its hierarchy */
    boolean contains(Marker other);
    
    /** Check if marker contains the named marker in its hierarchy */
    boolean contains(String name);
}

Usage Examples:

private static final Logger logger = LogManager.getLogger();

public void demonstrateBasicMarkers() {
    // Create markers
    Marker networkMarker = MarkerManager.getMarker("NETWORK");
    Marker securityMarker = MarkerManager.getMarker("SECURITY");
    Marker databaseMarker = MarkerManager.getMarker("DATABASE");
    
    // Use markers in logging
    logger.info(networkMarker, "Network connection established");
    logger.warn(securityMarker, "Invalid login attempt detected");
    logger.error(databaseMarker, "Database connection failed");
    
    // Markers can be used with all logging methods
    logger.debug(networkMarker, "Network packet received: {}", packetData);
    logger.error(securityMarker, "Security violation", exception);
}

// Hierarchical marker example
public void demonstrateMarkerHierarchy() {
    // Create parent markers
    Marker auditMarker = MarkerManager.getMarker("AUDIT");
    Marker securityMarker = MarkerManager.getMarker("SECURITY");
    
    // Create child markers
    Marker loginMarker = MarkerManager.getMarker("LOGIN");
    Marker accessMarker = MarkerManager.getMarker("ACCESS");
    
    // Establish hierarchy - LOGIN and ACCESS are both types of SECURITY
    loginMarker.addParents(securityMarker);
    accessMarker.addParents(securityMarker);
    
    // SECURITY is a type of AUDIT
    securityMarker.addParents(auditMarker);
    
    // Now LOGIN is also considered an instance of AUDIT through the hierarchy
    logger.info(loginMarker, "User logged in"); // This log event has LOGIN, SECURITY, and AUDIT markers
    
    // Check hierarchy
    if (loginMarker.isInstanceOf(auditMarker)) {
        System.out.println("Login events are audit events"); // This will print
    }
    
    if (loginMarker.isInstanceOf("SECURITY")) {
        System.out.println("Login events are security events"); // This will print
    }
}

MarkerManager Factory

Factory for creating and managing Marker instances with singleton behavior.

/**
 * Factory for creating and managing Marker instances
 */
public final class MarkerManager {
    /** Get or create a marker with the given name */
    public static Marker getMarker(String name);
    
    /** Check if a marker with the given name exists */
    public static boolean exists(String key);
    
    /** Clear all markers (use with caution) */
    public static void clear();
    
    /**
     * Actual Marker implementation
     */
    public static class Log4jMarker implements Marker {
        // Implementation of Marker interface
    }
}

Usage Examples:

public class MarkerConstants {
    // Define application markers as constants
    public static final Marker SECURITY = MarkerManager.getMarker("SECURITY");
    public static final Marker PERFORMANCE = MarkerManager.getMarker("PERFORMANCE");
    public static final Marker BUSINESS = MarkerManager.getMarker("BUSINESS");
    public static final Marker TECHNICAL = MarkerManager.getMarker("TECHNICAL");
    
    // Hierarchical markers
    public static final Marker LOGIN = MarkerManager.getMarker("LOGIN");
    public static final Marker LOGOUT = MarkerManager.getMarker("LOGOUT");
    public static final Marker ACCESS_DENIED = MarkerManager.getMarker("ACCESS_DENIED");
    
    static {
        // Set up marker hierarchy
        LOGIN.addParents(SECURITY);
        LOGOUT.addParents(SECURITY);
        ACCESS_DENIED.addParents(SECURITY);
        
        SECURITY.addParents(BUSINESS);
        PERFORMANCE.addParents(TECHNICAL);
    }
}

public class ApplicationService {
    private static final Logger logger = LogManager.getLogger();
    
    public void login(String username, String password) {
        logger.info(MarkerConstants.LOGIN, "Login attempt for user: {}", username);
        
        if (authenticate(username, password)) {
            logger.info(MarkerConstants.LOGIN, "Login successful for user: {}", username);
        } else {
            logger.warn(MarkerConstants.ACCESS_DENIED, "Login failed for user: {}", username);
        }
    }
    
    public void checkMarkerExistence() {
        if (MarkerManager.exists("SECURITY")) {
            logger.debug("Security marker is available");
        }
        
        // Get the same marker instance (singleton behavior)
        Marker sec1 = MarkerManager.getMarker("SECURITY");
        Marker sec2 = MarkerManager.getMarker("SECURITY");
        assert sec1 == sec2; // Same instance
    }
}

Marker-Aware Logging

All logging methods support markers for enhanced filtering and routing.

public interface Logger {
    // All logging methods have marker overloads
    void trace(Marker marker, String message);
    void debug(Marker marker, String message);
    void info(Marker marker, String message);
    void warn(Marker marker, String message);
    void error(Marker marker, String message);
    void fatal(Marker marker, String message);
    
    // Parameterized logging with markers
    void trace(Marker marker, String message, Object... params);
    void debug(Marker marker, String message, Object... params);
    void info(Marker marker, String message, Object... params);
    void warn(Marker marker, String message, Object... params);
    void error(Marker marker, String message, Object... params);
    void fatal(Marker marker, String message, Object... params);
    
    // Exception logging with markers
    void trace(Marker marker, String message, Throwable throwable);
    void debug(Marker marker, String message, Throwable throwable);
    void info(Marker marker, String message, Throwable throwable);
    void warn(Marker marker, String message, Throwable throwable);
    void error(Marker marker, String message, Throwable throwable);
    void fatal(Marker marker, String message, Throwable throwable);
    
    // Generic logging with markers
    void log(Level level, Marker marker, String message);
    void log(Level level, Marker marker, String message, Object... params);
    void log(Level level, Marker marker, String message, Throwable throwable);
    
    // Level checking with markers
    boolean isTraceEnabled(Marker marker);
    boolean isDebugEnabled(Marker marker);
    boolean isInfoEnabled(Marker marker);
    boolean isWarnEnabled(Marker marker);
    boolean isErrorEnabled(Marker marker);
    boolean isFatalEnabled(Marker marker);
    boolean isEnabled(Level level, Marker marker);
}

Usage Examples:

private static final Logger logger = LogManager.getLogger();
private static final Marker PERFORMANCE = MarkerManager.getMarker("PERFORMANCE");
private static final Marker SECURITY = MarkerManager.getMarker("SECURITY");
private static final Marker AUDIT = MarkerManager.getMarker("AUDIT");

public class MarkerLoggingExamples {
    
    public void demonstrateMarkerLogging() {
        // Basic marker logging
        logger.info(PERFORMANCE, "Operation completed in {}ms", executionTime);
        logger.warn(SECURITY, "Suspicious activity detected from IP: {}", clientIP);
        logger.error(AUDIT, "Configuration change failed", exception);
        
        // Conditional logging with markers
        if (logger.isDebugEnabled(PERFORMANCE)) {
            logger.debug(PERFORMANCE, "Performance metrics: {}", 
                        gatherDetailedMetrics());
        }
        
        // Multiple markers through hierarchy
        Marker sqlMarker = MarkerManager.getMarker("SQL");
        sqlMarker.addParents(PERFORMANCE); // SQL operations are performance-related
        
        logger.debug(sqlMarker, "Executing query: {}", sql);
        // This log event will match filters for both SQL and PERFORMANCE markers
    }
    
    // Web request processing with markers
    public void processWebRequest(HttpServletRequest request) {
        Marker requestMarker = MarkerManager.getMarker("REQUEST");
        
        logger.info(requestMarker, "Processing {} request to {}", 
                   request.getMethod(), request.getRequestURI());
        
        try {
            String result = handleRequest(request);
            logger.info(requestMarker, "Request processed successfully");
        } catch (SecurityException e) {
            logger.error(SECURITY, "Security violation in request processing", e);
        } catch (Exception e) {
            logger.error(requestMarker, "Request processing failed", e);
        }
    }
    
    // Business logic with contextual markers
    public void processPayment(PaymentRequest payment) {
        Marker paymentMarker = MarkerManager.getMarker("PAYMENT");
        paymentMarker.addParents(AUDIT); // Payment operations are auditable
        
        logger.info(paymentMarker, "Processing payment of ${} for user {}", 
                   payment.getAmount(), payment.getUserId());
        
        if (payment.getAmount().compareTo(BigDecimal.valueOf(10000)) > 0) {
            Marker highValueMarker = MarkerManager.getMarker("HIGH_VALUE");
            highValueMarker.addParents(paymentMarker, SECURITY);
            
            logger.warn(highValueMarker, "High-value payment transaction: ${}", 
                       payment.getAmount());
        }
        
        try {
            PaymentResult result = paymentProcessor.process(payment);
            logger.info(paymentMarker, "Payment processed successfully: {}", 
                       result.getTransactionId());
        } catch (PaymentException e) {
            logger.error(paymentMarker, "Payment processing failed", e);
        }
    }
}

LogBuilder with Markers

Fluent API supports markers for complex log event construction.

public interface LogBuilder {
    /** Add a marker to the log event */
    LogBuilder withMarker(Marker marker);
    
    // All other LogBuilder methods remain the same
    LogBuilder withThrowable(Throwable throwable);
    LogBuilder withLocation();
    void log(String message);
    void log(String message, Object... params);
}

Usage Examples:

private static final Logger logger = LogManager.getLogger();
private static final Marker SECURITY = MarkerManager.getMarker("SECURITY");
private static final Marker AUDIT = MarkerManager.getMarker("AUDIT");

public void demonstrateLogBuilderWithMarkers() {
    // Simple marker with LogBuilder
    logger.atError()
          .withMarker(SECURITY)
          .log("Security violation detected");
    
    // Complex log event with marker, exception, and location
    logger.atWarn()
          .withMarker(AUDIT)
          .withThrowable(exception)
          .withLocation()
          .log("Audit event failed for user {}", userId);
    
    // Conditional marker application
    LogBuilder builder = logger.atInfo();
    
    if (isSecurityRelated) {
        builder = builder.withMarker(SECURITY);
    }
    
    if (exception != null) {
        builder = builder.withThrowable(exception);
    }
    
    builder.log("Dynamic marker application: {}", eventData);
    
    // Multiple markers through hierarchy
    Marker specificMarker = MarkerManager.getMarker("SQL_INJECTION");
    specificMarker.addParents(SECURITY);
    
    logger.atError()
          .withMarker(specificMarker) // Includes both SQL_INJECTION and SECURITY
          .withLocation()
          .log("SQL injection attempt detected from {}", clientIP);
}

Marker Filtering Patterns

Common patterns for using markers in filtering and routing configurations.

// Example marker hierarchy for a web application
public class WebAppMarkers {
    // Top-level categories
    public static final Marker APPLICATION = MarkerManager.getMarker("APPLICATION");
    public static final Marker INFRASTRUCTURE = MarkerManager.getMarker("INFRASTRUCTURE");
    
    // Application subcategories
    public static final Marker BUSINESS_LOGIC = MarkerManager.getMarker("BUSINESS_LOGIC");
    public static final Marker SECURITY = MarkerManager.getMarker("SECURITY");
    public static final Marker PERFORMANCE = MarkerManager.getMarker("PERFORMANCE");
    
    // Infrastructure subcategories
    public static final Marker DATABASE = MarkerManager.getMarker("DATABASE");
    public static final Marker NETWORK = MarkerManager.getMarker("NETWORK");
    public static final Marker CACHE = MarkerManager.getMarker("CACHE");
    
    // Specific security markers
    public static final Marker AUTHENTICATION = MarkerManager.getMarker("AUTHENTICATION");
    public static final Marker AUTHORIZATION = MarkerManager.getMarker("AUTHORIZATION");
    public static final Marker AUDIT = MarkerManager.getMarker("AUDIT");
    
    static {
        // Set up hierarchy
        BUSINESS_LOGIC.addParents(APPLICATION);
        SECURITY.addParents(APPLICATION);
        PERFORMANCE.addParents(APPLICATION);
        
        DATABASE.addParents(INFRASTRUCTURE);
        NETWORK.addParents(INFRASTRUCTURE);
        CACHE.addParents(INFRASTRUCTURE);
        
        AUTHENTICATION.addParents(SECURITY);
        AUTHORIZATION.addParents(SECURITY);
        AUDIT.addParents(SECURITY);
    }
}

Usage Examples:

public class MarkerUsagePatterns {
    private static final Logger logger = LogManager.getLogger();
    
    // Service layer with business logic markers
    @Service
    public class OrderService {
        
        public Order createOrder(OrderRequest request) {
            logger.info(WebAppMarkers.BUSINESS_LOGIC, 
                       "Creating order for customer {}", request.getCustomerId());
            
            try {
                validateOrderRequest(request);
                Order order = processOrder(request);
                
                logger.info(WebAppMarkers.AUDIT, 
                           "Order {} created successfully", order.getId());
                
                return order;
                
            } catch (ValidationException e) {
                logger.warn(WebAppMarkers.BUSINESS_LOGIC, 
                           "Order validation failed", e);
                throw e;
            } catch (Exception e) {
                logger.error(WebAppMarkers.BUSINESS_LOGIC, 
                            "Order creation failed", e);
                throw e;
            }
        }
        
        private void validateOrderRequest(OrderRequest request) {
            logger.debug(WebAppMarkers.BUSINESS_LOGIC, 
                        "Validating order request");
            
            // Validation with specific markers
            if (!authService.hasPermission(request.getCustomerId())) {
                logger.warn(WebAppMarkers.AUTHORIZATION, 
                           "Customer {} lacks permission to create orders", 
                           request.getCustomerId());
                throw new AuthorizationException("Insufficient permissions");
            }
        }
    }
    
    // Data access layer with infrastructure markers
    @Repository
    public class OrderRepository {
        
        public Order save(Order order) {
            logger.debug(WebAppMarkers.DATABASE, "Saving order to database");
            
            long startTime = System.currentTimeMillis();
            try {
                Order savedOrder = jdbcTemplate.save(order);
                
                long duration = System.currentTimeMillis() - startTime;
                if (duration > 1000) {
                    logger.warn(WebAppMarkers.PERFORMANCE, 
                               "Slow database operation: {}ms", duration);
                }
                
                return savedOrder;
                
            } catch (DataAccessException e) {
                logger.error(WebAppMarkers.DATABASE, 
                            "Database error saving order", e);
                throw e;
            }
        }
    }
    
    // Security interceptor with authentication markers
    @Component
    public class SecurityInterceptor {
        
        public boolean authenticate(String token) {
            logger.debug(WebAppMarkers.AUTHENTICATION, 
                        "Authenticating token");
            
            if (isValidToken(token)) {
                logger.info(WebAppMarkers.AUTHENTICATION, 
                           "Token authentication successful");
                return true;
            } else {
                logger.warn(WebAppMarkers.SECURITY, 
                           "Invalid token authentication attempt");
                return false;
            }
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-apache-logging-log4j--log4j-api

docs

core-logging.md

index.md

markers.md

message-system.md

performance-features.md

spi.md

status-system.md

thread-context.md

tile.json