CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apache-logging-log4j--log4j-slf4j2-impl

SLF4J 2 provider that bridges SLF4J 2 logging calls to the Apache Log4j API

Pending
Overview
Eval results
Files

marker-management.mddocs/

Marker Management

Comprehensive marker creation, hierarchy management, and lifecycle operations for organizing and categorizing log events. Markers provide metadata for advanced log filtering, routing, and contextual organization.

Capabilities

Marker Factory Operations

Core marker creation and management through the MarkerFactory.

/**
 * Get or create a marker with the specified name
 * @param name The marker name (must not be null)
 * @return Marker instance (cached for reuse)
 * @throws IllegalArgumentException if name is null
 */
Marker getMarker(String name);

/**
 * Check if a marker with the given name exists
 * @param name The marker name to check
 * @return true if marker exists in cache
 */
boolean exists(String name);

/**
 * Attempt to detach a marker (not supported in Log4j)
 * @param name The marker name
 * @return false (Log4j does not support marker detachment)
 */
boolean detachMarker(String name);

/**
 * Get a detached marker (returns attached marker with warning)
 * @param name The marker name
 * @return Marker instance (attached, detachment not supported)
 */
Marker getDetachedMarker(String name);

Usage Examples:

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

// Create/retrieve markers
Marker webMarker = MarkerFactory.getMarker("WEB");
Marker securityMarker = MarkerFactory.getMarker("SECURITY"); 
Marker performanceMarker = MarkerFactory.getMarker("PERFORMANCE");

// Check existence
if (!MarkerFactory.exists("CUSTOM_MARKER")) {
    Marker customMarker = MarkerFactory.getMarker("CUSTOM_MARKER");
}

// Marker instances are cached and reused
Marker web1 = MarkerFactory.getMarker("WEB");
Marker web2 = MarkerFactory.getMarker("WEB");
// web1 == web2 (same instance)

Marker Properties

Access and manage marker properties and metadata.

/**
 * Get the marker name
 * @return The marker name
 */
String getName();

/**
 * Get hash code for the marker
 * @return Hash code based on underlying Log4j marker
 */
int hashCode();

/**
 * Check equality with another marker
 * @param obj Object to compare with
 * @return true if markers are equal
 */
boolean equals(Object obj);

Usage Examples:

Marker marker = MarkerFactory.getMarker("DATABASE");

// Get marker properties
String name = marker.getName(); // "DATABASE"
int hash = marker.hashCode();

// Equality check
Marker other = MarkerFactory.getMarker("DATABASE");
boolean same = marker.equals(other); // true

// Use in collections
Set<Marker> markerSet = new HashSet<>();
markerSet.add(marker);

Marker Hierarchy Management

Build and manage hierarchical marker relationships for complex categorization.

/**
 * Add a child marker to create parent-child relationship
 * @param reference The child marker to add
 * @throws IllegalArgumentException if reference is null
 */
void add(Marker reference);

/**
 * Remove a child marker from this marker
 * @param reference The child marker to remove
 * @return true if the marker was removed, false if it wasn't present
 */
boolean remove(Marker reference);

/**
 * Check if this marker has child markers
 * @return true if marker has children
 */
boolean hasChildren();

/**
 * Check if this marker has parent references
 * @return true if marker has parent references
 */
boolean hasReferences();

/**
 * Get iterator over direct child markers
 * @return Iterator over child markers
 */
Iterator<Marker> iterator();

Usage Examples:

// Create marker hierarchy
Marker rootMarker = MarkerFactory.getMarker("APPLICATION");
Marker webMarker = MarkerFactory.getMarker("WEB");
Marker apiMarker = MarkerFactory.getMarker("API");
Marker authMarker = MarkerFactory.getMarker("AUTH");

// Build hierarchy: APPLICATION -> WEB -> API -> AUTH
rootMarker.add(webMarker);
webMarker.add(apiMarker);
apiMarker.add(authMarker);

// Check hierarchy properties
boolean hasChildren = webMarker.hasChildren(); // true
boolean hasReferences = apiMarker.hasReferences(); // true

// Iterate over children
for (Iterator<Marker> it = webMarker.iterator(); it.hasNext(); ) {
    Marker child = it.next();
    logger.debug("Child marker: {}", child.getName());
}

// Remove from hierarchy
boolean removed = webMarker.remove(apiMarker); // true

Marker Containment Checks

Check if markers contain other markers in their hierarchy.

/**
 * Check if this marker contains another marker (direct or hierarchical)
 * @param other The marker to check for
 * @return true if this marker contains the other marker
 * @throws IllegalArgumentException if other is null
 */
