Layouts

An appender uses a layout to encode a LogEvent into a form that meets the needs of whatever will be consuming the log event. This page will try to answer following questions:

Common concerns

This section introduces you to some common concerns shared by almost all predefined layouts that you need to be aware of while using them.

Structured logging

In almost any modern production deployment, logs are no more written to files read by engineers while troubleshooting, but forwarded to log ingestion systems (Elasticsearch, Google Cloud Logging, etc.) for several observability use cases ranging from logging to metrics. This necessitates the applications to structure their logs in a machine-readable way ready to be delivered to an external system. This act of encoding logs following a certain structure is called structured logging.

Log4j strives to provide top of the class support for structured logging. To create an end-to-end experience, it provides several structured message types along with layouts supporting structured logging.

We recommend JSON Template Layout for structured logging purposes.

Character encoding

All predefined layouts produce String that eventually get converted into a byte using the Charset configured. While doing so, unless an explicit encoding configuration is stated, they use UTF-8 by default. If you want all your log events to be formatted in a certain character encoding that is different from what the employed layout defaults to, make sure to configure the layout’s character encoding as needed.

Location information

Several layouts offer directives to include the location information: the caller class, method, file, and line. Log4j takes a snapshot of the stack, and walks the stack trace to find the location information. This is an expensive operation and should be avoided in performance-sensitive setups.

Note that the caller class of the location information and the logger name are two different things. In most setups just using the logger name – which doesn’t incur any overhead to obtain while logging! – is a sufficient and zero-cost substitute for the caller class.

Example demonstrating that the logger name can be a substitute for the caller name
package com.mycompany;

public class PaymentService {

    // Logger name: `com.mycompany.PaymentService`
    private static final Logger LOGGER = LogManager.getLogger();

    private static final class PaymentTransaction {
        void doPayment() {
            // Caller class: `com.mycompany.PaymentService$PaymentTransaction`
            LOGGER.trace("...");
        }
    }

}

In the above example, if the caller class (which is expensive to compute!) is omitted in the layout, the produced log line will still be likely to contain sufficient information to trace back the source by just looking at the logger name.

Asynchronous loggers need to capture the location information before passing the log message to another thread; otherwise the location information will be lost after that point. Due to associated performance implications, asynchronous loggers and asynchronous appenders do not include location information by default. You can override the default behaviour in your asynchronous logger or asynchronous appender configuration.

Even if a layout is configured not to request location information, it might use it if the information is already available. This is always the case if the location information is captured at build time using the Log4j Transform Maven Plugin.

Collection

Log4j bundles predefined layouts to assist in several common deployment use cases. Let’s start with shortcuts to most used ones:

  • Are you looking for a production-grade JSON layout ready to be deployed to a log ingestion system such as Elasticsearch or Google Cloud? Refer to JSON Template Layout.

  • Are you looking for a layout that encodes log events in a human-readable format suitable for tests and local development? Refer to Pattern Layout.

Following sections explain all predefined layouts in detail.

CSV Layouts

There are two layouts performing Comma Separated Value (CSV) encoding:

CSV Parameter Layout

CsvParameterLayout encodes only the parameters of the message of a log event. Generated CSV records will be composed of fields denoting the message parameters.

Click here for examples

Given the following statement

LOGGER.info("Record1 {} {}", "arg1", "arg2");
LOGGER.error("Record2 {} {} {}", "arg3", "arg4", "arg5", throwable);

CsvParameterLayout will output

arg1,arg2
arg3,arg4,arg5

The same can be achieved using ObjectArrayMessage as follows:

LOGGER.info(new ObjectArrayMessage("arg1", "arg2"));
LOGGER.info(new ObjectArrayMessage("arg3", "arg4", "arg5"));

CSV Log Event Layout

CsvLogEventLayout encodes the complete log event, including the formatted message. Generated CSV records will be composed of following fields in the given order:

  1. Time (in nanoseconds)

  2. Time (in milliseconds)

  3. Level

  4. Thread ID

  5. Thread name

  6. Thread priority

  7. Message (formatted, hence including parameters)

  8. Logger FQCN

  9. Logger name

  10. Marker

  11. Throwable

  12. Source

  13. Thread context map

  14. Thread context stack

Click here for examples

Given the following statement

LOGGER.debug("one={}, two={}, three={}", 1, 2, 3);

CsvLogEventLayout will output

0,1441617184044,DEBUG,main,"one=1, two=2, three=3",org.apache.logging.log4j.spi.AbstractLogger,,,,org.apache.logging.log4j.core.layout.CsvLogEventLayoutTest.testLayout(CsvLogEventLayoutTest.java:98),{},[]

