Log4j 1.x API compatibility layer that implements Apache Log4j API over SLF4J for seamless migration
—
Appender interfaces and skeleton implementations for output destinations, plus layout classes for message formatting. Most implementations are minimal or no-op since actual output handling is managed by the underlying SLF4J implementation.
Base interface defining the contract for log output destinations. All methods provide compatibility with Log4j 1.x API.
/**
* Base interface for log output destinations
*/
public interface Appender {
/**
* Add filter to the appender
* @param newFilter Filter to add
*/
void addFilter(Filter newFilter);
/**
* Get the head filter in the filter chain
* @return Head filter or null if no filters
*/
Filter getFilter();
/**
* Clear all filters from the appender
*/
void clearFilters();
/**
* Close the appender and release resources
*/
void close();
/**
* Log event to appender destination
* @param event LoggingEvent to append
*/
void doAppend(LoggingEvent event);
/**
* Get appender name
* @return Name of the appender
*/
String getName();
/**
* Set appender name
* @param name Name for the appender
*/
void setName(String name);
/**
* Get error handler for this appender
* @return ErrorHandler instance
*/
ErrorHandler getErrorHandler();
/**
* Set error handler for this appender
* @param errorHandler ErrorHandler to set
*/
void setErrorHandler(ErrorHandler errorHandler);
/**
* Get layout for this appender
* @return Layout instance
*/
Layout getLayout();
/**
* Set layout for this appender
* @param layout Layout to set
*/
void setLayout(Layout layout);
/**
* Check if this appender requires a layout
* @return true if layout is required
*/
boolean requiresLayout();
}Minimal implementation class implementing OptionHandler interface. Provides skeleton methods for appender functionality.
/**
* Skeleton implementation for appender functionality
*/
public class AppenderSkeleton implements OptionHandler {
/**
* Set layout for the appender (no-op implementation)
* @param layout Layout to set
*/
public void setLayout(Layout layout);
/**
* Set name for the appender (no-op implementation)
* @param name Name to set
*/
public void setName(String name);
/**
* Activate options (no-op implementation)
*/
public void activateOptions();
/**
* Set threshold priority (no-op implementation)
* @param threshold Priority threshold to set
*/
public void setThreshold(Priority threshold);
}Usage Examples:
// AppenderSkeleton provides minimal compatibility
AppenderSkeleton appender = new AppenderSkeleton() {};
appender.setName("MyAppender");
appender.setLayout(new SimpleLayout());
appender.activateOptions(); // No-opMinimal appender class extending AppenderSkeleton. Empty implementation providing inheritance hierarchy compatibility.
/**
* Minimal writer-based appender extending AppenderSkeleton
*/
public class WriterAppender extends AppenderSkeleton {
// Empty implementation - all functionality inherited from AppenderSkeleton
}Skeleton implementation for console output. Extends WriterAppender with console-specific constructors.
/**
* Console output appender (skeleton implementation)
*/
public class ConsoleAppender extends WriterAppender {
/**
* Default constructor
*/
public ConsoleAppender();
/**
* Constructor with layout
* @param layout Layout for formatting messages
*/
public ConsoleAppender(Layout layout);
/**
* Constructor with layout and target
* @param layout Layout for formatting messages
* @param target Target stream ("System.out" or "System.err")
*/
public ConsoleAppender(Layout layout, String target);
}Usage Examples:
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.SimpleLayout;
import org.apache.log4j.PatternLayout;
// Create console appender with simple layout
ConsoleAppender consoleAppender = new ConsoleAppender(new SimpleLayout());
// Create with pattern layout
PatternLayout pattern = new PatternLayout("%d [%t] %-5p %c - %m%n");
ConsoleAppender patternAppender = new ConsoleAppender(pattern);
// Create with target specification
ConsoleAppender errorAppender = new ConsoleAppender(pattern, "System.err");
// Note: These are skeleton implementations - actual output
// is handled by SLF4J implementationFile output appender with minimal implementation. Extends WriterAppender.
/**
* File output appender (minimal implementation)
*/
public class FileAppender extends WriterAppender {
// Minimal implementation - inherits from WriterAppender
}Rolling file appender with minimal implementation. Does not extend FileAppender in this implementation.
/**
* Rolling file appender (minimal implementation)
*/
public class RollingFileAppender {
/**
* Default constructor
*/
public RollingFileAppender();
/**
* Constructor with layout and filename
* @param layout Layout for formatting
* @param filename Output file name
* @throws IOException If file operations fail
*/
public RollingFileAppender(Layout layout, String filename) throws IOException;
/**
* Constructor with layout, filename and append mode
* @param layout Layout for formatting
* @param filename Output file name
* @param append Whether to append to existing file
* @throws IOException If file operations fail
*/
public RollingFileAppender(Layout layout, String filename, boolean append) throws IOException;
/**
* Set maximum number of backup files (no-op implementation)
* @param maxBackups Maximum backup files
*/
public void setMaxBackupIndex(int maxBackups);
/**
* Set maximum file size before rolling (no-op implementation)
* @param maxFileSize Maximum file size in bytes
*/
public void setMaximumFileSize(long maxFileSize);
}Usage Examples:
import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.PatternLayout;
import java.io.IOException;
try {
// Create rolling file appender
RollingFileAppender rollingAppender = new RollingFileAppender(
new PatternLayout("%d %-5p [%c] - %m%n"),
"app.log"
);
// Configure rolling parameters (no-op)
rollingAppender.setMaxBackupIndex(5);
rollingAppender.setMaximumFileSize(10 * 1024 * 1024); // 10MB
} catch (IOException e) {
// Handle file creation errors
}
// Note: This is a minimal implementation for API compatibilityLayout classes for formatting log messages. Minimal implementations providing basic API compatibility.
/**
* Base class for message layouts (minimal implementation)
*/
public class Layout {
// Minimal implementation - actual formatting handled by SLF4J
}
/**
* Simple layout extending base Layout
*/
public class SimpleLayout extends Layout {
// Minimal implementation extending Layout
}
/**
* Pattern-based layout with minimal implementation
*/
public class PatternLayout extends Layout {
/**
* Default constructor
*/
public PatternLayout();
/**
* Constructor with pattern
* @param pattern Conversion pattern (stored but not used)
*/
public PatternLayout(String pattern);
}Usage Examples:
import org.apache.log4j.SimpleLayout;
import org.apache.log4j.PatternLayout;
// Simple layout
SimpleLayout simple = new SimpleLayout();
// Pattern layouts (pattern parameter accepted but not processed)
PatternLayout basic = new PatternLayout();
PatternLayout detailed = new PatternLayout("%d [%t] %-5p %c - %m%n");
// Note: Actual message formatting is handled by SLF4J implementation
// These layouts provide API compatibility onlySPI interfaces providing minimal implementations for Log4j compatibility.
/**
* Option handler interface for activation
*/
public interface OptionHandler {
/**
* Activate configured options
*/
void activateOptions();
}
/**
* Filter interface (minimal implementation)
*/
public abstract class Filter {
// Minimal implementation - filtering handled by SLF4J
}
/**
* Error handler interface (minimal implementation)
*/
public interface ErrorHandler {
// Minimal interface - error handling managed by SLF4J
}
/**
* Logging event class (minimal implementation)
*/
public class LoggingEvent {
// Minimal implementation - event data handled by SLF4J
}Usage Examples:
// These SPI classes provide API compatibility but minimal functionality
// Actual filtering, error handling, and event processing is managed by SLF4J
// Custom option handler
public class CustomAppender implements OptionHandler {
@Override
public void activateOptions() {
// Configuration activation logic
}
}Important: All appender and layout classes in log4j-over-slf4j are minimal or skeleton implementations. They provide API compatibility with Log4j 1.x but do not perform actual logging operations. Instead:
Migration Strategy:
When migrating from Log4j 1.x to log4j-over-slf4j:
Example SLF4J Configuration (logback.xml):
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d %-5level [%logger{36}] - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>Install with Tessl CLI
npx tessl i tessl/maven-org-slf4j--log4j-over-slf4j