CtrlK
BlogDocsLog inGet started
Tessl Logo

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

A versatile, industrial-grade, and reference implementation of the Log4j API with rich components for various logging use cases.

Pending
Overview
Eval results
Files

async-logging.mddocs/

Asynchronous Logging

Log4j Core provides high-performance asynchronous logging capabilities using the LMAX Disruptor framework. Async logging significantly reduces the latency impact of logging on application threads by processing log events in background threads.

Capabilities

Async Logger

High-performance asynchronous logger implementation that inherits all Logger functionality while processing events asynchronously.

/**
 * Asynchronous logger implementation using LMAX Disruptor
 * Inherits all methods from Logger but processes events asynchronously
 */
public class AsyncLogger extends Logger {
    /**
     * Constructor for AsyncLogger
     * @param context Logger context
     * @param name Logger name
     * @param messageFactory Message factory
     * @param asyncLoggerConfigDisruptor Disruptor for async processing
     */
    protected AsyncLogger(LoggerContext context, String name, MessageFactory messageFactory, 
                         AsyncLoggerConfigDisruptor asyncLoggerConfigDisruptor);
    
    /**
     * Check if this logger supports flow tracing
     * @return true if flow tracing is supported
     */
    public boolean isFlowTracingSupported();
    
    // All logging methods inherited from Logger:
    // void debug(String message);
    // void info(String message);  
    // void warn(String message);
    // void error(String message);
    // etc.
}

Async Logger Context

Logger context specifically designed for asynchronous logging operations.

/**
 * Logger context for async loggers with specialized configuration
 */
public class AsyncLoggerContext extends LoggerContext {
    /**
     * Create AsyncLoggerContext
     * @param name Context name
     */
    public AsyncLoggerContext(String name);
    
    /**
     * Create AsyncLoggerContext with configuration source
     * @param name Context name
     * @param externalContext External context object
     * @param configLocn Configuration location
     */
    public AsyncLoggerContext(String name, Object externalContext, String configLocn);
    
    /**
     * Create AsyncLoggerContext with configuration source URI
     * @param name Context name
     * @param externalContext External context object  
     * @param configLocn Configuration location URI
     */
    public AsyncLoggerContext(String name, Object externalContext, URI configLocn);
    
    /**
     * Check if async loggers are supported in this context
     * @return true if async loggers are supported
     */
    public boolean hasAsyncLoggers();
    
    /**
     * Set whether to include location information in async logging
     * @param includeLocation true to include location info
     */
    public void setIncludeLocation(boolean includeLocation);
}

Async Logger Config

Configuration class for async logger behavior and settings.

/**
 * Configuration for async logger with specialized async handling
 */
public class AsyncLoggerConfig extends LoggerConfig {
    /**
     * Create AsyncLoggerConfig
     */
    public AsyncLoggerConfig();
    
    /**
     * Create AsyncLoggerConfig with name and level
     * @param name Logger name
     * @param level Logger level
     * @param additive Additivity flag
     */
    public AsyncLoggerConfig(String name, Level level, boolean additive);
    
    /**
     * Process log event asynchronously
     * @param event LogEvent to process
     */
    protected void processLogEvent(LogEvent event);
    
    /**
     * Handle async queue full condition
     * @param event LogEvent that couldn't be queued
     * @return EventRoute indicating how to handle the event
     */
    protected EventRoute handleQueueFull(LogEvent event);
}

Async Logger Context Selector

Context selector for choosing async logger contexts.

/**
 * Context selector that creates AsyncLoggerContext instances
 */
public class AsyncLoggerContextSelector implements ContextSelector {
    /**
     * Get logger context for the calling context
     * @param fqcn Fully qualified class name
     * @param loader ClassLoader
     * @param currentContext Use current context flag
     * @param externalContext External context object
     * @return LoggerContext instance
     */
    public LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext, Object externalContext);
    
    /**
     * Get logger context for specific parameters
     * @param fqcn Fully qualified class name
     * @param loader ClassLoader
     * @param currentContext Use current context flag
     * @param configLocation Configuration location
     * @return LoggerContext instance
     */
    public LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext, URI configLocation);
    
    /**
     * Get all logger contexts
     * @return List of all LoggerContext instances
     */
    public List<LoggerContext> getLoggerContexts();
    
    /**
     * Remove logger context
     * @param context LoggerContext to remove
     */
    public void removeContext(LoggerContext context);
    
    /**
     * Check if context selector supports async loggers
     * @return true if async loggers are supported
     */
    public boolean hasAsyncLoggers();
}

Usage Examples:

import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.apache.logging.log4j.core.selector.ContextSelector;

// Set async logger context selector
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");

// Get async context
AsyncLoggerContextSelector selector = new AsyncLoggerContextSelector();
LoggerContext context = selector.getContext("com.example.MyClass", 
    MyClass.class.getClassLoader(), false, null);

// Check if context supports async loggers
boolean supportsAsync = selector.hasAsyncLoggers(); // true

Queue Full Policies

Policies for handling situations when the async logging queue becomes full.

Async Queue Full Policy Interface

/**
 * Policy interface for handling full async queues
 */
public interface AsyncQueueFullPolicy {
    /**
     * Get event route when queue is full
     * @param backgroundThreadId ID of background thread
     * @param level Log level of the event
     * @return EventRoute indicating how to handle the event
     */
    EventRoute getRoute(long backgroundThreadId, Level level);
    
    /**
     * Event route enumeration
     */
    enum EventRoute {
        /** Synchronously process the event in caller thread */
        SYNCHRONOUS,
        /** Enqueue the event (may block) */
        ENQUEUE,
        /** Discard the event */
        DISCARD
    }
}

Default Async Queue Full Policy