Configuration

Both CsvParameterLayout and CsvLogEventLayout are configured with the following parameters:

Parameter Type Description

format

String

A predefined format name (Default, Excel, MySQL, RFC4180, TDF, etc.) accepted by CSVFormat

delimiter

Character

The field delimiter character

escape

Character

The escape character

quote

Character

The quote character

quoteMode

String

A quote mode name (ALL, ALL_NONE_NULL, MINIMAL, NON_NUMERIC, NONE, etc.) accepted by QuoteMode

nullString

String

The string to denote null values

recordSeparator

String

The record separator string

charset

Charset

The character encoding

header

String

The header to include when the stream is opened

footer

String

The footer to include when the stream is closed

Additional runtime dependencies are required for using CSV layouts:

  • Maven

  • Gradle

We assume you use log4j-bom for dependency management.

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-csv</artifactId>
  <scope>runtime</scope>
</dependency>

We assume you use log4j-bom for dependency management.

runtimeOnly 'org.apache.logging.log4j:log4j-csv'

HTML Layout

HtmlLayout generates an HTML page, and adds each log event to a row in a table.

It is configured with the following parameters:

Parameter Type Description

charset

String

The character encoding

contentType

String

The Content-Type header value (defaults to text/html)

datePattern

String

The date format of the log event. The default is JVM_ELAPSE_TIME, which outputs the milliseconds since JVM started. For other valid values, refer to the date conversion specifier of Pattern Layout.

fontName

String

The font-family (defaults to arial,sans-serif)

fontSize

String

The font size (defaults to small)

locationInfo

boolean

If true, the source location information be included (defaults to false)

timezone

String

The time zone ID of the log event. If not specified, this layout uses the TimeZone.getDefault() as the default. You can use time zone IDs supported by TimeZone.getTimeZone(String).

title

String

The HTML page title

JSON Template Layout

JsonTemplateLayout is a customizable, efficient, and garbage-free JSON generating layout. It encodes LogEvents according to the structure described by the JSON template provided.

For instance, given the following event template stored in MyLayout.json in your classpath:

{
  "instant": { (1)
    "$resolver": "timestamp",
    "pattern": {
      "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
      "timeZone": "UTC"
    }
  },
  "someConstant": 1, (2)
  "message": { (3)
    "$resolver": "message",
    "stringified": true
  }
}
1 Using the timestamp event template resolver to populate the instant field
2 Passing a constant that will be rendered as is
3 Using the message event template resolver to populate the message field

in combination with the below layout configuration:

  • XML

  • JSON

  • YAML

  • Properties

Snippet from an example log4j2.xml
<JsonTemplateLayout eventTemplateUri="classpath:MyLayout.json"/>
Snippet from an example log4j2.json
"JsonTemplateLayout": {
  "eventTemplateUri": "classpath:MyLayout.json"
}
Snippet from an example log4j2.yaml
JsonTemplateLayout:
  eventTemplateUri: "classpath:MyLayout.json"
Snippet from an example log4j2.properties
appender.0.layout.type = JsonTemplateLayout
appender.0.layout.eventTemplateUri = classpath:MyLayout.json

JSON Template Layout generates JSON as follows:

{"instant":"2017-05-25T19:56:23.370Z","someConstant":1,"message":"Hello, error!"} (1)
1 JSON pretty-printing is not supported for performance reasons.

Good news is JSON Template Layout is perfectly production-ready without any configuration! It bundles several predefined event templates modeling popular JSON-based log formats.

Read more on JSON Template Layout…​

Message Layout

MessageLayout is a special layout that extracts the Message contained in a log event. It is currently only useful with the JDBC Appender.

Pattern Layout

PatternLayout is a customizable, efficient, garbage-free, and human-readable string generating layout using a user-provided pattern. It is analogous to String#format() with specialized directives on injecting certain properties of a LogEvent.

Pattern Layout is not intended for structural logging purposes. For production environments, you are strongly advised to use JSON Template Layout producing JSON output ready to be delivered to log ingestion systems such as Elasticsearch or Google Cloud Logging.

A conversion pattern is composed of literal text and format control expressions. For instance, given the %-5p [%t]: %m%n pattern, following statements

LOGGER.debug("Message 1");
LOGGER.warn("Message 2");

will yield the output

DEBUG [main]: Message 1
WARN  [main]: Message 2

Read more on Pattern Layout…​

RFC 5424 Layout

Rfc5424 Layout encodes log events according to the Syslog message format described in RFC 5424.

RFC 5424 obsoletes RFC 3164, implemented by Syslog Layout.

