blob: 1a1918c5dc368ae9fd67b2f7d1cd5d15c3984844 [file] [log] [blame]
<!DOCTYPE html>
<!--
| Generated by Apache Maven Doxia Site Renderer 1.9.1 from src/site/asciidoc/manual/json-template-layout.adoc.vm at 2021-03-07
| Rendered using Apache Maven Fluido Skin 1.8
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="generator" content="Apache Maven Doxia Site Renderer 1.9.1" />
<title>Log4j &#x2013; </title>
<link rel="stylesheet" href="../css/apache-maven-fluido-1.8.min.css" />
<link rel="stylesheet" href="../css/site.css" />
<link rel="stylesheet" href="../css/print.css" media="print" />
<script src="../js/apache-maven-fluido-1.8.min.js"></script>
</head>
<body class="topBarDisabled">
<div class="container-fluid">
<header>
<div id="banner">
<div class="pull-left"><a href="http://logging.apache.org" id="bannerLeft"><img src="../images/ls-logo.jpg" alt=""/></a></div>
<div class="pull-right"><a href="http://logging.apache.org/log4j/2.x" id="bannerRight"><img src="../images/logo.png" alt=""/></a></div>
<div class="clear"><hr/></div>
</div>
<div id="breadcrumbs">
<ul class="breadcrumb">
<li id="publishDate">Last Published: 2021-03-07<span class="divider">|</span>
</li>
<li id="projectVersion">Version: 2.14.1</li>
<li class="pull-right"><span class="divider">|</span>
<a href="https://github.com/apache/logging-log4j2" class="externalLink" title="GitHub">GitHub</a></li>
<li class="pull-right"><span class="divider">|</span>
<a href="https://analysis.apache.org/dashboard/index/org.apache.logging.log4j:log4j" class="externalLink" title="Sonar">Sonar</a></li>
<li class="pull-right"><span class="divider">|</span>
<a href="../../../" title="Logging Services">Logging Services</a></li>
<li class="pull-right"><span class="divider">|</span>
<a href="https://www.apache.org/" class="externalLink" title="Apache">Apache</a></li>
<li class="pull-right"><a href="https://cwiki.apache.org/confluence/display/LOGGING/Log4j" class="externalLink" title="Logging Wiki">Logging Wiki</a></li>
</ul>
</div>
</header>
<div class="row-fluid">
<header id="leftColumn" class="span2">
<nav class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/home.png" alt="Apache Log4j™ 2" border="0"/> Apache Log4j™ 2</li>
<li><a href="../index.html" title="About"><span class="none"></span>About</a></li>
<li><a href="../download.html" title="Download"><span class="none"></span>Download</a></li>
<li><a href="../javadoc.html" title="Javadoc"><span class="icon-chevron-right"></span>Javadoc</a></li>
<li><a href="../maven-artifacts.html" title="Maven, Ivy, Gradle Artifacts"><span class="icon-chevron-right"></span>Maven, Ivy, Gradle Artifacts</a></li>
<li><a href="../runtime-dependencies.html" title="Runtime Dependencies"><span class="none"></span>Runtime Dependencies</a></li>
<li><a href="../changelog.html" title="Changelog"><span class="none"></span>Changelog</a></li>
<li><a href="../faq.html" title="FAQ"><span class="none"></span>FAQ</a></li>
<li><a href="../performance.html" title="Performance"><span class="icon-chevron-right"></span>Performance</a></li>
<li><a href="../articles.html" title="Articles and Tutorials"><span class="none"></span>Articles and Tutorials</a></li>
<li><a href="../security.html" title="Security"><span class="none"></span>Security</a></li>
<li><a href="../support.html" title="Support"><span class="none"></span>Support</a></li>
<li><a href="../thanks.html" title="Thanks"><span class="none"></span>Thanks</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/pencil.png" alt="For Contributors" border="0"/> For Contributors</li>
<li><a href="../build.html" title="Building Log4j from Source"><span class="none"></span>Building Log4j from Source</a></li>
<li><a href="../guidelines.html" title="Guidelines"><span class="none"></span>Guidelines</a></li>
<li><a href="../javastyle.html" title="Style Guide"><span class="none"></span>Style Guide</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/book.png" alt="Manual" border="0"/> Manual</li>
<li><a href="../manual/index.html" title="Introduction"><span class="none"></span>Introduction</a></li>
<li><a href="../manual/architecture.html" title="Architecture"><span class="none"></span>Architecture</a></li>
<li><a href="../manual/compatibility.html" title="Log4j 1.x Compatibility"><span class="none"></span>Log4j 1.x Compatibility</a></li>
<li><a href="../manual/migration.html" title="Log4j 1.x Migration"><span class="none"></span>Log4j 1.x Migration</a></li>
<li><a href="../manual/api.html" title="Java API"><span class="icon-chevron-right"></span>Java API</a></li>
<li><a href="../manual/scala-api.html" title="Scala API"><span class="none"></span>Scala API</a></li>
<li><a href="../manual/configuration.html" title="Configuration"><span class="icon-chevron-right"></span>Configuration</a></li>
<li><a href="../manual/usage.html" title="Usage"><span class="icon-chevron-right"></span>Usage</a></li>
<li><a href="../manual/webapp.html" title="Web Applications and JSPs"><span class="icon-chevron-right"></span>Web Applications and JSPs</a></li>
<li><a href="../manual/lookups.html" title="Lookups"><span class="icon-chevron-right"></span>Lookups</a></li>
<li><a href="../manual/appenders.html" title="Appenders"><span class="icon-chevron-right"></span>Appenders</a></li>
<li><a href="../manual/layouts.html" title="Layouts"><span class="icon-chevron-down"></span>Layouts</a>
<ul class="nav nav-list">
<li><a href="../manual/layouts.html#CSVLayouts" title="CSV"><span class="none"></span>CSV</a></li>
<li><a href="../manual/layouts.html#GELFLayout" title="GELF"><span class="none"></span>GELF</a></li>
<li><a href="../manual/layouts.html#HTMLLayout" title="HTML"><span class="none"></span>HTML</a></li>
<li><a href="../manual/layouts.html#JSONLayout" title="JSON"><span class="none"></span>JSON</a></li>
<li class="active"><a href="#"><span class="none"></span>JSON Template</a></li>
<li><a href="../manual/layouts.html#PatternLayout" title="Pattern"><span class="none"></span>Pattern</a></li>
<li><a href="../manual/layouts.html#RFC5424Layout" title="RFC-5424"><span class="none"></span>RFC-5424</a></li>
<li><a href="../manual/layouts.html#SerializedLayout" title="Serialized"><span class="none"></span>Serialized</a></li>
<li><a href="../manual/layouts.html#SyslogLayout" title="Syslog"><span class="none"></span>Syslog</a></li>
<li><a href="../manual/layouts.html#XMLLayout" title="XML"><span class="none"></span>XML</a></li>
<li><a href="../manual/layouts.html#YamlLayout" title="YAML"><span class="none"></span>YAML</a></li>
<li><a href="../manual/layouts.html#LocationInformation" title="Location Information"><span class="none"></span>Location Information</a></li>
</ul></li>
<li><a href="../manual/filters.html" title="Filters"><span class="icon-chevron-right"></span>Filters</a></li>
<li><a href="../manual/async.html" title="Async Loggers"><span class="icon-chevron-right"></span>Async Loggers</a></li>
<li><a href="../manual/garbagefree.html" title="Garbage-free Logging"><span class="icon-chevron-right"></span>Garbage-free Logging</a></li>
<li><a href="../manual/jmx.html" title="JMX"><span class="none"></span>JMX</a></li>
<li><a href="../manual/logsep.html" title="Logging Separation"><span class="none"></span>Logging Separation</a></li>
<li><a href="../manual/extending.html" title="Extending Log4j"><span class="icon-chevron-right"></span>Extending Log4j</a></li>
<li><a href="../manual/plugins.html" title="Plugins"><span class="icon-chevron-right"></span>Plugins</a></li>
<li><a href="../manual/customconfig.html" title="Programmatic Log4j Configuration"><span class="icon-chevron-right"></span>Programmatic Log4j Configuration</a></li>
<li><a href="../manual/customloglevels.html" title="Custom Log Levels"><span class="icon-chevron-right"></span>Custom Log Levels</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/tag.png" alt="Related Projects" border="0"/> Related Projects</li>
<li><a href="http://logging.apache.org/log4j/scala/index.html" class="externalLink" title="Log4j-Scala"><span class="none"></span>Log4j-Scala</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/link.png" alt="Legacy Sites" border="0"/> Legacy Sites</li>
<li><a href="http://logging.apache.org/log4j/1.2/" class="externalLink" title="Log4j 1.2 - End of Life"><span class="none"></span>Log4j 1.2 - End of Life</a></li>
<li><a href="http://logging.apache.org/log4j/log4j-2.3/" class="externalLink" title="Log4j 2.3 - Java 6"><span class="none"></span>Log4j 2.3 - Java 6</a></li>
<li><a href="http://logging.apache.org/log4j/log4j-2.12.1" class="externalLink" title="Log4j 2.12.1 - Java 7"><span class="none"></span>Log4j 2.12.1 - Java 7</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/cog.png" alt="Components" border="0"/> Components</li>
<li><a href="../log4j-api/index.html" title="API"><span class="none"></span>API</a></li>
<li><a href="../log4j-core/index.html" title="Implementation"><span class="none"></span>Implementation</a></li>
<li><a href="../log4j-jcl/index.html" title="Commons Logging Bridge"><span class="none"></span>Commons Logging Bridge</a></li>
<li><a href="../log4j-1.2-api/index.html" title="Log4j 1.2 API"><span class="none"></span>Log4j 1.2 API</a></li>
<li><a href="../log4j-slf4j-impl/index.html" title="SLF4J Binding"><span class="none"></span>SLF4J Binding</a></li>
<li><a href="../log4j-jul/index.html" title="JUL Adapter"><span class="none"></span>JUL Adapter</a></li>
<li><a href="../log4j-jpl/index.html" title="JDK Platform Logger"><span class="none"></span>JDK Platform Logger</a></li>
<li><a href="../log4j-to-slf4j/index.html" title="Log4j 2 to SLF4J Adapter"><span class="none"></span>Log4j 2 to SLF4J Adapter</a></li>
<li><a href="../log4j-flume-ng/index.html" title="Apache Flume Appender"><span class="none"></span>Apache Flume Appender</a></li>
<li><a href="../log4j-taglib/index.html" title="Log4j Tag Library"><span class="none"></span>Log4j Tag Library</a></li>
<li><a href="../log4j-jmx-gui/index.html" title="Log4j JMX GUI"><span class="none"></span>Log4j JMX GUI</a></li>
<li><a href="../log4j-web/index.html" title="Log4j Web Application Support"><span class="none"></span>Log4j Web Application Support</a></li>
<li><a href="../log4j-appserver/index.html" title="Log4j Application Server Integration"><span class="none"></span>Log4j Application Server Integration</a></li>
<li><a href="../log4j-couchdb/index.html" title="Log4j CouchDB appender"><span class="none"></span>Log4j CouchDB appender</a></li>
<li><a href="../log4j-mongodb3/index.html" title="Log4j MongoDB3 appender"><span class="none"></span>Log4j MongoDB3 appender</a></li>
<li><a href="../log4j-mongodb4/index.html" title="Log4j MongoDB4 appender"><span class="none"></span>Log4j MongoDB4 appender</a></li>
<li><a href="../log4j-cassandra/index.html" title="Log4j Cassandra appender"><span class="none"></span>Log4j Cassandra appender</a></li>
<li><a href="../log4j-iostreams/index.html" title="Log4j IO Streams"><span class="none"></span>Log4j IO Streams</a></li>
<li><a href="../log4j-liquibase/index.html" title="Log4j Liquibase Binding"><span class="none"></span>Log4j Liquibase Binding</a></li>
<li><a href="../log4j-docker/index.html" title="Log4j Docker Support"><span class="none"></span>Log4j Docker Support</a></li>
<li><a href="../log4j-spring-cloud-config/log4j-spring-cloud-config-client/index.html" title="Log4j Spring Cloud Config Client"><span class="none"></span>Log4j Spring Cloud Config Client</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/info.png" alt="Project Information" border="0"/> Project Information</li>
<li><a href="../dependency-convergence.html" title="Dependency Convergence"><span class="none"></span>Dependency Convergence</a></li>
<li><a href="../dependency-management.html" title="Dependency Management"><span class="none"></span>Dependency Management</a></li>
<li><a href="../team-list.html" title="Project Team"><span class="none"></span>Project Team</a></li>
<li><a href="../mail-lists.html" title="Mailing Lists"><span class="none"></span>Mailing Lists</a></li>
<li><a href="../issue-tracking.html" title="Issue Tracking"><span class="none"></span>Issue Tracking</a></li>
<li><a href="../license.html" title="Project License"><span class="none"></span>Project License</a></li>
<li><a href="../source-repository.html" title="Source Repository"><span class="none"></span>Source Repository</a></li>
<li><a href="../project-summary.html" title="Project Summary"><span class="none"></span>Project Summary</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/layers.png" alt="Project Reports" border="0"/> Project Reports</li>
<li><a href="../changes-report.html" title="Changes Report"><span class="none"></span>Changes Report</a></li>
<li><a href="../jira-report.html" title="JIRA Report"><span class="none"></span>JIRA Report</a></li>
<li><a href="../rat-report.html" title="RAT Report"><span class="none"></span>RAT Report</a></li>
</ul>
</nav>
<div class="well sidebar-nav">
<hr />
<div id="poweredBy">
<div class="clear"></div>
<div class="clear"></div>
<div class="clear"></div>
<a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /></a>
</div>
</div>
</header>
<main id="bodyColumn" class="span10" >
<h1>JSON Template Layout</h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p><code>JsonTemplateLayout</code> is a customizable, efficient, and garbage-free JSON
emitting layout. It encodes <code>LogEvent</code>s according to the structure described
by the JSON template provided. In a nutshell, it shines with its</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Customizable JSON structure (see <code>eventTemplate[Uri]</code> and
<code>stackTraceElementTemplate[Uri]</code> parameters)</p>
</li>
<li>
<p>Customizable timestamp formatting (see <code>timestamp</code> parameter)</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="usage">Usage</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Adding <code>log4j-layout-template-json</code> artifact to your list of dependencies is
enough to enable access to <code>JsonTemplateLayout</code> in your Log4j configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.apache.logging.log4j&lt;/groupId&gt;
&lt;artifactId&gt;log4j-layout-template-json&lt;/artifactId&gt;
&lt;version&gt;2.14.1&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>For instance, given the following JSON template modelling
<a href="https://github.com/logstash/log4j-jsonevent-layout">the official Logstash
<code>JSONEventLayoutV1</code></a> (accessible via <code>classpath:LogstashJsonEventLayoutV1.json</code>)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"mdc": {
"$resolver": "mdc"
},
"exception": {
"exception_class": {
"$resolver": "exception",
"field": "className"
},
"exception_message": {
"$resolver": "exception",
"field": "message"
},
"stacktrace": {
"$resolver": "exception",
"field": "stackTrace",
"stackTrace": {
"stringified": true
}
}
},
"line_number": {
"$resolver": "source",
"field": "lineNumber"
},
"class": {
"$resolver": "source",
"field": "className"
},
"@version": 1,
"source_host": "${hostName}",
"message": {
"$resolver": "message",
"stringified": true
},
"thread_name": {
"$resolver": "thread",
"field": "name"
},
"@timestamp": {
"$resolver": "timestamp"
},
"level": {
"$resolver": "level",
"field": "name"
},
"file": {
"$resolver": "source",
"field": "fileName"
},
"method": {
"$resolver": "source",
"field": "methodName"
},
"logger_name": {
"$resolver": "logger",
"field": "name"
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>in combination with the below <code>log4j2.xml</code> configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;JsonTemplateLayout eventTemplateUri="classpath:LogstashJsonEventLayoutV1.json"/&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>or with the below <code>log4j2.properties</code> configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">appender.console.json.type = JsonTemplateLayout
appender.console.json.eventTemplateUri = classpath:LogstashJsonEventLayoutV1.json</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>JsonTemplateLayout</code> emits JSON strings as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"exception": {
"exception_class": "java.lang.RuntimeException",
"exception_message": "test",
"stacktrace": "java.lang.RuntimeException: test\n\tat org.apache.logging.log4j.JsonTemplateLayoutDemo.main(JsonTemplateLayoutDemo.java:11)\n"
},
"line_number": 12,
"class": "org.apache.logging.log4j.JsonTemplateLayoutDemo",
"@version": 1,
"source_host": "varlik",
"message": "Hello, error!",
"thread_name": "main",
"@timestamp": "2017-05-25T19:56:23.370+02:00",
"level": "ERROR",
"file": "JsonTemplateLayoutDemo.java",
"method": "main",
"logger_name": "org.apache.logging.log4j.JsonTemplateLayoutDemo"
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="layout-config">Layout Configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p><code>JsonTemplateLayout</code> is configured with the following parameters:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 1. <code>JsonTemplateLayout</code> parameters</caption>
<colgroup>
<col style="width: 16.6666%;"/>
<col style="width: 16.6666%;"/>
<col style="width: 66.6668%;"/>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Parameter Name</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Type</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Description</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>charset</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Charset</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Charset</code> used for <code>String</code> encoding</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>locationInfoEnabled</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>boolean</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">toggles access to the <code>LogEvent</code> source; file name, line number, etc.
(defaults to <code>false</code> set by <code>log4j.layout.jsonTemplate.locationInfoEnabled</code>
property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>stackTraceEnabled</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>boolean</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">toggles access to the stack traces (defaults to <code>true</code> set by
<code>log4j.layout.jsonTemplate.stackTraceEnabled</code> property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>eventTemplate</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">inline JSON template for rendering <code>LogEvent</code>s (has priority over
<code>eventTemplateUri</code>, defaults to <code>null</code> set by
<code>log4j.layout.jsonTemplate.eventTemplate</code> property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>eventTemplateUri</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">URI pointing to the JSON template for rendering <code>LogEvent</code>s (defaults to
<code>classpath:EcsLayout.json</code> set by <code>log4j.layout.jsonTemplate.eventTemplateUri</code>
property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>eventTemplateRootObjectKey</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">if given, puts the event template into a JSON object composed of a single
member with the given key (defaults to <code>null</code> set by
<code>log4j.layout.jsonTemplate.eventTemplateRootObjectKey</code>
property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>eventTemplateAdditionalFields</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>EventTemplateAdditionalField[]</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">additional key-value pairs appended to the root of the event template</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>stackTraceElementTemplate</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">inline JSON template for rendering <code>StackTraceElement</code>s (has priority over
<code>stackTraceElementTemplateUri</code>, defaults to <code>null</code> set by
<code>log4j.layout.jsonTemplate.stackTraceElementTemplate</code> property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>stackTraceElementTemplateUri</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">JSON template for rendering <code>StackTraceElement</code>s (defaults to
<code>classpath:StackTraceElementLayout.json</code> set by
<code>log4j.layout.jsonTemplate.stackTraceElementTemplateUri</code> property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>eventDelimiter</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">delimiter used for separating emitted <code>LogEvent</code>s (defaults to
<code>System.lineSeparator()</code> set by <code>log4j.layout.jsonTemplate.eventDelimiter</code>
property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>nullEventDelimiterEnabled</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>boolean</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">append <code>\0</code> (<code>null</code>) character to the end of every emitted <code>eventDelimiter</code>
(defaults to <code>false</code> set by
<code>log4j.layout.jsonTemplate.nullEventDelimiterEnabled</code> property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>maxStringLength</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>int</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">truncate string values longer than the specified limit (defaults to 16384 set
by <code>log4j.layout.jsonTemplate.maxStringLength</code> property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>truncatedStringSuffix</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">suffix to append to strings truncated due to exceeding <code>maxStringLength</code>
(defaults to <code></code> set by <code>log4j.layout.jsonTemplate.truncatedStringSuffix</code>
property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>recyclerFactory</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RecyclerFactory</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">recycling strategy that can either be <code>dummy</code>, <code>threadLocal</code>, or <code>queue</code>
(set by <code>log4j.layout.jsonTemplate.recyclerFactory</code> property)</p></td>
</tr>
</tbody>
</table>
<div class="sect2">
<h3 id="additional-event-template-fields">Additonal event template fields</h3>
<div class="paragraph">
<p>Additional event template fields are a convenient short-cut to add custom fields
to a template or override the existing ones. Following configuration overrides
the <code>host</code> field of the <code>GelfLayout.json</code> template and adds two new custom
fields:</p>
</div>
<div class="listingblock">
<div class="title">XML configuration with additional fields</div>
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;JsonTemplateLayout eventTemplateUri="classpath:GelfLayout.json"&gt;
&lt;EventTemplateAdditionalField key="host" value="www.apache.org"/&gt;
&lt;EventTemplateAdditionalField key="_serviceName" value="auth-service"/&gt;
&lt;EventTemplateAdditionalField key="_containerId" value="6ede3f0ca7d9"/&gt;
&lt;/JsonTemplateLayout&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The default <code>format</code> for the added new fields are <code>String</code>.
One can also provide JSON-formatted additional fields:</p>
</div>
<div class="listingblock">
<div class="title">XML-formatted configuration with JSON-formatted additional fields</div>
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;JsonTemplateLayout eventTemplateUri="classpath:GelfLayout.json"&gt;
&lt;EventTemplateAdditionalField
key="marker"
format="JSON"
value='{"$resolver": "marker", "field": "name"}'/&gt;
&lt;EventTemplateAdditionalField
key="aNumber"
format="JSON"
value="1"/&gt;
&lt;EventTemplateAdditionalField
key="aList"
format="JSON"
value='[1, 2, "three"]'/&gt;
&lt;/JsonTemplateLayout&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Additional event template fields can very well be introduced using properties-,
YAML-, and JSON-formatted configurations:</p>
</div>
<div class="listingblock">
<div class="title">Properties-formatted configuration with JSON-formatted additional fields</div>
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">appender.console.layout.type = JsonTemplateLayout
appender.console.layout.eventTemplateUri = classpath:GelfLayout.json
appender.console.layout.eventTemplateAdditionalField[0].type = EventTemplateAdditionalField
appender.console.layout.eventTemplateAdditionalField[0].key = marker
appender.console.layout.eventTemplateAdditionalField[0].value = {"$resolver": "marker", "field": "name"}
appender.console.layout.eventTemplateAdditionalField[0].format = JSON
appender.console.layout.eventTemplateAdditionalField[1].type = EventTemplateAdditionalField
appender.console.layout.eventTemplateAdditionalField[1].key = aNumber
appender.console.layout.eventTemplateAdditionalField[1].value = 1
appender.console.layout.eventTemplateAdditionalField[1].format = JSON
appender.console.layout.eventTemplateAdditionalField[2].type = EventTemplateAdditionalField
appender.console.layout.eventTemplateAdditionalField[2].key = aList
appender.console.layout.eventTemplateAdditionalField[2].value = [1, 2, "three"]
appender.console.layout.eventTemplateAdditionalField[2].format = JSON</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">YAML-formatted configuration with JSON-formatted additional fields</div>
<div class="content">
<pre class="highlight"><code class="language-yaml" data-lang="yaml">JsonTemplateLayout:
eventTemplateAdditionalField:
- key: "marker"
value: '{"$resolver": "marker", "field": "name"}'
format: "JSON"
- key: "aNumber"
value: "1"
format: "JSON"
- key: "aList"
value: '[1, 2, "three"]'
format: "JSON"</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">JSON-formatted configuration with JSON-formatted additional fields</div>
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"JsonTemplateLayout": {
"eventTemplateAdditionalField": [
{
"key": "marker",
"value": "{\"$resolver\": \"marker\", \"field\": \"name\"}",
"format": "JSON"
},
{
"key": "aNumber",
"value": "1",
"format": "JSON"
},
{
"key": "aList",
"value": "[1, 2, \"three\"]",
"format": "JSON"
}
]
}
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="recycling-strategy">Recycling strategy</h3>
<div class="paragraph">
<p><code>RecyclerFactory</code> plays a crucial role for determining the memory footprint of
the layout. Template resolvers employ it to create recyclers for objects that
they can reuse. The function of each <code>RecyclerFactory</code> and when one should
prefer one over another is explained below:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>dummy</code> performs no recycling, hence each recycling attempt will result in a
new instance. This will obviously create a load on the garbage-collector. It
is a good choice for applications with low and medium log rate.</p>
</li>
<li>
<p><code>threadLocal</code> performs the best, since every instance is stored in
<code>ThreadLocal</code>s and accessed without any synchronization cost. Though this
might not be a desirable option for applications running with hundreds of
threads or more, e.g., a web servlet.</p>
</li>
<li>
<p><code>queue</code> is the best of both worlds. It allows recycling of objects up to a
certain number (<code>capacity</code>). When this limit is exceeded due to excessive
concurrent load (e.g., <code>capacity</code> is 50 but there are 51 threads concurrently
trying to log), it starts allocating. <code>queue</code> is a good strategy where
<code>threadLocal</code> is not desirable.</p>
<div class="paragraph">
<p><code>queue</code> also accepts optional <code>supplier</code> (of type <code>java.util.Queue</code>, defaults to
<code>org.jctools.queues.MpmcArrayQueue.new</code> if JCTools is in the classpath;
otherwise <code>java.util.concurrent.ArrayBlockingQueue.new</code>) and <code>capacity</code> (of
type <code>int</code>, defaults to <code>max(8,2*cpuCount+1)</code>) parameters:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>queue:supplier=org.jctools.queues.MpmcArrayQueue.new
queue:capacity=10
queue:supplier=java.util.concurrent.ArrayBlockingQueue.new,capacity=50</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The default <code>RecyclerFactory</code> is <code>threadLocal</code>, if
<code>log4j2.enable.threadlocals=true</code>; otherwise, <code>queue</code>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="template-config">Template Configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Templates are configured by means of the following <code>JsonTemplateLayout</code>
parameters:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>eventTemplate[Uri]</code> (for serializing <code>LogEvent</code>s)</p>
</li>
<li>
<p><code>stackTraceElementTemplate[Uri]</code> (for serializing <code>StackStraceElement</code>s)</p>
</li>
<li>
<p><code>eventTemplateAdditionalFields</code> (for extending the used event template)</p>
</li>
</ul>
</div>
<div class="sect2">
<h3 id="event-templates">Event Templates</h3>
<div class="paragraph">
<p><code>eventTemplate[Uri]</code> describes the JSON structure <code>JsonTemplateLayout</code> uses to
serialize <code>LogEvent</code>s. The default configuration (accessible by
<code>log4j.layout.jsonTemplate.eventTemplate[Uri]</code> property) is set to
<code>classpath:EcsLayout.json</code> provided by the <code>log4j-layout-template-json</code>
artifact:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"@timestamp": {
"$resolver": "timestamp",
"pattern": {
"format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"timeZone": "UTC"
}
},
"log.level": {
"$resolver": "level",
"field": "name"
},
"message": {
"$resolver": "message",
"stringified": true
},
"process.thread.name": {
"$resolver": "thread",
"field": "name"
},
"log.logger": {
"$resolver": "logger",
"field": "name"
},
"labels": {
"$resolver": "mdc",
"flatten": true,
"stringified": true
},
"tags": {
"$resolver": "ndc"
},
"error.type": {
"$resolver": "exception",
"field": "className"
},
"error.message": {
"$resolver": "exception",
"field": "message"
},
"error.stack_trace": {
"$resolver": "exception",
"field": "stackTrace",
"stackTrace": {
"stringified": true
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>log4j-layout-template-json</code> artifact contains the following predefined event
templates:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://github.com/apache/logging-log4j2/tree/master/log4j-layout-template-json/src/main/resources/EcsLayout.json"><code>EcsLayout.json</code></a>
described by <a href="https://www.elastic.co/guide/en/ecs/current/ecs-reference.html">the Elastic Common Schema (ECS) specification</a></p>
</li>
<li>
<p><a href="https://github.com/apache/logging-log4j2/tree/master/log4j-layout-template-json/src/main/resources/LogstashJsonEventLayoutV1.json"><code>LogstashJsonEventLayoutV1.json</code></a>
described in <a href="https://github.com/logstash/log4j-jsonevent-layout">Logstash
<code>json_event</code> pattern for log4j</a></p>
</li>
<li>
<p><a href="https://github.com/apache/logging-log4j2/tree/master/log4j-layout-template-json/src/main/resources/GelfLayout.json"><code>GelfLayout.json</code></a>
described by <a href="https://docs.graylog.org/en/3.1/pages/gelf.html#gelf-payload-specification">the
Graylog Extended Log Format (GELF) payload specification</a> with additional
<code>_thread</code> and <code>_logger</code> fields. (Here it is advised to override the obligatory
<code>host</code> field with a user provided constant via <code>eventTemplateAdditionalFields</code>
to avoid <code>hostName</code> property lookup at runtime, which incurs an extra cost.)</p>
</li>
<li>
<p><a href="https://github.com/apache/logging-log4j2/tree/master/log4j-layout-template-json/src/main/resources/JsonLayout.json"><code>JsonLayout.json</code></a>
providing the exact JSON structure generated by <a href="layouts.html#JSONLayout"><code>JsonLayout</code></a>
with the exception of <code>thrown</code> field. (<code>JsonLayout</code> serializes the <code>Throwable</code>
as is via Jackson <code>ObjectMapper</code>, whereas <code>JsonLayout.json</code> template of
<code>JsonTemplateLayout</code> employs the <code>StackTraceElementLayout.json</code> template
for stack traces to generate a document-store-friendly flat structure.)</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="event-template-resolvers">Event Template Resolvers</h4>
<div class="sect4">
<h5 id="event-template-resolver-endOfBatch"><code>endOfBatch</code></h5>
<div class="paragraph">
<p>Resolves <code>logEvent.isEndOfBatch()</code> boolean flag:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "endOfBatch"
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-exception"><code>exception</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = field , [ stringified ] , [ stackTrace ]
field = "field" -&gt; ( "className" \| "message" \| "stackTrace" )
stackTrace = "stackTrace" -&gt; stringified
stringified = "stringified" -&gt; ( boolean \| truncation )
truncation = "truncation" -&gt; (
[ suffix ]
, [ pointMatcherStrings ]
, [ pointMatcherRegexes ]
)
suffix = "suffix" -&gt; string
pointMatcherStrings = "pointMatcherStrings" -&gt; string[]
pointMatcherRegexes = "pointMatcherRegexes" -&gt; string[]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves fields of the <code>Throwable</code> returned by <code>logEvent.getThrown()</code>.</p>
</div>
<div class="paragraph">
<p><code>stringified</code> is set to <code>false</code> by default. <code>stringified</code> at the root level is
<strong>deprecated</strong> in favor of <code>stackTrace.stringified</code>, which has precedence if both
are provided.</p>
</div>
<div class="paragraph">
<p><code>pointMatcherStrings</code> and <code>pointMatcherRegexes</code> enable the truncation of
stringified stack traces after the given matching point. If both parameters are
provided, <code>pointMatcherStrings</code> will be checked first.</p>
</div>
<div class="paragraph">
<p>If a stringified stack trace truncation takes place, it will be indicated with
<code>suffix</code>, which by default is set to the configured <code>truncatedStringSuffix</code> in
the layout, unless explicitly provided.</p>
</div>
<div class="paragraph">
<p>Note that this resolver is toggled by
<code>log4j.layout.jsonTemplate.stackTraceEnabled</code> property.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<div class="paragraph">
<p>Since <code>Throwable#getStackTrace()</code> clones the original <code>StackTraceElement[]</code>,
access to (and hence rendering of) stack traces are not garbage-free.</p>
</div>
<div class="paragraph">
<p>Each <code>pointMatcherRegexes</code> item triggers a <code>Pattern#matcher()</code> call, which is
not garbage-free either.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Resolve <code>logEvent.getThrown().getClass().getCanonicalName()</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "exception",
"field": "className"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the stack trace into a list of <code>StackTraceElement</code> objects:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "exception",
"field": "stackTrace"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the stack trace into a string field:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "exception",
"field": "stackTrace",
"stackTrace": {
"stringified": true
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the stack trace into a string field such that the content will be
truncated by the given point matcher:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "exception",
"field": "stackTrace",
"stackTrace": {
"stringified": {
"truncation": {
"suffix": "&gt;",
"pointMatcherStrings": ["at javax.servlet.http.HttpServlet.service"]
}
}
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-exceptionRootCause"><code>exceptionRootCause</code></h5>
<div class="paragraph">
<p>Resolves the fields of the innermost <code>Throwable</code> returned by
<code>logEvent.getThrown()</code>. Its syntax and garbage-footprint are identical to the
<a href="#event-template-exception"><code>exception</code></a> resolver.</p>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-level"><code>level</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = field , [ severity ]
field = "field" -&gt; ( "name" | "severity" )
severity = severity-field
severity-field = "field" -&gt; ( "keyword" | "code" )</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves the fields of the <code>logEvent.getLevel()</code>.</p>
</div>
<div class="paragraph">
<p>Resolve the level name:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "level",
"field": "name"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the <a href="https://en.wikipedia.org/wiki/Syslog#Severity_levels">Syslog severity</a>
keyword:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "level",
"field": "severity",
"severity": {
"field": "keyword"
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the <a href="https://en.wikipedia.org/wiki/Syslog#Severity_levels">Syslog severity</a>
code:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "level",
"field": "severity",
"severity": {
"field": "code"
}
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-logger"><code>logger</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = "field" -&gt; ( "name" | "fqcn" )</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves <code>logEvent.getLoggerFqcn()</code> and <code>logEvent.getLoggerName()</code>.</p>
</div>
<div class="paragraph">
<p>Resolve the logger name:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "logger",
"field": "name"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the logger&#8217;s fully qualified class name:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "logger",
"field": "fqcn"
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-main"><code>main</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = ( index | key )
index = "index" -&gt; number
key = "key" -&gt; string</code></pre>
</div>
</div>
<div class="paragraph">
<p>Performs <a href="lookups.html#AppMainArgsLookup">Main Argument Lookup</a> for the
given <code>index</code> or <code>key</code>.</p>
</div>
<div class="paragraph">
<p>Resolve the 1st <code>main()</code> method argument:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "main",
"index": 0
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the argument coming right after <code>--userId</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "main",
"key": "--userId"
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-map"><code>map</code></h5>
<div class="paragraph">
<p>Resolves <code>MapMessage</code>s. See <a href="#map-resolver-template">Map Resolver Template</a>
for details.</p>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-mdc"><code>mdc</code></h5>
<div class="paragraph">
<p>Resolves Mapped Diagnostic Context (MDC), aka. Thread Context Data. See
<a href="#map-resolver-template">Map Resolver Template</a> for details.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<div class="paragraph">
<p><code>log4j2.garbagefreeThreadContextMap</code> flag needs to be turned on to iterate
the map without allocations.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-message"><code>message</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = [ stringified ] , [ fallbackKey ]
stringified = "stringified" -&gt; boolean
fallbackKey = "fallbackKey" -&gt; string</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves <code>logEvent.getMessage()</code>.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<div class="paragraph">
<p>For simple string messages, the resolution is performed without allocations.
For <code>ObjectMessage</code>s and <code>MultiformatMessage</code>s, it depends.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Resolve the message into a string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "message",
"stringified": true
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the message such that if it is an <code>ObjectMessage</code> or a
<code>MultiformatMessage</code> with JSON support, its type (string, list, object, etc.)
will be retained:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "message"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Given the above configuration, a <code>SimpleMessage</code> will generate a <code>"sample log
message"</code>, whereas a <code>MapMessage</code> will generate a <code>{"action": "login",
"sessionId": "87asd97a"}</code>. Certain indexed log storage systems (e.g.,
<a href="https://www.elastic.co/elasticsearch/">Elasticsearch</a>) will not allow both values
to coexist due to type mismatch: one is a <code>string</code> while the other is an <code>object</code>.
Here one can use a <code>fallbackKey</code> to work around the problem:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "message",
"fallbackKey": "formattedMessage"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Using this configuration, a <code>SimpleMessage</code> will generate a
<code>{"formattedMessage": "sample log message"}</code> and a <code>MapMessage</code> will generate a
<code>{"action": "login", "sessionId": "87asd97a"}</code>. Note that both emitted JSONs are
of type <code>object</code> and have no type-conflicting fields.</p>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-messageParameter"><code>messageParameter</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = [ stringified ] , [ index ]
stringified = "stringified" -&gt; boolean
index = "index" -&gt; number</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves <code>logEvent.getMessage().getParameters()</code>.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<div class="paragraph">
<p>Regarding garbage footprint, <code>stringified</code> flag translates to
<code>String.valueOf(value)</code>, hence mind not-<code>String</code>-typed values. Further,
<code>logEvent.getMessage()</code> is expected to implement <code>ParameterVisitable</code> interface,
which is the case if <code>log4j2.enableThreadLocals</code> property set to true.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Resolve the message parameters into an array:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "messageParameter"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the string representation of all message parameters into an array:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "messageParameter",
"stringified": true
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the first message parameter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "messageParameter",
"index": 0
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the string representation of the first message parameter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "messageParameter",
"index": 0,
"stringified": true
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-ndc"><code>ndc</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = [ pattern ]
pattern = "pattern" -&gt; string</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves the Nested Diagnostic Context (NDC), aka. Thread Context Stack,
<code>String[]</code> returned by <code>logEvent.getContextStack()</code>.</p>
</div>
<div class="paragraph">
<p>Resolve all NDC values into a list:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "ndc"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve all NDC values matching with the <code>pattern</code> regex:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "ndc",
"pattern": "user(Role|Rank):\\w+"
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-pattern"><code>pattern</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = pattern , [ stackTraceEnabled ]
pattern = "pattern" -&gt; string
stackTraceEnabled = "stackTraceEnabled" -&gt; boolean</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolver delegating to <a href="layouts.html#PatternLayout"><code>PatternLayout</code></a>.</p>
</div>
<div class="paragraph">
<p>The default value of <code>stackTraceEnabled</code> is inherited from the parent
<code>JsonTemplateLayout</code>.</p>
</div>
<div class="paragraph">
<p>Resolve the string produced by <code>%p %c{1.} [%t] %X{userId} %X %m%ex</code> pattern:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "pattern",
"pattern": "%p %c{1.} [%t] %X{userId} %X %m%ex"
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-source"><code>source</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = "field" -&gt; (
"className" |
"fileName" |
"methodName" |
"lineNumber" )</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves the fields of the <code>StackTraceElement</code> returned by
<code>logEvent.getSource()</code>.</p>
</div>
<div class="paragraph">
<p>Note that this resolver is toggled by
<code>log4j.layout.jsonTemplate.locationInfoEnabled</code> property.</p>
</div>
<div class="paragraph">
<p>Resolve the line number:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "source",
"field": "lineNumber"
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-thread"><code>thread</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = "field" -&gt; ( "name" | "id" | "priority" )</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves <code>logEvent.getThreadId()</code>, <code>logEvent.getThreadName()</code>,
<code>logEvent.getThreadPriority()</code>.</p>
</div>
<div class="paragraph">
<p>Resolve the thread name:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "thread",
"field": "name"
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="event-template-resolver-timestamp"><code>timestamp</code></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = [ patternConfig | epochConfig ]
patternConfig = "pattern" -&gt; ( [ format ] , [ timeZone ] , [ locale ] )
format = "format" -&gt; string
timeZone = "timeZone" -&gt; string
locale = "locale" -&gt; (
language |
( language , "_" , country ) |
( language , "_" , country , "_" , variant )
)
epochConfig = "epoch" -&gt; ( unit , [ rounded ] )
unit = "unit" -&gt; (
"nanos" |
"millis" |
"secs" |
"millis.nanos" |
"secs.nanos" |
)
rounded = "rounded" -&gt; boolean</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolves <code>logEvent.getInstant()</code> in various forms.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 2. <code>timestamp</code> template resolver examples</caption>
<colgroup>
<col style="width: 71.4285%;"/>
<col style="width: 28.5715%;"/>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Configuration</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Output</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp"
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>2020-02-07T13:38:47.098+02:00</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp",
"pattern": {
"format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
"timeZone": "UTC",
"locale": "en_US"
}
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>2020-02-07T13:38:47.098Z</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp",
"epoch": {
"unit": "secs"
}
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>1581082727.982123456</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp",
"epoch": {
"unit": "secs",
"rounded": true
}
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>1581082727</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp",
"epoch": {
"unit": "secs.nanos"
}
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>982123456</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp",
"epoch": {
"unit": "millis"
}
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>1581082727982.123456</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp",
"epoch": {
"unit": "millis",
"rounded": true
}
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>1581082727982</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp",
"epoch": {
"unit": "millis.nanos"
}
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>123456</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "timestamp",
"epoch": {
"unit": "nanos"
}
}</code></pre>
</div>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>1581082727982123456</code></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="map-resolver-template">Map Resolver Template</h4>
<div class="paragraph">
<p><code>ReadOnlyStringMap</code> is Log4j&#8217;s <code>Map&lt;String, Object&gt;</code> equivalent with
garbage-free accessors and heavily employed throughout the code base. It is the
data structure backing both Mapped Diagnostic Context (MDC), aka. Thread Context
Data and <code>MapMessage</code> implementations. Hence template resolvers for both of
these are provided by a single backend: <code>ReadOnlyStringMapResolver</code>. Put another
way, both <code>mdc</code> and <code>map</code> resolvers support identical configuration, behaviour,
and garbage footprint, which are detailed below.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = singleAccess | multiAccess
singleAccess = key , [ stringified ]
key = "key" -&gt; string
stringified = "stringified" -&gt; boolean
multiAccess = [ pattern ] , [ flatten ] , [ stringified ]
pattern = "pattern" -&gt; string
flatten = "flatten" -&gt; ( boolean | flattenConfig )
flattenConfig = [ flattenPrefix ]
flattenPrefix = "prefix" -&gt; string</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>singleAccess</code> resolves a single field, whilst <code>multiAccess</code> resolves a
multitude of fields. If <code>flatten</code> is provided, <code>multiAccess</code> merges the fields
with the parent, otherwise creates a new JSON object containing the values.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<div class="paragraph">
<p>Regarding garbage footprint, <code>stringified</code> flag translates to
<code>String.valueOf(value)</code>, hence mind not-<code>String</code>-typed values.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><code>"$resolver"</code> is left out in the following examples, since it is to be
defined by the actual resolver, e.g., <code>map</code>, <code>mdc</code>.</p>
</div>
<div class="paragraph">
<p>Resolve the value of the field keyed with <code>userRole</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "…",
"key": "userRole"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve the string representation of the <code>userRank</code> field value:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "…",
"key": "userRank",
"stringified": true
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve all fields into an object:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "…"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Resolve all fields into an object such that values are converted to string:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "…",
"stringified": true
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Merge all fields whose keys are matching with the <code>user(Role|Rank)</code> regex into
the parent:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "…",
"flatten": true,
"pattern": "user(Role|Rank)"
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>After converting the corresponding field values to string, merge all fields to
parent such that keys are prefixed with <code>_</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"$resolver": "…",
"stringified": true,
"flatten": {
"prefix": "_"
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="stack-trace-element-templates">Stack Trace Element Templates</h3>
<div class="paragraph">
<p><code>stackTraceElement[Uri]</code> describes the JSON structure <code>JsonTemplateLayout</code> uses
to format <code>StackTraceElement</code>s. The default configuration (accessible by
<code>log4j.layout.jsonTemplate.stackTraceElementTemplate[Uri]</code> property) is set to
<code>classpath:StackTraceElementLayout.json</code> provided by the
<code>log4j-layout-template-json</code> artifact:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{
"class": {
"$resolver": "stackTraceElement",
"field": "className"
},
"method": {
"$resolver": "stackTraceElement",
"field": "methodName"
},
"file": {
"$resolver": "stackTraceElement",
"field": "fileName"
},
"line": {
"$resolver": "stackTraceElement",
"field": "lineNumber"
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The allowed template configuration syntax is as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>config = "field" -&gt; (
"className" |
"fileName" |
"methodName" |
"lineNumber" )</code></pre>
</div>
</div>
<div class="paragraph">
<p>All above accesses to <code>StackTraceElement</code> is garbage-free.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="features">Features</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Below is a feature comparison matrix between <code>JsonTemplateLayout</code> and
alternatives.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 3. Feature comparison matrix</caption>
<colgroup>
<col style="width: 42.8571%;"/>
<col style="width: 14.2857%;"/>
<col style="width: 14.2857%;"/>
<col style="width: 14.2857%;"/>
<col style="width: 14.2858%;"/>
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Feature</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>JsonTemplateLayout</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="layouts.html#JSONLayout"><code>JsonLayout</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="layouts.html#GELFLayout"><code>GelfLayout</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://github.com/elastic/java-ecs-logging/tree/master/log4j2-ecs-layout"><code>EcsLayout</code></a></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Java version</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Dependencies</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Jackson</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">None</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Schema customization?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Timestamp customization?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">(Almost) garbage-free?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Custom typed <code>Message</code> serialization?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">?<sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnote_1" title="View footnote.">1</a>]</sup></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Custom typed <code>MDC</code> value serialization?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Rendering stack traces as array?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Stack trace truncation?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">JSON pretty print?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Additional string fields?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Additional JSON fields?</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="faq">F.A.Q.</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="faq-lookups">Are lookups supported in templates?</h3>
<div class="paragraph">
<p>Yes, <a href="lookups.html">lookups</a> (e.g., <code>${java:version}</code>,
<code>${env:USER}</code>, <code>${date:MM-dd-yyyy}</code>) are supported in string
literals of templates. Though note that they are not garbage-free.</p>
</div>
</div>
<div class="sect2">
<h3 id="are_recursive_collections_supported">Are recursive collections supported?</h3>
<div class="paragraph">
<p>No. Consider a <code>Message</code> containing a recursive value as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">Object[] recursiveCollection = new Object[1];
recursiveCollection[0] = recursiveCollection;</code></pre>
</div>
</div>
<div class="paragraph">
<p>While the exact exception might vary, you will most like get a
<code>StackOverflowError</code> while trying to render <code>recursiveCollection</code> into a
<code>String</code>. Note that this is also the default behaviour for other Java standard
library methods, e.g., <code>Arrays.toString()</code>. Hence mind self references while
logging.</p>
</div>
</div>
<div class="sect2">
<h3 id="faq-garbage-free">Is <code>JsonTemplateLayout</code> garbage-free?</h3>
<div class="paragraph">
<p>Yes, if the garbage-free layout behaviour toggling properties
<code>log4j2.enableDirectEncoders</code> and <code>log4j2.garbagefreeThreadContextMap</code> are
enabled. Take into account the following caveats:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The configured <a href="#recycling-strategy">recycling strategy</a> might not be
garbage-free.</p>
</li>
<li>
<p>Since <code>Throwable#getStackTrace()</code> clones the original <code>StackTraceElement[]</code>,
access to (and hence rendering of) stack traces are not garbage-free.</p>
</li>
<li>
<p>Serialization of <code>MapMessage</code>s and <code>ObjectMessage</code>s are mostly
garbage-free except for certain types (e.g., <code>BigDecimal</code>, <code>BigInteger</code>,
<code>Collection</code>s with the exception of <code>List</code>).</p>
</li>
<li>
<p><a href="lookups.html">Lookups</a> (that is, <code>${&#8230;&#8203;}</code> variables) are not garbage-free.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Don&#8217;t forget to checkout <a href="#event-template-resolvers">the notes on garbage footprint of resolvers</a>
you employ in templates.</p>
</div>
</div>
</div>
</div>
<div id="footnotes">
<hr/>
<div class="footnote" id="_footnote_1">
<a href="#_footnoteref_1">1</a>. Only for <code>ObjectMessage</code>s and if Jackson is in the classpath.
</div>
</div>
</main>
</div>
</div>
<hr/>
<footer>
<div class="container-fluid">
<div class="row-fluid">
<p align="center">Copyright &copy; 1999-2021 <a class="external" href="http://www.apache.org">The Apache Software Foundation</a>. All Rights Reserved.<br>
Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, and the Apache Logging project logo are trademarks of The Apache Software Foundation.</p>
</div>
</div>
</footer>
</body>
</html>