boolean contains(Marker other);

/**
 * Check if this marker contains a marker with the given name
 * @param name The marker name to check for
 * @return true if this marker contains a marker with the given name, false if name is null
 */
boolean contains(String name);

Usage Examples:

// Create nested marker structure
Marker security = MarkerFactory.getMarker("SECURITY");
Marker auth = MarkerFactory.getMarker("AUTH");
Marker login = MarkerFactory.getMarker("LOGIN");
Marker logout = MarkerFactory.getMarker("LOGOUT");

// Build hierarchy
security.add(auth);
auth.add(login);
auth.add(logout);

// Containment checks
boolean containsAuth = security.contains(auth); // true (direct child)
boolean containsLogin = security.contains(login); // true (hierarchical)
boolean containsLogout = security.contains("LOGOUT"); // true (by name)

// Use for conditional logging
if (security.contains("LOGIN")) {
    logger.info("Login-related security event detected");
}

Advanced Marker Patterns

Domain-Specific Marker Hierarchies

// E-commerce application marker hierarchy
public class MarkerConstants {
    // Root domain markers
    public static final Marker ECOMMERCE = MarkerFactory.getMarker("ECOMMERCE");
    public static final Marker SECURITY = MarkerFactory.getMarker("SECURITY");
    public static final Marker PERFORMANCE = MarkerFactory.getMarker("PERFORMANCE");
    
    // Business domain markers
    public static final Marker ORDER = MarkerFactory.getMarker("ORDER");
    public static final Marker PAYMENT = MarkerFactory.getMarker("PAYMENT");
    public static final Marker INVENTORY = MarkerFactory.getMarker("INVENTORY");
    public static final Marker USER = MarkerFactory.getMarker("USER");
    
    // Operation markers
    public static final Marker CREATE = MarkerFactory.getMarker("CREATE");
    public static final Marker UPDATE = MarkerFactory.getMarker("UPDATE");
    public static final Marker DELETE = MarkerFactory.getMarker("DELETE");
    public static final Marker QUERY = MarkerFactory.getMarker("QUERY");
    
    static {
        // Build domain hierarchy
        ECOMMERCE.add(ORDER);
        ECOMMERCE.add(PAYMENT);
        ECOMMERCE.add(INVENTORY);
        ECOMMERCE.add(USER);
        
        // Add operation markers to domains
        ORDER.add(CREATE);
        ORDER.add(UPDATE);
        PAYMENT.add(CREATE);
        USER.add(CREATE);
        USER.add(UPDATE);
        USER.add(DELETE);
        
        // Cross-cutting concerns
        SECURITY.add(USER);
        PERFORMANCE.add(ORDER);
        PERFORMANCE.add(PAYMENT);
    }
}

Dynamic Marker Creation

// Runtime marker creation based on configuration
public class DynamicMarkerManager {
    private final Map<String, Marker> customMarkers = new ConcurrentHashMap<>();
    
    public Marker getOrCreateMarker(String category, String operation) {
        String markerName = category.toUpperCase() + "_" + operation.toUpperCase();
        
        return customMarkers.computeIfAbsent(markerName, name -> {
            Marker marker = MarkerFactory.getMarker(name);
            
            // Add to category hierarchy if exists
            Marker categoryMarker = MarkerFactory.getMarker(category.toUpperCase());
            categoryMarker.add(marker);
            
            logger.debug("Created dynamic marker: {}", name);
            return marker;
        });
    }
    
    public void createBusinessMarkers(List<String> businessDomains) {
        businessDomains.forEach(domain -> {
            Marker domainMarker = MarkerFactory.getMarker(domain.toUpperCase());
            
            // Add common operations to each domain
            Arrays.asList("CREATE", "READ", "UPDATE", "DELETE").forEach(op -> {
                Marker opMarker = MarkerFactory.getMarker(op);
                domainMarker.add(opMarker);
            });
        });
    }
}

Marker-Based Filtering Strategies

// Service with marker-based logging strategy
public class OrderService {
    private static final Marker ORDER_PROCESSING = MarkerFactory.getMarker("ORDER_PROCESSING");
    private static final Marker BUSINESS_CRITICAL = MarkerFactory.getMarker("BUSINESS_CRITICAL");
    private static final Marker AUDIT_TRAIL = MarkerFactory.getMarker("AUDIT_TRAIL");
    
    static {
        // Create filtering hierarchy
        BUSINESS_CRITICAL.add(ORDER_PROCESSING);
        AUDIT_TRAIL.add(ORDER_PROCESSING);
    }
    