RFC 5424 Layout is configured with the following parameters:

Parameter Type Description

appName

String

The APP-NAME field as described in RFC 5424

charset

String

The character encoding (defaults to UTF-8)

enterpriseNumber

integer

The enterpriseId parameter as described in RFC 5424. If missing, 32473 will be used, which is reserved for documentation use.

exceptionPattern

String

An exception conversion specifier of Pattern Layout. The default is to not include the Throwable from the event, if any, in the output.

facility

String

The name of Facility as described in RFC 5424. The matching is case-insensitive. It defaults to LOCAL0.

id

String

The default Structured Data ID to use when formatting according to RFC 5424. If the log event contains a StructuredDataMessage, the ID from that message will be used instead.

includeMDC

boolean

Indicates whether data from the https://logging.apache.org/log4j/2.x/manual/thread-context.html map will be included in the RFC 5424 Syslog record (defaults to true)

loggerFields

KeyValuePair[]

Allows arbitrary https://logging.apache.org/log4j/2.x/manual/thread-context.html map entries. To use, include a LoggerFields nested element, containing one or more KeyValuePair elements. Each KeyValuePair must have key and value attributes associating them with a thread context map entry. The value attribute can be an arbitrary Pattern Layout pattern.

mdcExcludes

String

A comma-separated list of https://logging.apache.org/log4j/2.x/manual/thread-context.html map (aka, MDC) keys that should be excluded. This is mutually exclusive with mdcIncludes. This attribute only applies to RFC 5424 Syslog records.

mdcIncludes

String

A comma-separated list of https://logging.apache.org/log4j/2.x/manual/thread-context.html map (aka, MDC) keys that should be included. Any keys in the thread context map not found in the list will be excluded. This option is mutually exclusive with mdcExcludes. This attribute only applies to RFC 5424 Syslog records.

mdcId

String

The ID to use for the https://logging.apache.org/log4j/2.x/manual/thread-context.html map (aka, MDC) Structured Data Element. It defaults to mdc. This attribute only applies to RFC 5424 Syslog records.

mdcPrefix

String

A string to be prepended to each https://logging.apache.org/log4j/2.x/manual/thread-context.html map (aka, MDC) key to distinguish it from event attributes. It defaults to mdc:. This attribute only applies to RFC 5424 Syslog records.

mdcRequired

String

A comma-separated list of ThreadContext map (aka, MDC) keys that must be present. If a key is not present, a LoggingException will be thrown. This attribute only applies to RFC 5424 Syslog records.

messageId

String

The default value to be used in the MSGID field of RFC 5424 Syslog records

newLine

boolean

If true, a \n character will be appended to the end of the Syslog record (defaults to false)

newLineEscape

String

The string that should be used to replace newlines within the message text

RFC 5424 Layout has specialized handling for StructuredDataMessages. By combining two, users can have complete control on how their message is encoded in a way compliant with RFC 5424, while RFC 5424 Layout will make sure the rest of the information attached to the log event is properly injected.

Syslog Layout

SyslogLayout encodes log events according to the syslog message format described in RFC 3164. This matches the same format used by Log4j 1.

RFC 3164, implemented by Syslog Layout, is obsoleted by RFC 5424, implemented by RFC 5424 Layout.

Syslog Layout is configured with the following parameters:

Parameter Type Description

charset

String

The character encoding (defaults to UTF-8)

facility

String

The name of Facility as described in RFC 5424. The matching is case-insensitive. It defaults to LOCAL0.

newLine

boolean

If true, a \n character will be appended to the end of the Syslog record (defaults to false)

newLineEscape

String

The string that should be used to replace newlines within the message text

Extending

Layouts are plugins implementing the Layout interface. This section will guide you on how to create custom ones.

While the predefined layout collection should address most common use cases, you might find yourself needing to implement a custom one. If this is the case, we really appreciate it if you can share your use case in a user support channel.

Plugin preliminaries

Log4j plugin system is the de facto extension mechanism embraced by various Log4j components. Plugins make it possible for extensible components to receive feature implementations without any explicit links in between. It is analogous to a dependency injection framework, but curated for Log4j-specific needs.

In a nutshell, you annotate your classes with @Plugin and their (static) factory methods with @PluginFactory. Last, you inform the Log4j plugin system to discover these custom classes. This is done using running the PluginProcessor annotation processor while building your project. Refer to Plugins for details.

Extending layouts

Layouts are plugins implementing the Layout interface. If your layout is a String-based one, we recommend you to extend your plugin class from AbstractStringLayout, which contains convenience for some of the boilerplate code shared by String-based layouts. You can check out following files for examples: