You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2018/04/08 19:04:41 UTC

[4/5] logging-log4j2 git commit: LOG4J2-1802: Convert messages manual page to asciidoc

LOG4J2-1802: Convert messages manual page to asciidoc


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/c34fa7ef
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/c34fa7ef
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/c34fa7ef

Branch: refs/heads/master
Commit: c34fa7efaa75f41ecdbae5ca426c2529738f2d86
Parents: 56eb7a0
Author: Matt Sicker <bo...@gmail.com>
Authored: Sun Apr 8 13:59:27 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Sun Apr 8 13:59:27 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/messages.adoc | 333 ++++++++++++++++++++++++++++
 src/site/xdoc/manual/messages.xml      | 314 --------------------------
 2 files changed, 333 insertions(+), 314 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c34fa7ef/src/site/asciidoc/manual/messages.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/messages.adoc b/src/site/asciidoc/manual/messages.adoc
new file mode 100644
index 0000000..8c27dc3
--- /dev/null
+++ b/src/site/asciidoc/manual/messages.adoc
@@ -0,0 +1,333 @@
+////
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements. See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License. You may obtain a copy of the License at
+
+        https://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+////
+= Log4j 2 API
+Ralph Goers <rg...@apache.org>
+
+[#Messages]
+== Messages
+
+Although Log4j 2 provides Logger methods that accept Strings and
+Objects, all of these are ultimately captured in Message objects that
+are then associated with the log event. Applications are free to
+construct Messages of their own and pass them to the Logger. Although it
+may seem more expensive than passing the message format and parameters
+directly to the event, testing has shown that with modern JVMs the cost
+of creating and destroying events is minor, especially when complex
+tasks are encapsulated in the Message instead of the application. In
+addition, when using the methods that accept Strings and parameters, the
+underlying Message object will only be created if any configured global
+filters or the Logger's log level allow the message to be processed.
+
+Consider an application that has a Map object containing \{"Name" =
+"John Doe", "Address" = "123 Main St.", "Phone" = "(999) 555-1212"} and
+a User object that has a getId method that returns "jdoe". The developer
+would like to add an informational message that returns "User John Doe
+has logged in using id jdoe". The way this could be accomplished is by
+doing:
+
+[source,java]
+----
+logger.info("User {} has logged in using id {}", map.get("Name"), user.getId());
+----
+
+While there is nothing inherently wrong with this, as the complexity of
+the objects and desired output increases this technique becomes harder
+to use. As an alternative, using Messages allows:
+
+[source,java]
+----
+logger.info(new LoggedInMessage(map, user));
+----
+
+In this alternative the formatting is delegated to the `LoggedInMessage`
+object's `getFormattedMessage` method. Although in this alternative a new
+object is created, none of the methods on the objects passed to the
+`LoggedInMessage` are invoked until the `LoggedInMessage` is formatted. This
+is especially useful when an `Object`'s `toString` method does not produce
+the information you would like to appear in the log.
+
+Another advantage to Messages is that they simplify writing Layouts. In
+other logging frameworks the Layout must loop through the parameters
+individually and determine what to do based on what objects are
+encountered. With Messages the Layout has the option of delegating the
+formatting to the Message or performing its formatting based on the type
+of Message encountered.
+
+Borrowing from the earlier example illustrating Markers to identify SQL
+statements being logged, Messages can also be leveraged. First, the
+Message is defined.
+
+[source,java]
+----
+public class SQLMessage implements Message {
+  public enum SQLType {
+      UPDATE,
+      QUERY
+  };
+
+  private final SQLType type;
+  private final String table;
+  private final Map<String, String> cols;
+
+  public SQLMessage(SQLType type, String table) {
+      this(type, table, null);
+  }
+
+  public SQLMessage(SQLType type, String table, Map<String, String> cols) {
+      this.type = type;
+      this.table = table;
+      this.cols = cols;
+  }
+
+  public String getFormattedMessage() {
+      switch (type) {
+          case UPDATE:
+            return createUpdateString();
+            break;
+          case QUERY:
+            return createQueryString();
+            break;
+          default;
+      }
+  }
+
+  public String getMessageFormat() {
+      return type + " " + table;
+  }
+
+  public Object getParameters() {
+      return cols;
+  }
+
+  private String createUpdateString() {
+  }
+
+  private String createQueryString() {
+  }
+
+  private String formatCols(Map<String, String> cols) {
+      StringBuilder sb = new StringBuilder();
+      boolean first = true;
+      for (Map.Entry<String, String> entry : cols.entrySet()) {
+          if (!first) {
+              sb.append(", ");
+          }
+          sb.append(entry.getKey()).append("=").append(entry.getValue());
+          first = false;
+      }
+      return sb.toString();
+  }
+}
+----
+
+Next we can use the message in our application.
+
+[source,java]
+----
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import java.util.Map;
+
+public class MyApp {
+
+    private Logger logger = LogManager.getLogger(MyApp.class.getName());
+    private static final Marker SQL_MARKER = MarkerManager.getMarker("SQL");
+    private static final Marker UPDATE_MARKER = MarkerManager.getMarker("SQL_UPDATE", SQL_MARKER);
+    private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL_QUERY", SQL_MARKER);
+
+    public String doQuery(String table) {
+        logger.entry(param);
+
+        logger.debug(QUERY_MARKER, new SQLMessage(SQLMessage.SQLType.QUERY, table));
+
+        return logger.exit();
+    }
+
+    public String doUpdate(String table, Map<String, String> params) {
+        logger.entry(param);
+
+        logger.debug(UPDATE_MARKER, new SQLMessage(SQLMessage.SQLType.UPDATE, table, parmas);
+
+        return logger.exit();
+    }
+}
+----
+
+Notice that in contrast to the prior version of this example, the
+`logger.debug` in `doUpdate` no longer needs to be wrapped in an
+`isDebugEnabled` call as creation of the `SQLMessage` is on the same order
+of magnitude of performing that check. Furthermore, all the formatting
+of the SQL columns is now hidden in the `SQLMessage` instead of having to
+take place in the business logic. Finally, if desired, Filters and/or
+Layouts can be written to take special action when an `SQLMessage` is
+encountered.
+
+[#FormattedMessage]
+=== FormattedMessage
+
+The message pattern passed to a
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/FormattedMessage.html[`FormattedMessage`]
+is first checked to see if it is a valid `java.text.MessageFormat`
+pattern. If it is, a `MessageFormatMessage` is used to format it. If not
+it is next checked to see if it contains any tokens that are valid
+format specifiers for `String.format()`. If so, a `StringFormattedMessage`
+is used to format it. Finally, if the pattern doesn't match either of
+those then a `ParameterizedMessage` is used to format it.
+
+[#LocalizedMessage]
+=== LocalizedMessage
+
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/LocalizedMessage.html[`LocalizedMessage`]
+is provided primarily to provide compatibility with Log4j 1.x.
+Generally, the best approach to localization is to have the client UI
+render the events in the client's locale.
+
+`LocalizedMessage` incorporates a `ResourceBundle` and allows the message
+pattern parameter to be the key to the message pattern in the bundle. If
+no bundle is specified, `LocalizedMessage` will attempt to locate a bundle
+with the name of the Logger used to log the event. The message retrieved
+from the bundle will be formatted using a FormattedMessage.
+
+[#LoggerNameAwareMessage]
+=== LoggerNameAwareMessage
+
+`LoggerNameAwareMessage` is an interface with a `setLoggerName` method. This
+method will be called during event construction so that the Message has
+the name of the Logger used to log the event when the message is being
+formatted.
+
+[#MapMessage]
+=== MapMessage
+
+A `MapMessage` contains a Map of String keys and values. `MapMessage`
+implements `FormattedMessage` and accepts format specifiers of "XML",
+"JSON" or "JAVA", in which case the Map will be formatted as XML, JSON
+or as documented by
+https://docs.oracle.com/javase/7/docs/api/java/util/AbstractMap.html#toString()[`java.util.AbstractMap.toString()`].
+Otherwise, the Map will be formatted as `"key1=value1 key2=value2 ..."`.
+
+Some Appenders make special use of `MapMessage` objects:
+
+* When a link:appenders.html#JMSAppender[JMS Appender] is configured
+with a `MessageLayout`, it converts a Log4j `MapMessage` to a JMS
+`javax.jms.MapMessage`.
+* When a link:appenders.html#JDBCAppender[JDBC Appender] is configured
+with a `MessageLayout`, it converts a Log4j `MapMessage` to values in a
+SQL INSERT statement.
+* When a link:appenders.html#NoSQLAppenderMongoDB2[MongoDB2 Appender] or
+link:appenders.html#NoSQLAppenderMongoDB3[MongoDB3 Appender] is
+configured with a `MessageLayout`, it converts a Log4j `MapMessage` to
+fields in a MongoDB object.
+
+When an Appender is `MessageLayout`-aware, the object Log4j sends to
+target is not a Log4j Log Event but a custom object.
+
+[#MessageFormatMessage]
+=== MessageFormatMessage
+
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/MessageFormatMessage.html[`MessageFormatMessage`]
+handles messages that use a
+https://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html[conversion
+format]. While this `Message` has more flexibility than
+`ParameterizedMessage`, it is also about two times slower.
+
+[#MultiformatMessage]
+=== MultiformatMessage
+
+A `MultiformatMessage` will have a getFormats method and a
+`getFormattedMessage` method that accepts and array of format Strings. The
+`getFormats` method may be called by a Layout to provide it information on
+what formatting options the Message supports. The Layout may then call
+`getFormattedMessage` with one or more for the formats. If the Message
+doesn't recognize the format name it will simply format the data using
+its default format. An example of this is `StructuredDataMessage`
+which accepts a format String of "XML" which will cause it to format the
+event data as XML instead of the RFC 5424 format.
+
+[#ObjectMessage]
+=== ObjectMessage
+
+Formats an `Object` by calling its `toString` method. Since Log4j 2.6,
+Layouts trying to be low-garbage or garbage-free will call the
+`formatTo(StringBuilder)` method instead.
+
+[#ParameterizedMessage]
+=== ParameterizedMessage
+
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/ParameterizedMessage.html[`ParameterizedMessage`]
+handles messages that contain "\{}" in the format to represent
+replaceable tokens and the replacement parameters.
+
+[#ReusableObjectMessage]
+=== ReusableObjectMessage
+
+In garbage-free mode, this message is used to pass logged Objects to the
+Layout and Appenders. Functionally equivalent to
+<<ObjectMessage>>.
+
+[#ReusableParameterizedMessage]
+=== ReusableParameterizedMessage
+
+In garbage-free mode, this message is used to handle messages that
+contain "\{}" in the format to represent replaceable tokens and the
+replacement parameters. Functionally equivalent to
+<<ParameterizedMessage>>.
+
+[#ReusableSimpleMessage]
+=== ReusableSimpleMessage
+
+In garbage-free mode, this message is used to pass logged `String`s and
+`CharSequence`s to the Layout and Appenders. Functionally equivalent to
+<<SimpleMessage>>.
+
+[#SimpleMessage]
+=== SimpleMessage
+
+`SimpleMessage` contains a `String` or `CharSequence` that requires no
+formatting.
+
+[#StringFormattedMessage]
+=== StringFormattedMessage
+
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/StringFormattedMessage.html[`StringFormattedMessage`]
+handles messages that use a
+https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax[conversion
+format] that is compliant with
+https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#format(java.lang.String,%20java.lang.Object...)[java.lang.String.format()].
+While this Message has more flexibility than `ParameterizedMessage`, it is
+also 5 to 10 times slower.
+
+[#StructuredDataMessage]
+=== StructuredDataMessage
+
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/StructuredDataMessage.html[`StructuredDataMessage`]
+allows applications to add items to a `Map` as well as set the id to allow
+a message to be formatted as a Structured Data element in accordance
+with http://tools.ietf.org/html/rfc5424[RFC 5424].
+
+[#ThreadDumpMessage]
+=== ThreadDumpMessage
+
+A ThreadDumpMessage, if logged, will generate stack traces for all
+threads. The stack traces will include any locks that are held.
+
+[#TimestampMessage]
+=== TimestampMessage
+
+A TimestampMessage will provide a `getTimestamp` method that is called
+during event construction. The timestamp in the Message will be used in
+lieu of the current timestamp.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c34fa7ef/src/site/xdoc/manual/messages.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/messages.xml b/src/site/xdoc/manual/messages.xml
deleted file mode 100644
index 9eef316..0000000
--- a/src/site/xdoc/manual/messages.xml
+++ /dev/null
@@ -1,314 +0,0 @@
-<?xml version="1.0"?>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<document xmlns="http://maven.apache.org/XDOC/2.0"
-          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-          xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
-  <properties>
-    <title>Log4j 2 API Messages</title>
-    <author email="rgoers@apache.org">Ralph Goers</author>
-  </properties>
-
-  <body>
-    <section name="Log4j 2 API">
-      <subsection name="Messages">
-        <a name="Messages"/>
-        <p>
-          Although Log4j 2 provides Logger methods that accept Strings and Objects, all of these are ultimately
-          captured in Message objects that are then associated with the log event. Applications are free to
-          construct Messages of their own and pass them to the Logger. Although it may seem more expensive than
-          passing the message format and parameters directly to the event, testing has shown that with modern
-          JVMs the cost of creating and destroying events is minor, especially when complex tasks are encapsulated
-          in the Message instead of the application. In addition, when using the methods that accept Strings and
-          parameters, the underlying Message object will only be created if any configured global filters
-          or the Logger's log level allow the message to be processed.
-        </p>
-        <p>
-          Consider an application that has a Map object containing {"Name" = "John Doe", "Address" = "123 Main
-          St.",
-          "Phone" = "(999) 555-1212"} and a User object that has a getId method that returns "jdoe". The developer
-          would like to add an informational message that returns "User John Doe has logged in using id jdoe". The
-          way this could be accomplished is by doing:
-        </p>
-        <pre class="prettyprint">logger.info("User {} has logged in using id {}", map.get("Name"), user.getId());</pre>
-        <p>
-          While there is nothing inherently wrong with this, as the complexity of the objects and desired output
-          increases this technique becomes harder to use. As an alternative, using Messages allows:
-        </p>
-        <pre class="prettyprint">logger.info(new LoggedInMessage(map, user));</pre>
-        <p>
-          In this alternative the formatting is delegated to the LoggedInMessage object's getFormattedMessage
-          method.
-          Although in this alternative a new object is created, none of the methods on the objects passed to the
-          LoggedInMessage are invoked until the LoggedInMessage is formatted. This is especially useful when an
-          Object's toString method does not produce the information you would like to appear in the log.
-        </p>
-        <p>
-          Another advantage to Messages is that they simplify writing Layouts. In other logging frameworks the
-          Layout must loop through the parameters individually and determine what to do based on what objects
-          are encountered. With Messages the Layout has the option of delegating the formatting to the Message or
-          performing its formatting based on the type of Message encountered.
-        </p>
-        <p>
-          Borrowing from the earlier example illustrating Markers to identify SQL statements being logged, Messages
-          can also be leveraged. First, the Message is defined.
-        </p>
-        <pre class="prettyprint linenums"><![CDATA[
-public class SQLMessage implements Message {
-  public enum SQLType {
-      UPDATE,
-      QUERY
-  };
-
-  private final SQLType type;
-  private final String table;
-  private final Map<String, String> cols;
-
-  public SQLMessage(SQLType type, String table) {
-      this(type, table, null);
-  }
-
-  public SQLMessage(SQLType type, String table, Map<String, String> cols) {
-      this.type = type;
-      this.table = table;
-      this.cols = cols;
-  }
-
-  public String getFormattedMessage() {
-      switch (type) {
-          case UPDATE:
-            return createUpdateString();
-            break;
-          case QUERY:
-            return createQueryString();
-            break;
-          default;
-      }
-  }
-
-  public String getMessageFormat() {
-      return type + " " + table;
-  }
-
-  public Object getParameters() {
-      return cols;
-  }
-
-  private String createUpdateString() {
-  }
-
-  private String createQueryString() {
-  }
-
-  private String formatCols(Map<String, String> cols) {
-      StringBuilder sb = new StringBuilder();
-      boolean first = true;
-      for (Map.Entry<String, String> entry : cols.entrySet()) {
-          if (!first) {
-              sb.append(", ");
-          }
-          sb.append(entry.getKey()).append("=").append(entry.getValue());
-          first = false;
-      }
-      return sb.toString();
-  }
-}]]></pre>
-      <p>
-        Next we can use the message in our application.
-      </p>
-        <pre class="prettyprint linenums"><![CDATA[
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-import java.util.Map;
-
-public class MyApp {
-
-    private Logger logger = LogManager.getLogger(MyApp.class.getName());
-    private static final Marker SQL_MARKER = MarkerManager.getMarker("SQL");
-    private static final Marker UPDATE_MARKER = MarkerManager.getMarker("SQL_UPDATE", SQL_MARKER);
-    private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL_QUERY", SQL_MARKER);
-
-    public String doQuery(String table) {
-        logger.entry(param);
-
-        logger.debug(QUERY_MARKER, new SQLMessage(SQLMessage.SQLType.QUERY, table));
-
-        return logger.exit();
-    }
-
-    public String doUpdate(String table, Map<String, String> params) {
-        logger.entry(param);
-
-        logger.debug(UPDATE_MARKER, new SQLMessage(SQLMessage.SQLType.UPDATE, table, parmas);
-
-        return logger.exit();
-    }
-}]]></pre>
-        <p>
-          Notice that in contrast to the prior version of this example, the logger.debug in doUpdate no longer
-          needs to be wrapped in an isDebugEnabled call as creation of the SQLMessage is on the same order of
-          magnitude of performing that check. Furthermore, all the formatting of the SQL columns is now hidden
-          in the SQLMessage instead of having to take place in the business logic. Finally, if desired, Filters
-          and/or Layouts can be written to take special action when an SQLMessage is encountered.
-        </p>
-      <h4>FormattedMessage</h4>
-        <a name="FormattedMessage"/>
-        <p>
-          The message pattern passed to a
-          <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/message/FormattedMessage.html">FormattedMessage</a>
-          is first checked to see if it is a valid java.text.MessageFormat pattern. If it is, a MessageFormatMessage is
-          used to format it. If not it is next checked to see if it contains any tokens that are valid format
-          specifiers for String.format(). If so, a StringFormattedMessage is used to format it. Finally, if the
-          pattern doesn't match either of those then a ParameterizedMessage is used to format it.
-        </p>
-      <h4>LocalizedMessage</h4>
-        <a name="LocalizedMessage"/>
-        <p>
-          <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/message/LocalizedMessage.html">LocalizedMessage</a>
-          is provided primarily to provide compatibility with Log4j 1.x. Generally,
-          the best approach to localization is to have the client UI render the events in the client's locale.
-        </p>
-        <p>
-          LocalizedMessage incorporates a ResourceBundle and allows the message pattern parameter to be the key to
-          the message pattern in the bundle. If no bundle is specified,
-          LocalizedMessage will attempt to locate a bundle with the name of the Logger used to log the event. The
-          message retrieved from the bundle will be formatted using a FormattedMessage.
-        </p>
-      <h4>LoggerNameAwareMessage</h4>
-        <a name="LoggerNameAwareMessage"/>
-        <p>
-          LoggerNameAwareMessage is an interface with a setLoggerName method. This method will be called during
-          event construction so that the Message has the name of the Logger used to log the event when the
-          message is being formatted.
-        </p>
-      <h4>MapMessage</h4>
-        <a name="MapMessage"/>
-        <p>
-          A <code>MapMessage</code> contains a Map of String keys and values. <code>MapMessage</code> implements 
-          <code>FormattedMessage</code> and accepts format specifiers of "XML", "JSON" or "JAVA", in which case the Map
-          will be formatted as XML, JSON or as documented by
-          <a class="javadoc" href="https://docs.oracle.com/javase/7/docs/api/java/util/AbstractMap.html#toString()">java.util.AbstractMap.toString()</a>.
-          Otherwise, the Map will be formatted as <code>"key1=value1 key2=value2 ..."</code>.
-        </p>
-        <p>
-          Some Appenders make special use of <code>MapMessage</code> objects: 
-        </p>
-        <ul>
-          <li>
-            When a <a href="appenders.html#JMSAppender">JMS Appender</a> is configured with a <code>MessageLayout</code>, it converts a Log4j 
-            <code>MapMessage</code> to a JMS <code>javax.jms.MapMessage</code>.
-          </li>
-          <li>
-            When a <a href="appenders.html#JDBCAppender">JDBC Appender</a> is configured with a <code>MessageLayout</code>, it converts a Log4j 
-            <code>MapMessage</code> to values in a SQL INSERT statement.
-          </li>
-          <li>
-            When a <a href="appenders.html#NoSQLAppenderMongoDB2">MongoDB2 Appender</a> or 
-            <a href="appenders.html#NoSQLAppenderMongoDB3">MongoDB3 Appender</a> is configured with a <code>MessageLayout</code>, it converts a Log4j 
-            <code>MapMessage</code> to fields in a MongoDB object. 
-          </li>
-        </ul>
-        <p>
-          When an Appender is <code>MessageLayout</code>-aware, the object Log4j sends to target is not a Log4j Log 
-          Event but a custom object.
-        </p>
-        <h4>MessageFormatMessage</h4>
-        <a name="MessageFormatMessage"/>
-        <p>
-          <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/message/MessageFormatMessage.html">MessageFormatMessage</a>
-          handles messages that use a <a href="https://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html">conversion format</a>.
-          While this Message has more flexibility than ParameterizedMessage, it is also about two times slower.
-        </p>
-      <h4>MultiformatMessage</h4>
-        <a name="MultiformatMessage"/>
-        <p>
-          A MultiformatMessage will have a getFormats method and a getFormattedMessage method that accepts and array
-          of format Strings. The getFormats method may be called by a Layout to provide it information on what
-          formatting options the Message supports. The Layout may then call getFormattedMessage with one or more
-          for the formats. If the Message doesn't recognize the format name it will simply format the data using its
-          default format. An example of this is the StructuredDataMessage which accepts a format String of "XML"
-          which will cause it to format the event data as XML instead of the RFC 5424 format.
-        </p>
-      <h4>ObjectMessage</h4>
-        <a name="ObjectMessage"/>
-        <p>
-          Formats an Object by calling its toString method. Since Log4j 2.6, Layouts trying to be low-garbage or
-          garbage-free will call the <tt>formatTo(StringBuilder)</tt> method instead.
-        </p>
-      <h4>ParameterizedMessage</h4>
-        <a name="ParameterizedMessage"/>
-        <p>
-          <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/message/ParameterizedMessage.html">ParameterizedMessage</a>
-          handles messages that contain "{}" in the format to represent replaceable tokens and the replacement
-          parameters.
-        </p>
-      <h4>ReusableObjectMessage</h4>
-        <a name="ReusableObjectMessage"/>
-        <p>
-          In garbage-free mode, this message is used to pass logged Objects to the Layout and Appenders.
-          Functionally equivalent to <a href="#ObjectMessage">ObjectMessage</a>.
-        </p>
-      <h4>ReusableParameterizedMessage</h4>
-        <a name="ReusableParameterizedMessage"/>
-        <p>
-          In garbage-free mode, this message is used to handle messages that contain "{}" in the format to
-          represent replaceable tokens and the replacement parameters.
-          Functionally equivalent to <a href="#ParameterizedMessage">ParameterizedMessage</a>.
-        </p>
-      <h4>ReusableSimpleMessage</h4>
-        <a name="ReusableSimpleMessage"/>
-        <p>
-          In garbage-free mode, this message is used to pass logged Strings and CharSequences to the Layout and Appenders.
-          Functionally equivalent to <a href="#SimpleMessage">SimpleMessage</a>.
-        </p>
-      <h4>SimpleMessage</h4>
-        <a name="SimpleMessage"/>
-        <p>
-          SimpleMessage contains a String or CharSequence that requires no formatting.
-        </p>
-      <h4>StringFormattedMessage</h4>
-        <a name="StringFormattedMessage"/>
-        <p>
-          <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/message/StringFormattedMessage.html">StringFormattedMessage</a>
-          handles messages that use a <a href="https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">conversion format</a>
-          that is compliant with <a class="javadoc" href="https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#format(java.lang.String, java.lang.Object...)">java.lang.String.format()</a>.
-          While this Message has more flexibility than ParameterizedMessage, it is also 5 to 10 times slower.
-        </p>
-      <h4>StructuredDataMessage</h4>
-        <a name="StructuredDataMessage"/>
-        <p>
-          <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/message/StructuredDataMessage.html">StructuredDataMessage</a>
-          allows applications to add items to a Map as well as set the id to allow a message to be formatted as a
-          Structured Data element in accordance with <a href="http://tools.ietf.org/html/rfc5424">RFC 5424</a>.
-        </p>
-      <h4>ThreadDumpMessage</h4>
-        <a name="ThreadDumpMessage"/>
-        <p>
-          A ThreadDumpMessage, if logged, will generate stack traces for all threads.
-          The stack traces will include any locks that are held.
-        </p>
-      <h4>TimestampMessage</h4>
-        <a name="TimestampMessage"/>
-        <p>
-          A TimestampMessage will provide a getTimestamp method that is called during event construction. The
-          timestamp in the Message will be used in lieu of the current timestamp.
-        </p>
-      </subsection>
-    </section>
-  </body>
-</document>