View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements. See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache license, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License. You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the license for the specific language governing permissions and
    15   * limitations under the license.
    16   */
    17  package org.apache.log4j;
    18
    19  import java.util.Stack;
    20
    21  /**
    22   *
    23   */
    24  public final class NDC {
    25
    26      private NDC() {
    27      }
    28
    29      /**
    30       * Clear any nested diagnostic information if any. This method is
    31       * useful in cases where the same thread can be potentially used
    32       * over and over in different unrelated contexts.
    33       * <p>
    34       * This method is equivalent to calling the {@link #setMaxDepth}
    35       * method with a zero <code>maxDepth</code> argument.
    36       * </p>
    37       */
    38      public static void clear() {
    39          org.apache.logging.log4j.ThreadContext.clearStack();
    40      }
    41
    42
    43      /**
    44       * Clone the diagnostic context for the current thread.
    45       * <p>
    46       * Internally a diagnostic context is represented as a stack.  A
    47       * given thread can supply the stack (i.e. diagnostic context) to a
    48       * child thread so that the child can inherit the parent thread's
    49       * diagnostic context.
    50       * </p>
    51       * <p>
    52       * The child thread uses the {@link #inherit inherit} method to
    53       * inherit the parent's diagnostic context.
    54       * </p>
    55       * @return Stack A clone of the current thread's  diagnostic context.
    56       */
    57      @SuppressWarnings("rawtypes")
    58      public static Stack cloneStack() {
    59          final Stack<String> stack = new Stack<String>();
    60          for (final String element : org.apache.logging.log4j.ThreadContext.cloneStack().asList()) {
    61              stack.push(element);
    62          }
    63          return stack;
    64      }
    65
    66
    67      /**
    68       * Inherit the diagnostic context of another thread.
    69       * <p>
    70       * The parent thread can obtain a reference to its diagnostic
    71       * context using the {@link #cloneStack} method.  It should
    72       * communicate this information to its child so that it may inherit
    73       * the parent's diagnostic context.
    74       * </p>
    75       * <p>
    76       * The parent's diagnostic context is cloned before being
    77       * inherited. In other words, once inherited, the two diagnostic
    78       * contexts can be managed independently.
    79       * </p>
    80       * <p>
    81       * In java, a child thread cannot obtain a reference to its
    82       * parent, unless it is directly handed the reference. Consequently,
    83       * there is no client-transparent way of inheriting diagnostic
    84       * contexts. Do you know any solution to this problem?
    85       * </p>
    86       * @param stack The diagnostic context of the parent thread.
    87       */
    88      public static void inherit(final Stack<String> stack) {
    89          org.apache.logging.log4j.ThreadContext.setStack(stack);
    90      }
    91
    92
    93      /**
    94       * <strong style="color:#FF4040">Never use this method directly.</strong>
    95       *
    96       * @return The string value of the specified key.
    97       */
    98      public static String get() {
    99          return org.apache.logging.log4j.ThreadContext.peek();
    100     }
    101
    102     /**
    103      * Get the current nesting depth of this diagnostic context.
    104      * @return int The number of elements in the call stack.
    105      * @see #setMaxDepth
    106      */
    107     public static int getDepth() {
    108         return org.apache.logging.log4j.ThreadContext.getDepth();
    109     }
    110
    111     /**
    112      * Clients should call this method before leaving a diagnostic
    113      * context.
    114      * <p>
    115      * The returned value is the value that was pushed last. If no
    116      * context is available, then the empty string "" is returned.
    117      * </p>
    118      * @return String The innermost diagnostic context.
    119      */
    120     public static String pop() {
    121         return org.apache.logging.log4j.ThreadContext.pop();
    122     }
    123
    124     /**
    125      * Looks at the last diagnostic context at the top of this NDC
    126      * without removing it.
    127      * <p>
    128      * The returned value is the value that was pushed last. If no
    129      * context is available, then the empty string "" is returned.
    130      * </p>
    131      * @return String The innermost diagnostic context.
    132      */
    133     public static String peek() {
    134         return org.apache.logging.log4j.ThreadContext.peek();
    135     }
    136
    137     /**
    138      * Push new diagnostic context information for the current thread.
    139      * <p>
    140      * The contents of the <code>message</code> parameter is
    141      * determined solely by the client.
    142      * </p>
    143      * @param message The new diagnostic context information.
    144      */
    145     public static void push(final String message) {
    146         org.apache.logging.log4j.ThreadContext.push(message);
    147     }
    148
    149     /**
    150      * Remove the diagnostic context for this thread.
    151      * <p>
    152      * Each thread that created a diagnostic context by calling
    153      * {@link #push} should call this method before exiting. Otherwise,
    154      * the memory used by the <b>thread</b> cannot be reclaimed by the
    155      * VM.
    156      * </p>
    157      * <p>
    158      * As this is such an important problem in heavy duty systems and
    159      * because it is difficult to always guarantee that the remove
    160      * method is called before exiting a thread, this method has been
    161      * augmented to lazily remove references to dead threads. In
    162      * practice, this means that you can be a little sloppy and
    163      * occasionally forget to call {@code remove} before exiting a
    164      * thread. However, you must call <code>remove</code> sometime. If
    165      * you never call it, then your application is sure to run out of
    166      * memory.
    167      * </p>
    168      */
    169     public static void remove() {
    170         org.apache.logging.log4j.ThreadContext.removeStack();
    171     }
    172
    173     /**
    174      * Set maximum depth of this diagnostic context. If the current
    175      * depth is smaller or equal to <code>maxDepth</code>, then no
    176      * action is taken.
    177      * <p>
    178      * This method is a convenient alternative to multiple {@link
    179      * #pop} calls. Moreover, it is often the case that at the end of
    180      * complex call sequences, the depth of the NDC is
    181      * unpredictable. The <code>setMaxDepth</code> method circumvents
    182      * this problem.
    183      * </p>
    184      * <p>
    185      * For example, the combination
    186      * </p>
    187      * <pre>
    188      * void foo() {
    189      * &nbsp;  int depth = NDC.getDepth();
    190      *
    191      * &nbsp;  ... complex sequence of calls
    192      *
    193      * &nbsp;  NDC.setMaxDepth(depth);
    194      * }
    195      * </pre>
    196      * <p>
    197      * ensures that between the entry and exit of foo the depth of the
    198      * diagnostic stack is conserved.
    199      * </p>
    200      *
    201      * @see #getDepth
    202      * @param maxDepth The maximum depth of the stack.
    203      */
    204     public static void setMaxDepth(final int maxDepth) {
    205         org.apache.logging.log4j.ThreadContext.trim(maxDepth);
    206     }
    207 }