SLF4J 2 provider that bridges SLF4J 2 logging calls to the Apache Log4j API
—
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.
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)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);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); // trueCheck 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");
}// 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);
}
}// 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);
});
});
}
}// 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);
}
}
}// 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 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;
}
}// 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