OK, cool!
:-)
Gary

On Mon, Nov 14, 2016 at 10:30 AM, Greg Thomas <greg.d.tho...@gmail.com>
wrote:

> Already fixed in trunk @ https://github.com/apache/
> logging-log4j2/blob/master/log4j-api/src/main/java/org/
> apache/logging/log4j/CloseableThreadContext.java
>
> I think the merge of my pull request copied all the commits, you weren't
> the only one to spot that!
>
> Greg
> --
> Sent from my iPhone
>
> On 14 Nov 2016, at 17:44, Gary Gregory <garydgreg...@gmail.com> wrote:
>
> Note that "@since 2.7.1" should all be "@since 2.8"
>
> Gary
>
> ---------- Forwarded message ----------
> From: <mi...@apache.org>
> Date: Mon, Nov 14, 2016 at 2:17 AM
> Subject: [1/4] logging-log4j2 git commit: LOG4J2-1692: Add putAll() /
> pushAll() methods to CloseableThreadContext
> To: comm...@logging.apache.org
>
>
> Repository: logging-log4j2
> Updated Branches:
>   refs/heads/master 6e69e95d3 -> df481a19c
>
>
> LOG4J2-1692: Add putAll() / pushAll() methods to CloseableThreadContext
>
>
> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
> Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit
> /3ba3628f
> Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/3ba3628f
> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/3ba3628f
>
> Branch: refs/heads/master
> Commit: 3ba3628fa6a94db512ceef10ecf2188ee740e857
> Parents: abf29af
> Author: Greg Thomas <greg.d.tho...@gmail.com>
> Authored: Fri Nov 11 16:39:51 2016 +0000
> Committer: Greg Thomas <greg.d.tho...@gmail.com>
> Committed: Fri Nov 11 16:39:51 2016 +0000
>
> ----------------------------------------------------------------------
>  .../logging/log4j/CloseableThreadContext.java   |  66 +++-
>  .../log4j/CloseableThreadContextTest.java       |  39 ++-
>  src/site/xdoc/manual/thread-context.xml         | 329 ++++++++++---------
>  3 files changed, 272 insertions(+), 162 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3
> ba3628f/log4j-api/src/main/java/org/apache/logging/log4j/Clo
> seableThreadContext.java
> ----------------------------------------------------------------------
> diff --git 
> a/log4j-api/src/main/java/org/apache/logging/log4j/CloseableThreadContext.java
> b/log4j-api/src/main/java/org/apache/logging/log4j/Closeable
> ThreadContext.java
> index 9f0a279..5a45195 100644
> --- a/log4j-api/src/main/java/org/apache/logging/log4j/Closeable
> ThreadContext.java
> +++ b/log4j-api/src/main/java/org/apache/logging/log4j/Closeable
> ThreadContext.java
> @@ -62,8 +62,8 @@ public class CloseableThreadContext {
>      }
>
>      /**
> -     * Populates the Thread Context Map with the supplied key/value
> pairs. Any existing keys in the
> -     * {@link ThreadContext} will be replaced with the supplied values,
> and restored back to their original values when
> +     * Populates the Thread Context Map with the supplied key/value pair.
> Any existing key in the
> +     * {@link ThreadContext} will be replaced with the supplied value,
> and restored back to their original value when
>       * the instance is closed.
>       *
>       * @param key   The  key to be added
> @@ -74,6 +74,31 @@ public class CloseableThreadContext {
>          return new CloseableThreadContext.Instance().put(key, value);
>      }
>
> +    /**
> +     * Populates the Thread Context Stack with the supplied stack. The
> information will be popped off when
> +     * the instance is closed.
> +     *
> +     * @param values The stack of values to be added
> +     * @return a new instance that will back out the changes when closed.
> +     * @since 2.7.1
> +     */
> +    public static CloseableThreadContext.Instance pushAll(final
> ThreadContext.ContextStack stack) {
> +        return new CloseableThreadContext.Instance().pushAll(stack);
> +    }
> +
> +    /**
> +     * Populates the Thread Context Map with the supplied key/value
> pairs. Any existing keys in the
> +     * {@link ThreadContext} will be replaced with the supplied values,
> and restored back to their original value when
> +     * the instance is closed.
> +     *
> +     * @param values The map of key/value pairs to be added
> +     * @return a new instance that will back out the changes when closed.
> +     * @since 2.7.1
> +     */
> +    public static CloseableThreadContext.Instance putAll(final
> Map<String, String> values) {
> +        return new CloseableThreadContext.Instance().putAll(values);
> +    }
> +
>      public static class Instance implements AutoCloseable {
>
>          private int pushCount = 0;
> @@ -110,13 +135,13 @@ public class CloseableThreadContext {
>          }
>
>          /**
> -         * Populates the Thread Context Map with the supplied key/value
> pairs. Any existing keys in the
> -         * {@link ThreadContext} will be replaced with the supplied
> values, and restored back to their original values when
> +         * Populates the Thread Context Map with the supplied key/value
> pair. Any existing key in the
> +         * {@link ThreadContext} will be replaced with the supplied
> value, and restored back to their original value when
>           * the instance is closed.
>           *
>           * @param key   The  key to be added
>           * @param value The value to be added
> -         * @return the instance that will back out the changes when
> closed.
> +         * @return a new instance that will back out the changes when
> closed.
>           */
>          public Instance put(final String key, final String value) {
>              // If there are no existing values, a null will be stored as
> an old value
> @@ -128,6 +153,37 @@ public class CloseableThreadContext {
>          }
>
>          /**
> +         * Populates the Thread Context Map with the supplied key/value
> pairs. Any existing keys in the
> +         * {@link ThreadContext} will be replaced with the supplied
> values, and restored back to their original value when
> +         * the instance is closed.
> +         *
> +         * @param values The map of key/value pairs to be added
> +         * @return a new instance that will back out the changes when
> closed.
> +         * @since 2.7.1
> +         */
> +        public Instance putAll(final Map<String, String> values) {
> +            for (final Map.Entry<String, String> entry :
> values.entrySet()) {
> +                put(entry.getKey(), entry.getValue());
> +            }
> +            return this;
> +        }
> +
> +        /**
> +         * Populates the Thread Context Stack with the supplied stack.
> The information will be popped off when
> +         * the instance is closed.
> +         *
> +         * @param values The stack of values to be added
> +         * @return a new instance that will back out the changes when
> closed.
> +         * @since 2.7.1
> +         */
> +        public Instance pushAll(final ThreadContext.ContextStack stack) {
> +            for (final String message : stack.asList()) {
> +                push(message);
> +            }
> +            return this;
> +        }
> +
> +        /**
>           * Removes the values from the {@link ThreadContext}.
>           * <p>
>           * Values pushed to the {@link ThreadContext} <em>stack</em> will
> be popped off.
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3
> ba3628f/log4j-api/src/test/java/org/apache/logging/log4j/Clo
> seableThreadContextTest.java
> ----------------------------------------------------------------------
> diff --git 
> a/log4j-api/src/test/java/org/apache/logging/log4j/CloseableThreadContextTest.java
> b/log4j-api/src/test/java/org/apache/logging/log4j/Closeable
> ThreadContextTest.java
> index 1194678..6216c94 100644
> --- a/log4j-api/src/test/java/org/apache/logging/log4j/Closeable
> ThreadContextTest.java
> +++ b/log4j-api/src/test/java/org/apache/logging/log4j/Closeable
> ThreadContextTest.java
> @@ -17,12 +17,16 @@
>  package org.apache.logging.log4j;
>
>  import static org.hamcrest.CoreMatchers.is;
> +import static org.hamcrest.CoreMatchers.nullValue;
>  import static org.junit.Assert.assertThat;
>
>  import org.apache.logging.log4j.junit.ThreadContextRule;
>  import org.junit.Rule;
>  import org.junit.Test;
>
> +import java.util.HashMap;
> +import java.util.Map;
> +
>  /**
>   * Tests {@link CloseableThreadContext}.
>   *
> @@ -32,9 +36,9 @@ public class CloseableThreadContextTest {
>
>      private final String key = "key";
>      private final String value = "value";
> -
> +
>      @Rule
> -    public final ThreadContextRule threadContextRule = new
> ThreadContextRule();
> +    public final ThreadContextRule threadContextRule = new
> ThreadContextRule();
>
>      @Test
>      public void shouldAddAnEntryToTheMap() throws Exception {
> @@ -184,4 +188,35 @@ public class CloseableThreadContextTest {
>          assertThat(ThreadContext.get(key), is(originalMapValue));
>          assertThat(ThreadContext.peek(), is(originalStackValue));
>      }
> +
> +    @Test
> +    public void putAllWillPutAllValues() throws Exception {
> +
> +        final String oldValue = "oldValue";
> +        ThreadContext.put(key, oldValue);
> +
> +        final Map<String, String> valuesToPut = new HashMap<>();
> +        valuesToPut.put(key, value);
> +
> +        try (final CloseableThreadContext.Instance ignored =
> CloseableThreadContext.putAll(valuesToPut)) {
> +            assertThat(ThreadContext.get(key), is(value));
> +        }
> +        assertThat(ThreadContext.get(key), is(oldValue));
> +
> +    }
> +
> +    @Test
> +    public void pushAllWillPushAllValues() throws Exception {
> +
> +        ThreadContext.push(key);
> +        final ThreadContext.ContextStack stack =
> ThreadContext.getImmutableStack();
> +        ThreadContext.pop();
> +
> +        try (final CloseableThreadContext.Instance ignored =
> CloseableThreadContext.pushAll(stack)) {
> +            assertThat(ThreadContext.peek(), is(key));
> +        }
> +        assertThat(ThreadContext.peek(), is(""));
> +
> +    }
> +
>  }
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/3
> ba3628f/src/site/xdoc/manual/thread-context.xml
> ----------------------------------------------------------------------
> diff --git a/src/site/xdoc/manual/thread-context.xml
> b/src/site/xdoc/manual/thread-context.xml
> index dd5b21c..4401258 100644
> --- a/src/site/xdoc/manual/thread-context.xml
> +++ b/src/site/xdoc/manual/thread-context.xml
> @@ -26,164 +26,183 @@
>      </properties>
>
>      <body>
> -      <section name="Log4j 2 API">
> -        <subsection name="Thread Context">
> -          <h4>Introduction</h4>
> -          <p>Log4j introduced the concept of the Mapped Diagnostic
> Context or MDC. It has been documented and
> -            discussed in numerous places including
> -            <a href="http://veerasundar.com/b
> log/2009/10/log4j-mdc-mapped-diagnostic-context-what-and-why/">Log4j MDC:
> What and Why</a> and
> -            <a href="http://blog.f12.no/wp/20
> 04/12/09/log4j-and-the-mapped-diagnostic-context/">Log4j and the Mapped
> Diagnostic Context</a>.
> -            In addition, Log4j 1.x provides support for a Nested
> Diagnostic Context or NDC. It too has been documented
> -            and discussed in various places such as
> -            <a href="http://lstierneyltd.com/
> blog/development/log4j-nested-diagnostic-contexts-ndc/">Log4j NDC</a>.
> -            SLF4J/Logback followed with its own implementation of the
> MDC, which is documented very well at
> -            <a href="http://logback.qos.ch/manual/mdc.html";>Mapped
> Diagnostic Context</a>.
> -          </p>
> -          <p>Log4j 2 continues with the idea of the MDC and the NDC but
> merges them into a single Thread Context.
> -            The Thread Context Map is the equivalent of the MDC and the
> Thread Context Stack is the equivalent of the
> -            NDC. Although these are frequently used for purposes other
> than diagnosing problems, they are still
> -            frequently referred to as the MDC and NDC in Log4j 2 since
> they are already well known by those acronyms.
> -          </p>
> -          <h4>Fish Tagging</h4>
> -          <p>Most real-world systems have to deal with multiple clients
> simultaneously. In a typical multithreaded
> -            implementation of such a system, different threads will
> handle different clients. Logging is
> -            especially well suited to trace and debug complex distributed
> applications. A common approach to
> -            differentiate the logging output of one client from another
> is to instantiate a new separate logger for
> -            each client. This promotes the proliferation of loggers and
> increases the management overhead of logging.
> -          </p>
> -          <p>A lighter technique is to uniquely stamp each log request
> initiated from the same client interaction.
> -            Neil Harrison described this method in the book "Patterns for
> Logging Diagnostic Messages," in <em>Pattern
> -            Languages of Program Design 3</em>, edited by R. Martin, D.
> Riehle, and F. Buschmann
> -            (Addison-Wesley, 1997). Just as a fish can be tagged and have
> its movement tracked, stamping log
> -            events with a common tag or set of data elements allows the
> complete flow of a transaction or a request
> -            to be tracked. We call this <i>Fish Tagging</i>.
> -          </p>
> -          <p>Log4j provides two mechanisms for performing Fish Tagging;
> the Thread Context Map and the Thread
> -            Context Stack. The Thread Context Map allows any number of
> items to be added and be identified
> -            using key/value pairs. The Thread Context Stack allows one or
> more items to be pushed on the
> -            Stack and then be identified by their order in the Stack or
> by the data itself. Since key/value
> -            pairs are more flexible, the Thread Context Map is
> recommended when data items may be added during
> -            the processing of the request or when there are more than one
> or two items.
> -          </p>
> -           <p>To uniquely stamp each request using the Thread Context
> Stack, the user pushes contextual information
> -             on to the Stack.
> -           </p>
> -            <pre class="prettyprint linenums">
> -ThreadContext.push(UUID.randomUUID().toString()); // Add the fishtag;
> +        <section name="Log4j 2 API">
> +            <subsection name="Thread Context">
> +                <h4>Introduction</h4>
> +                <p>Log4j introduced the concept of the Mapped Diagnostic
> Context or MDC. It has been documented and
> +                    discussed in numerous places including
> +                    <a href="http://veerasundar.com/b
> log/2009/10/log4j-mdc-mapped-diagnostic-context-what-and-why/">Log4j MDC:
> What and Why</a> and
> +                    <a href="http://blog.f12.no/wp/20
> 04/12/09/log4j-and-the-mapped-diagnostic-context/">Log4j and the Mapped
> Diagnostic Context</a>.
> +                    In addition, Log4j 1.x provides support for a Nested
> Diagnostic Context or NDC. It too has been documented
> +                    and discussed in various places such as
> +                    <a href="http://lstierneyltd.com/
> blog/development/log4j-nested-diagnostic-contexts-ndc/">Log4j NDC</a>.
> +                    SLF4J/Logback followed with its own implementation of
> the MDC, which is documented very well at
> +                    <a href="http://logback.qos.ch/manual/mdc.html";>Mapped
> Diagnostic Context</a>.
> +                </p>
> +                <p>Log4j 2 continues with the idea of the MDC and the NDC
> but merges them into a single Thread Context.
> +                    The Thread Context Map is the equivalent of the MDC
> and the Thread Context Stack is the equivalent of the
> +                    NDC. Although these are frequently used for purposes
> other than diagnosing problems, they are still
> +                    frequently referred to as the MDC and NDC in Log4j 2
> since they are already well known by those acronyms.
> +                </p>
> +                <h4>Fish Tagging</h4>
> +                <p>Most real-world systems have to deal with multiple
> clients simultaneously. In a typical multithreaded
> +                    implementation of such a system, different threads
> will handle different clients. Logging is
> +                    especially well suited to trace and debug complex
> distributed applications. A common approach to
> +                    differentiate the logging output of one client from
> another is to instantiate a new separate logger for
> +                    each client. This promotes the proliferation of
> loggers and increases the management overhead of logging.
> +                </p>
> +                <p>A lighter technique is to uniquely stamp each log
> request initiated from the same client interaction.
> +                    Neil Harrison described this method in the book
> "Patterns for Logging Diagnostic Messages," in <em>Pattern
> +                        Languages of Program Design 3</em>, edited by R.
> Martin, D.  Riehle, and F. Buschmann
> +                    (Addison-Wesley, 1997). Just as a fish can be tagged
> and have its movement tracked, stamping log
> +                    events with a common tag or set of data elements
> allows the complete flow of a transaction or a request
> +                    to be tracked. We call this <i>Fish Tagging</i>.
> +                </p>
> +                <p>Log4j provides two mechanisms for performing Fish
> Tagging; the Thread Context Map and the Thread
> +                    Context Stack. The Thread Context Map allows any
> number of items to be added and be identified
> +                    using key/value pairs. The Thread Context Stack
> allows one or more items to be pushed on the
> +                    Stack and then be identified by their order in the
> Stack or by the data itself. Since key/value
> +                    pairs are more flexible, the Thread Context Map is
> recommended when data items may be added during
> +                    the processing of the request or when there are more
> than one or two items.
> +                </p>
> +                <p>To uniquely stamp each request using the Thread
> Context Stack, the user pushes contextual information
> +                    on to the Stack.
> +                </p>
> +                <pre class="prettyprint linenums">
> +                    ThreadContext.push(UUID.randomUUID().toString()); //
> Add the fishtag;
>
> -logger.debug("Message 1");
> -.
> -.
> -.
> -logger.debug("Message 2");
> -.
> -.
> -ThreadContext.pop();</pre>
> -          <p>
> -            The alternative to the Thread Context Stack is the Thread
> Context Map. In this case, attributes
> -            associated with the request being processed are adding at the
> beginning and removed at the end
> -            as follows:
> -          </p>
> -          <pre class="prettyprint linenums">
> -ThreadContext.put("id", UUID.randomUUID().toString()); // Add the fishtag;
> -ThreadContext.put("ipAddress", request.getRemoteAddr());
> -ThreadContext.put("loginId", session.getAttribute("loginId"));
> -ThreadContext.put("hostName", request.getServerName());
> -.
> -logger.debug("Message 1");
> -.
> -.
> -logger.debug("Message 2");
> -.
> -.
> -ThreadContext.clear();</pre>
> +                    logger.debug("Message 1");
> +                    .
> +                    .
> +                    .
> +                    logger.debug("Message 2");
> +                    .
> +                    .
> +                    ThreadContext.pop();</pre>
> +                <p>
> +                    The alternative to the Thread Context Stack is the
> Thread Context Map. In this case, attributes
> +                    associated with the request being processed are
> adding at the beginning and removed at the end
> +                    as follows:
> +                </p>
> +                <pre class="prettyprint linenums">
> +                    ThreadContext.put("id",
> UUID.randomUUID().toString()); // Add the fishtag;
> +                    ThreadContext.put("ipAddress",
> request.getRemoteAddr());
> +                    ThreadContext.put("loginId",
> session.getAttribute("loginId"));
> +                    ThreadContext.put("hostName",
> request.getServerName());
> +                    .
> +                    logger.debug("Message 1");
> +                    .
> +                    .
> +                    logger.debug("Message 2");
> +                    .
> +                    .
> +                    ThreadContext.clear();</pre>
>
> -          <h4>CloseableThreadContext</h4>
> -                 <p>When placing items on the stack or map, it's
> necessary to remove then again when appropriate. To assist with
> -                 this, the <tt>CloseableThreadContext</tt> implements
> the <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Aut
> oCloseable.html">AutoCloseable
> -                 interface</a>. This allows items to be pushed to the
> stack or put in the map, and removed when the <tt>close()</tt> method is
> called -
> -                 or automatically as part of a try-with-resources. For
> example, to temporarily push something on to the stack and then remove it:
> -          </p>
> -                 <pre class="prettyprint linenums">
> -// Add to the ThreadContext stack for this try block only;
> -try (final CloseableThreadContext.Instance ctc =
> CloseableThreadContext.push(UUID.randomUUID().toString())) {
> +                <h4>CloseableThreadContext</h4>
> +                <p>When placing items on the stack or map, it's necessary
> to remove then again when appropriate. To assist with
> +                    this, the <tt>CloseableThreadContext</tt> implements
> the <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Aut
> oCloseable.html">AutoCloseable
> +                        interface</a>. This allows items to be pushed to
> the stack or put in the map, and removed when the <tt>close()</tt> method
> is called -
> +                    or automatically as part of a try-with-resources. For
> example, to temporarily push something on to the stack and then remove it:
> +                </p>
> +                <pre class="prettyprint linenums">
> +                    // Add to the ThreadContext stack for this try block
> only;
> +                    try (final CloseableThreadContext.Instance ctc =
> CloseableThreadContext.push(UUID.randomUUID().toString())) {
>
> -    logger.debug("Message 1");
> -.
> -.
> -    logger.debug("Message 2");
> -.
> -.
> -}</pre>
> -          <p>
> -          Or, to temporarily put something in the map:
> -          </p>
> -                 <pre class="prettyprint linenums">
> -// Add to the ThreadContext map for this try block only;
> -try (final CloseableThreadContext.Instance ctc =
> CloseableThreadContext.put("id", UUID.randomUUID().toString())
> -
> .put("loginId", session.getAttribute("loginId"))) {
> +                    logger.debug("Message 1");
> +                    .
> +                    .
> +                    logger.debug("Message 2");
> +                    .
> +                    .
> +                    }</pre>
> +                <p>
> +                    Or, to temporarily put something in the map:
> +                </p>
> +                <pre class="prettyprint linenums">
> +                    // Add to the ThreadContext map for this try block
> only;
> +                    try (final CloseableThreadContext.Instance ctc =
> CloseableThreadContext.put("id", UUID.randomUUID().toString())
> +                    .put("loginId", session.getAttribute("loginId"))) {
>
> -    logger.debug("Message 1");
> -.
> -.
> -    logger.debug("Message 2");
> -.
> -.
> -}</pre>
> -                 <h4>Implementation details</h4>
> -          <p>The Stack and the Map are managed per thread and are based on
> -            <a href="http://docs.oracle.com/j
> avase/6/docs/api/java/lang/ThreadLocal.html">ThreadLocal</a>
> -            by default. The Map can be configured to use an
> -            <a href="http://docs.oracle.com/j
> avase/6/docs/api/java/lang/InheritableThreadLocal.html">Inhe
> ritableThreadLocal</a>
> -            by setting system property <tt>isThreadContextMapInheritable</tt>
> to <tt>"true"</tt>.
> -            When configured this way, the contents of the Map will be
> passed to child threads. However, as
> -            discussed in the
> -            <a href="http://docs.oracle.com/j
> avase/6/docs/api/java/util/concurrent/Executors.html#privile
> gedThreadFactory()">Executors</a>
> -            class and in other cases where thread pooling is utilized,
> the ThreadContext may not always be
> -            automatically passed to worker threads. In those cases the
> pooling mechanism should provide a means for
> -            doing so. The getContext() and cloneStack() methods can be
> used to obtain copies of the Map and Stack
> -            respectively.
> -          </p>
> -          <p>
> -            Note that all methods of the
> -            <a href="../log4j-api/apidocs/org
> /apache/logging/log4j/ThreadContext.html">ThreadContext</a>
> -            class are static.
> -          </p>
> -          <h4>Including the ThreadContext when writing logs</h4>
> -          <p>
> -            The <a href="../log4j-api/apidocs/org
> /apache/logging/log4j/core/PatternLayout.html">PatternLayout</a>
> -            provides mechanisms to print the contents of the
> -            <a href="../log4j-api/apidocs/org
> /apache/logging/log4j/ThreadContext.html">ThreadContext</a>
> -            Map and Stack.
> -          </p>
> -          <ul>
> -            <li>
> -              Use <code>%X</code> by itself to include the full contents
> of the Map.
> -            </li>
> -            <li>
> -              Use <code>%X{key}</code> to include the specified key.
> -            </li>
> -            <li>
> -              Use <code>%x</code> to include the full contents of the <a
> href="http://docs.oracle.com/javase/6/docs/api/java/util/Stack.html
> ">Stack</a>.
> -            </li>
> -          </ul>
> -          <h4>Custom context data injectors for non thread-local context
> data</h4>
> -          <p>
> -            With the ThreadContext logging statements can be tagged so
> log entries that were related in some way
> -            can be linked via these tags. The limitation is that this
> only works for logging done on the same application thread
> -            (or child threads when configured).
> -          </p>
> -          <p>
> -            Some applications have a thread model that delegates work to
> other threads, and
> -            in such models, tagging attributes that are put into a
> thread-local map in one thread are not visible
> -            in the other threads and logging done in the other threads
> will not show these attributes.
> -          </p>
> -          <p>
> -            Log4j 2.7 adds a flexible mechanism to tag logging statements
> with context data coming from
> -            other sources than the ThreadContext.
> -            See the manual page on <a 
> href="extending.html#Custom_ContextDataInjector">extending
> Log4j</a> for details.
> -          </p>
> -        </subsection>
> -      </section>
> +                    logger.debug("Message 1");
> +                    .
> +                    .
> +                    logger.debug("Message 2");
> +                    .
> +                    .
> +                    }</pre>
> +
> +                If you're using a thread pool, then you can initialise a
> CloseableThreadContext by using the
> +                <tt>putAll(final Map<String, String> values)</tt> method;
> +                <pre class="prettyprint linenums">
> +                    for( final Session session : sessions ) {
> +                    try (final CloseableThreadContext.Instance ctc =
> CloseableThreadContext.put("loginId", session.getAttribute("loginId"))) {
> +                    logger.debug("Starting background thread for user");
> +                    final Map&lt;String, String&gt; values =
> ThreadContext.getImmutableContext();
> +                    executor.submit(new Runnable() {
> +                    public void run() {
> +                    try (final CloseableThreadContext.Instance ctc =
> CloseableThreadContext.putAll(values)) {
> +                    logger.debug("Processing for user started");
> +                    .
> +                    logger.debug("Processing for user completed");
> +                    }
> +                    });
> +                    }
> +                    }</pre>
> +
> +                <h4>Implementation details</h4>
> +                <p>The Stack and the Map are managed per thread and are
> based on
> +                    <a href="http://docs.oracle.com/j
> avase/6/docs/api/java/lang/ThreadLocal.html">ThreadLocal</a>
> +                    by default. The Map can be configured to use an
> +                    <a href="http://docs.oracle.com/j
> avase/6/docs/api/java/lang/InheritableThreadLocal.html">Inhe
> ritableThreadLocal</a>
> +                    by setting system property
> <tt>isThreadContextMapInheritable</tt> to <tt>"true"</tt>.
> +                    When configured this way, the contents of the Map
> will be passed to child threads. However, as
> +                    discussed in the
> +                    <a href="http://docs.oracle.com/j
> avase/6/docs/api/java/util/concurrent/Executors.html#privile
> gedThreadFactory()">Executors</a>
> +                    class and in other cases where thread pooling is
> utilized, the ThreadContext may not always be
> +                    automatically passed to worker threads. In those
> cases the pooling mechanism should provide a means for
> +                    doing so. The getContext() and cloneStack() methods
> can be used to obtain copies of the Map and Stack
> +                    respectively.
> +                </p>
> +                <p>
> +                    Note that all methods of the
> +                    <a href="../log4j-api/apidocs/org
> /apache/logging/log4j/ThreadContext.html">ThreadContext</a>
> +                    class are static.
> +                </p>
> +                <h4>Including the ThreadContext when writing logs</h4>
> +                <p>
> +                    The <a href="../log4j-api/apidocs/org
> /apache/logging/log4j/core/PatternLayout.html">PatternLayout</a>
> +                    provides mechanisms to print the contents of the
> +                    <a href="../log4j-api/apidocs/org
> /apache/logging/log4j/ThreadContext.html">ThreadContext</a>
> +                    Map and Stack.
> +                </p>
> +                <ul>
> +                    <li>
> +                        Use <code>%X</code> by itself to include the full
> contents of the Map.
> +                    </li>
> +                    <li>
> +                        Use <code>%X{key}</code> to include the specified
> key.
> +                    </li>
> +                    <li>
> +                        Use <code>%x</code> to include the full contents
> of the <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Sta
> ck.html">Stack</a>.
> +                    </li>
> +                </ul>
> +                <h4>Custom context data injectors for non thread-local
> context data</h4>
> +                <p>
> +                    With the ThreadContext logging statements can be
> tagged so log entries that were related in some way
> +                    can be linked via these tags. The limitation is that
> this only works for logging done on the same application thread
> +                    (or child threads when configured).
> +                </p>
> +                <p>
> +                    Some applications have a thread model that delegates
> work to other threads, and
> +                    in such models, tagging attributes that are put into
> a thread-local map in one thread are not visible
> +                    in the other threads and logging done in the other
> threads will not show these attributes.
> +                </p>
> +                <p>
> +                    Log4j 2.7 adds a flexible mechanism to tag logging
> statements with context data coming from
> +                    other sources than the ThreadContext.
> +                    See the manual page on <a
> href="extending.html#Custom_ContextDataInjector">extending Log4j</a> for
> details.
> +                </p>
> +            </subsection>
> +        </section>
>      </body>
>  </document>
>
>
>
>
> --
> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
> Java Persistence with Hibernate, Second Edition
> <https://www.amazon.com/gp/product/1617290459/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1617290459&linkCode=as2&tag=garygregory-20&linkId=cadb800f39946ec62ea2b1af9fe6a2b8>
>
> <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1617290459>
> JUnit in Action, Second Edition
> <https://www.amazon.com/gp/product/1935182021/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182021&linkCode=as2&tag=garygregory-20&linkId=31ecd1f6b6d1eaf8886ac902a24de418%22>
>
> <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182021>
> Spring Batch in Action
> <https://www.amazon.com/gp/product/1935182951/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182951&linkCode=%7B%7BlinkCode%7D%7D&tag=garygregory-20&linkId=%7B%7Blink_id%7D%7D%22%3ESpring+Batch+in+Action>
> <http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182951>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>
>


-- 
E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
Java Persistence with Hibernate, Second Edition
<https://www.amazon.com/gp/product/1617290459/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1617290459&linkCode=as2&tag=garygregory-20&linkId=cadb800f39946ec62ea2b1af9fe6a2b8>

<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1617290459>
JUnit in Action, Second Edition
<https://www.amazon.com/gp/product/1935182021/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182021&linkCode=as2&tag=garygregory-20&linkId=31ecd1f6b6d1eaf8886ac902a24de418%22>

<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182021>
Spring Batch in Action
<https://www.amazon.com/gp/product/1935182951/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1935182951&linkCode=%7B%7BlinkCode%7D%7D&tag=garygregory-20&linkId=%7B%7Blink_id%7D%7D%22%3ESpring+Batch+in+Action>
<http:////ir-na.amazon-adsystem.com/e/ir?t=garygregory-20&l=am2&o=1&a=1935182951>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Reply via email to