Comprehensive SLF4J implementation providing enterprise-grade logging with flexible configuration, high performance, and extensive appender ecosystem for Java applications.
—
Message formatting and encoding for different output formats and protocols. Encoders are responsible for converting log events into byte arrays, while layouts format events into strings.
Base interfaces and classes for event encoding.
/**
* Interface for encoding log events to byte arrays
*/
public interface Encoder<E> extends ContextAware, LifeCycle {
/**
* Encode a single event
*/
byte[] encode(E event);
/**
* Get header bytes (written once at start)
*/
byte[] headerBytes();
/**
* Get footer bytes (written once at end)
*/
byte[] footerBytes();
}
/**
* Base implementation for encoders
*/
public abstract class EncoderBase<E> extends ContextAwareBase implements Encoder<E> {
protected boolean started;
public boolean isStarted();
public void start();
public void stop();
// Default implementations
public byte[] headerBytes();
public byte[] footerBytes();
}
/**
* Interface for layout-based encoders
*/
public interface LayoutWrappingEncoder<E> extends Encoder<E> {
Layout<E> getLayout();
void setLayout(Layout<E> layout);
String getCharset();
void setCharset(Charset charset);
boolean isImmediateFlush();
void setImmediateFlush(boolean immediateFlush);
}Most commonly used encoder that formats events using pattern strings.
/**
* Encoder that uses PatternLayout for formatting
*/
public class PatternLayoutEncoder extends LayoutWrappingEncoder<ILoggingEvent> {
/**
* Set the pattern string for formatting
*/
public void setPattern(String pattern);
public String getPattern();
/**
* Set the output pattern (alias for setPattern)
*/
public void setOutputPatternAsHeader(boolean outputPatternAsHeader);
public boolean isOutputPatternAsHeader();
}Usage Examples:
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
// Create pattern encoder
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(loggerContext);
// Set formatting pattern
encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n");
// Optional: output pattern as header
encoder.setOutputPatternAsHeader(true);
// Set charset if needed
encoder.setCharset(StandardCharsets.UTF_8);
encoder.start();Structured logging encoder that outputs events in JSON format.
/**
* JSON-based encoder for structured logging
*/
public class JsonEncoder extends EncoderBase<ILoggingEvent> {
private boolean includeContext = true;
private boolean includeMdc = true;
/**
* Include logger context information in JSON
*/
public void setIncludeContext(boolean includeContext);
public boolean isIncludeContext();
/**
* Include MDC properties in JSON
*/
public void setIncludeMdc(boolean includeMdc);
public boolean isIncludeMdc();
}Usage Examples:
import ch.qos.logback.classic.encoder.JsonEncoder;
// Create JSON encoder
JsonEncoder jsonEncoder = new JsonEncoder();
jsonEncoder.setContext(loggerContext);
jsonEncoder.setIncludeContext(true);
jsonEncoder.setIncludeMdc(true);
jsonEncoder.start();
// Results in JSON output like:
// {"timestamp":"2023-01-01T12:00:00.000Z","level":"INFO","logger":"com.example.App","message":"User logged in","mdc":{"userId":"123"}}Core layout interface for string-based event formatting.
/**
* Interface for formatting log events as strings
*/
public interface Layout<E> extends ContextAware, LifeCycle {
/**
* Format a single event as string
*/
String doLayout(E event);
/**
* Get file header string
*/
String getFileHeader();
/**
* Get presentation header string
*/
String getPresentationHeader();
/**
* Get presentation footer string
*/
String getPresentationFooter();
/**
* Get file footer string
*/
String getFileFooter();
/**
* Get content type for HTTP responses
*/
String getContentType();
}
/**
* Base implementation for layouts
*/
public abstract class LayoutBase<E> extends ContextAwareBase implements Layout<E> {
protected boolean started;
String fileHeader;
String presentationHeader;
String presentationFooter;
String fileFooter;
public boolean isStarted();
public void start();
public void stop();
public void setFileHeader(String header);
public String getFileHeader();
public void setPresentationHeader(String header);
public String getPresentationHeader();
public void setPresentationFooter(String footer);
public String getPresentationFooter();
public void setFileFooter(String footer);
public String getFileFooter();
public String getContentType();
}Flexible layout using pattern strings with conversion specifiers.
/**
* Layout that formats events using pattern strings
*/
public class PatternLayout extends PatternLayoutBase<ILoggingEvent> {
public static final Map<String, String> DEFAULT_CONVERTER_MAP = new HashMap<String, String>();
public static final String HEADER_PREFIX = "#logback.classic pattern: ";
static {
// Default pattern converters
DEFAULT_CONVERTER_MAP.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
DEFAULT_CONVERTER_MAP.put("d", DateConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("date", DateConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("r", RelativeTimeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("relative", RelativeTimeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("level", LevelConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("le", LevelConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("p", LevelConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("t", ThreadConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("thread", ThreadConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("lo", LoggerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("logger", LoggerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("c", LoggerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("m", MessageConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("msg", MessageConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("message", MessageConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("C", ClassOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("class", ClassOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("M", MethodOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("method", MethodOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("L", LineOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("line", LineOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("F", FileOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("file", FileOfCallerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("X", MDCConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("mdc", MDCConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("ex", ThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("exception", ThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("rEx", RootCauseFirstThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("rootException", RootCauseFirstThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("throwable", ThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("xEx", ExtendedThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("xException", ExtendedThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("xThrowable", ExtendedThrowableProxyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("nopex", NopThrowableInformationConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("nopexception", NopThrowableInformationConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("cn", ContextNameConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("contextName", ContextNameConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("caller", CallerDataConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("marker", MarkerConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("property", PropertyConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("n", LineSeparatorConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("black", BlackCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("red", RedCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("green", GreenCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("yellow", YellowCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("blue", BlueCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("magenta", MagentaCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("cyan", CyanCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("white", WhiteCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("gray", GrayCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("boldRed", BoldRedCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("boldGreen", BoldGreenCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("boldYellow", BoldYellowCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("boldBlue", BoldBlueCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("boldMagenta", BoldMagentaCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("boldCyan", BoldCyanCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("boldWhite", BoldWhiteCompositeConverter.class.getName());
DEFAULT_CONVERTER_MAP.put("highlight", HighlightingCompositeConverter.class.getName());
}
}
/**
* Base class for pattern-based layouts
*/
public abstract class PatternLayoutBase<E> extends LayoutBase<E> {
Node head;
String pattern;
protected PostCompileProcessor<E> postCompileProcessor;
/**
* Set the conversion pattern
*/
public void setPattern(String pattern);
public String getPattern();
/**
* Get the effective converter map
*/
public Map<String, String> getEffectiveConverterMap();
public Map<String, String> getDefaultConverterMap();
}Additional layout implementations for specific use cases.
/**
* Simple layout showing Time, Thread, Level, Logger (TTLL)
*/
public class TTLLLayout extends LayoutBase<ILoggingEvent> {
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
public String doLayout(ILoggingEvent event);
}
/**
* HTML-based layout for web display
*/
public class HTMLLayout extends LayoutBase<ILoggingEvent> {
protected String title = "Logback Log Messages";
protected CssBuilder cssBuilder;
public void setTitle(String title);
public String getTitle();
/**
* Set custom CSS builder for styling
*/
public CssBuilder getCssBuilder();
public void setCssBuilder(CssBuilder cssBuilder);
public String getFileHeader();
public String getPresentationHeader();
public String doLayout(ILoggingEvent event);
public String getPresentationFooter();
public String getFileFooter();
public String getContentType();
}Common pattern conversion specifiers for PatternLayout:
| Specifier | Description | Example |
|---|---|---|
%d{pattern} | Date/time | %d{yyyy-MM-dd HH:mm:ss.SSS} |
%thread | Thread name | %thread or %t |
%level | Log level | %-5level (left-aligned, 5 chars) |
%logger{length} | Logger name | %logger{36} (abbreviated to 36 chars) |
%msg | Log message | %msg or %message |
%n | Line separator | %n |
%ex | Exception | %ex (full stack trace) |
%mdc | MDC properties | %mdc or %X{key} |
%marker | SLF4J marker | %marker |
%property{key} | Context property | %property{user.home} |
%caller{depth} | Caller information | %caller{2} |
%class | Caller class | %C{1} (simple name) |
%method | Caller method | %M |
%line | Line number | %L |
%file | File name | %F |
// Create custom pattern layout
PatternLayout layout = new PatternLayout();
layout.setContext(loggerContext);
layout.setPattern("%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n");
layout.start();
// Use with WriterAppender
WriterAppender<ILoggingEvent> appender = new WriterAppender<>();
appender.setLayout(layout);// Pattern with conditional MDC
String pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}%X{userId:+ userId=%X{userId}} - %msg%n";
// Pattern with color highlighting
String colorPattern = "%red(%d{HH:mm:ss.SSS}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %msg%n";// Custom JSON encoder configuration
JsonEncoder jsonEncoder = new JsonEncoder();
jsonEncoder.setContext(loggerContext);
jsonEncoder.setIncludeContext(true);
jsonEncoder.setIncludeMdc(true);
// Example JSON output:
// {
// "timestamp": "2023-12-01T10:30:00.123Z",
// "level": "INFO",
// "thread": "main",
// "logger": "com.example.UserService",
// "message": "User created successfully",
// "mdc": {
// "userId": "12345",
// "requestId": "req-abc-123"
// },
// "context": {
// "name": "default"
// }
// }Install with Tessl CLI
npx tessl i tessl/maven-ch-qos-logback--logback-classic