    public void processOrder(Order order) {
        // Business critical event
        logger.info(BUSINESS_CRITICAL, "Processing order {}", order.getId());
        
        try {
            validateOrder(order);
            calculatePricing(order);
            reserveInventory(order);
            processPayment(order);
            
            // Audit trail
            logger.info(AUDIT_TRAIL, "Order {} completed successfully", order.getId());
            
        } catch (ValidationException e) {
            logger.warn(ORDER_PROCESSING, "Order validation failed: {}", order.getId(), e);
        } catch (PaymentException e) {
            logger.error(BUSINESS_CRITICAL, "Payment processing failed for order {}", order.getId(), e);
        }
    }
}

Contextual Marker Usage

// Request-scoped marker management
public class RequestContextMarkers {
    private static final ThreadLocal<Marker> REQUEST_MARKER = new ThreadLocal<>();
    
    public static void setRequestMarker(String requestType, String clientId) {
        Marker baseMarker = MarkerFactory.getMarker("REQUEST");
        Marker typeMarker = MarkerFactory.getMarker(requestType.toUpperCase());
        Marker clientMarker = MarkerFactory.getMarker("CLIENT_" + clientId);
        
        baseMarker.add(typeMarker);
        baseMarker.add(clientMarker);
        
        REQUEST_MARKER.set(baseMarker);
    }
    
    public static Marker getCurrentRequestMarker() {
        return REQUEST_MARKER.get();
    }
    
    public static void clearRequestMarker() {
        REQUEST_MARKER.remove();
    }
    
    // Usage in request processing
    public void handleRequest(String requestType, String clientId) {
        try {
            setRequestMarker(requestType, clientId);
            
            Marker requestMarker = getCurrentRequestMarker();
            logger.info(requestMarker, "Processing request");
            
            // All logging in this thread context includes the request marker
            processBusinessLogic();
            
        } finally {
            clearRequestMarker();
        }
    }
}

Marker Validation and Debugging

// Marker hierarchy validation utilities
public class MarkerUtils {
    
    public static void printMarkerHierarchy(Marker root, String indent) {
        logger.debug("{}Marker: {}", indent, root.getName());
        
        if (root.hasChildren()) {
            for (Iterator<Marker> it = root.iterator(); it.hasNext(); ) {
                printMarkerHierarchy(it.next(), indent + "  ");
            }
        }
    }
    
    public static boolean validateMarkerHierarchy(Marker marker, Set<Marker> visited) {
        if (visited.contains(marker)) {
            logger.warn("Circular reference detected in marker hierarchy: {}", marker.getName());
            return false;
        }
        
        visited.add(marker);
        
        if (marker.hasChildren()) {
            for (Iterator<Marker> it = marker.iterator(); it.hasNext(); ) {
                if (!validateMarkerHierarchy(it.next(), new HashSet<>(visited))) {
                    return false;
                }
            }
        }
        
        return true;
    }
    
    public static List<String> getMarkerPath(Marker target, Marker root) {
        List<String> path = new ArrayList<>();
        if (findMarkerPath(target, root, path)) {
            return path;
        }
        return Collections.emptyList();
    }
    
    private static boolean findMarkerPath(Marker target, Marker current, List<String> path) {
        path.add(current.getName());
        
        if (current.equals(target)) {
            return true;
        }
        
        if (current.hasChildren()) {
            for (Iterator<Marker> it = current.iterator(); it.hasNext(); ) {
                if (findMarkerPath(target, it.next(), path)) {
                    return true;
                }
            }
        }
        
        path.remove(path.size() - 1);
        return false;
    }
}

Integration with External Systems

Marker Export for Monitoring

// Export marker statistics for monitoring
public class MarkerMetrics {
    private final Map<String, Integer> markerUsageCount = new ConcurrentHashMap<>();
    
    public void recordMarkerUsage(Marker marker) {
        String markerName = marker.getName();
        markerUsageCount.merge(markerName, 1, Integer::sum);
        
        // Record hierarchical usage
        if (marker.hasChildren()) {
            for (Iterator<Marker> it = marker.iterator(); it.hasNext(); ) {
                recordMarkerUsage(it.next());
            }
        }
    }
    
    public Map<String, Integer> getMarkerUsageStatistics() {
        return new HashMap<>(markerUsageCount);
    }
}

This comprehensive marker management system provides flexible categorization and filtering capabilities for complex logging scenarios in enterprise applications.

Install with Tessl CLI

npx tessl i tessl/maven-org-apache-logging-log4j--log4j-slf4j2-impl

docs

fluent-logging.md

index.md

marker-logging.md

marker-management.md

mdc-support.md

standard-logging.md

tile.json