/**
 * Default policy that processes events synchronously when queue is full
 */
public class DefaultAsyncQueueFullPolicy implements AsyncQueueFullPolicy {
    /**
     * Create default policy
     */
    public DefaultAsyncQueueFullPolicy();
    
    /**
     * Returns SYNCHRONOUS route for all events when queue is full
     * @param backgroundThreadId Background thread ID
     * @param level Log level
     * @return Always returns EventRoute.SYNCHRONOUS
     */
    public EventRoute getRoute(long backgroundThreadId, Level level);
}

Discarding Async Queue Full Policy

/**
 * Policy that discards events based on level when queue is full
 */
public class DiscardingAsyncQueueFullPolicy implements AsyncQueueFullPolicy {
    /**
     * Create discarding policy with threshold level
     * @param thresholdLevel Minimum level to keep (higher levels discarded)
     */
    public DiscardingAsyncQueueFullPolicy(Level thresholdLevel);
    
    /**
     * Create discarding policy with default INFO threshold
     */
    public DiscardingAsyncQueueFullPolicy();
    
    /**
     * Return route based on level threshold
     * @param backgroundThreadId Background thread ID
     * @param level Log level
     * @return DISCARD for levels below threshold, SYNCHRONOUS for others
     */
    public EventRoute getRoute(long backgroundThreadId, Level level);
    
    /**
     * Get threshold level
     * @return Current threshold level
     */
    public Level getThresholdLevel();
}

Usage Examples:

import org.apache.logging.log4j.core.async.*;

// Set default queue full policy (process synchronously)
System.setProperty("log4j2.AsyncQueueFullPolicy", 
    "org.apache.logging.log4j.core.async.DefaultAsyncQueueFullPolicy");

// Set discarding policy to discard DEBUG and TRACE when queue full
System.setProperty("log4j2.AsyncQueueFullPolicy", 
    "org.apache.logging.log4j.core.async.DiscardingAsyncQueueFullPolicy");
System.setProperty("log4j2.DiscardThreshold", "INFO");

// Programmatic policy usage
AsyncQueueFullPolicy policy = new DiscardingAsyncQueueFullPolicy(Level.WARN);
EventRoute route = policy.getRoute(Thread.currentThread().getId(), Level.DEBUG);
// Returns EventRoute.DISCARD for DEBUG level

Configuration for Async Logging

System Properties

Key system properties for configuring async logging behavior:

/**
 * Important system properties for async logging configuration
 */
public class AsyncLoggerSystemProperties {
    // Ring buffer size for async loggers (default: 256 * 1024)
    public static final String ASYNC_LOGGER_RING_BUFFER_SIZE = "log4j2.asyncLoggerRingBufferSize";
    
    // Wait strategy for async loggers (default: Sleep)  
    public static final String ASYNC_LOGGER_WAIT_STRATEGY = "log4j2.asyncLoggerWaitStrategy";
    
    // Thread name strategy for async loggers
    public static final String ASYNC_LOGGER_THREAD_NAME_STRATEGY = "log4j2.asyncLoggerThreadNameStrategy";
    
    // Whether to include location information (default: false)
    public static final String ASYNC_LOGGER_INCLUDE_LOCATION = "log4j2.includeLocation";
    
    // Queue full policy class name
    public static final String ASYNC_QUEUE_FULL_POLICY = "log4j2.AsyncQueueFullPolicy";
    
    // Discard threshold level for DiscardingAsyncQueueFullPolicy
    public static final String DISCARD_THRESHOLD = "log4j2.DiscardThreshold";
    
    // Timeout for async logger shutdown (default: 3000ms)
    public static final String ASYNC_LOGGER_TIMEOUT = "log4j2.asyncLoggerTimeout";
}

Usage Examples:

// Configure async logging via system properties
System.setProperty("log4j2.asyncLoggerRingBufferSize", "1048576"); // 1MB buffer
System.setProperty("log4j2.asyncLoggerWaitStrategy", "Block");
System.setProperty("log4j2.includeLocation", "false");
System.setProperty("log4j2.asyncLoggerTimeout", "5000");

// Available wait strategies:
// - "Sleep" (default) - CPU-friendly but higher latency
// - "Yield" - Lower latency but higher CPU usage  
// - "Block" - Lowest latency but blocks threads
// - "Spin" - Lowest latency but highest CPU usage

Mixed Sync/Async Configuration

You can configure some loggers to be async while others remain synchronous:

XML Configuration Example:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <File name="File" fileName="application.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <!-- Async logger for high-volume package -->
        <AsyncLogger name="com.example.highvolume" level="INFO" additivity="false">
            <AppenderRef ref="File"/>
        </AsyncLogger>
        
        <!-- Regular synchronous logger -->
        <Logger name="com.example.critical" level="WARN" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
        
        <!-- Async root logger -->
        <AsyncRoot level="INFO">
            <AppenderRef ref="Console"/>
        </AsyncRoot>
    </Loggers>
</Configuration>

Performance Considerations

Thread Safety

Async loggers are fully thread-safe and can be called concurrently from multiple threads without external synchronization.

Memory Usage

The ring buffer size directly affects memory usage. Larger buffers provide better throughput but consume more memory.

Location Information

Including location information (class, method, line number) significantly impacts performance in async logging and should be disabled for maximum throughput.

Queue Full Behavior

Choose queue full policies based on your application's priorities:

  • DefaultAsyncQueueFullPolicy: Guarantees no log loss but may impact latency
  • DiscardingAsyncQueueFullPolicy: Maintains low latency but may lose low-priority log events

Install with Tessl CLI

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

docs

appenders.md

async-logging.md

configuration.md

core-context.md

filters.md

index.md

layouts.md

lookups.md

plugins.md

tile.json