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 }