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       * <p>This method is equivalent to calling the {@link #setMaxDepth}
35       * method with a zero <code>maxDepth</code> argument.
36       */
37      public static void clear() {
38          org.apache.logging.log4j.ThreadContext.clearStack();
39      }
40  
41  
42      /**
43       * Clone the diagnostic context for the current thread.
44       * <p/>
45       * <p>Internally a diagnostic context is represented as a stack.  A
46       * given thread can supply the stack (i.e. diagnostic context) to a
47       * child thread so that the child can inherit the parent thread's
48       * diagnostic context.
49       * <p/>
50       * <p>The child thread uses the {@link #inherit inherit} method to
51       * inherit the parent's diagnostic context.
52       *
53       * @return Stack A clone of the current thread's  diagnostic context.
54       */
55      public static Stack cloneStack() {
56          final Stack<String> stack = new Stack<String>();
57          for (final String element : org.apache.logging.log4j.ThreadContext.cloneStack().asList()) {
58              stack.push(element);
59          }
60          return stack;
61      }
62  
63  
64      /**
65       * Inherit the diagnostic context of another thread.
66       * <p/>
67       * <p>The parent thread can obtain a reference to its diagnostic
68       * context using the {@link #cloneStack} method.  It should
69       * communicate this information to its child so that it may inherit
70       * the parent's diagnostic context.
71       * <p/>
72       * <p>The parent's diagnostic context is cloned before being
73       * inherited. In other words, once inherited, the two diagnostic
74       * contexts can be managed independently.
75       * <p/>
76       * <p>In java, a child thread cannot obtain a reference to its
77       * parent, unless it is directly handed the reference. Consequently,
78       * there is no client-transparent way of inheriting diagnostic
79       * contexts. Do you know any solution to this problem?
80       *
81       * @param stack The diagnostic context of the parent thread.
82       */
83      public static void inherit(final Stack<String> stack) {
84          org.apache.logging.log4j.ThreadContext.setStack(stack);
85      }
86  
87  
88      /**
89       * <font color="#FF4040"><b>Never use this method directly.</b>
90       * @return The string value of the specified key.
91       */
92      public static String get() {
93          return org.apache.logging.log4j.ThreadContext.peek();
94      }
95  
96      /**
97       * Get the current nesting depth of this diagnostic context.
98       * @return int The number of elements in the call stack.
99       * @see #setMaxDepth
100      */
101     public static int getDepth() {
102         return org.apache.logging.log4j.ThreadContext.getDepth();
103     }
104 
105     /**
106      * Clients should call this method before leaving a diagnostic
107      * context.
108      * <p/>
109      * <p>The returned value is the value that was pushed last. If no
110      * context is available, then the empty string "" is returned.
111      *
112      * @return String The innermost diagnostic context.
113      */
114     public static String pop() {
115         return org.apache.logging.log4j.ThreadContext.pop();
116     }
117 
118     /**
119      * Looks at the last diagnostic context at the top of this NDC
120      * without removing it.
121      * <p/>
122      * <p>The returned value is the value that was pushed last. If no
123      * context is available, then the empty string "" is returned.
124      *
125      * @return String The innermost diagnostic context.
126      */
127     public static String peek() {
128         return org.apache.logging.log4j.ThreadContext.peek();
129     }
130 
131     /**
132      * Push new diagnostic context information for the current thread.
133      * <p/>
134      * <p>The contents of the <code>message</code> parameter is
135      * determined solely by the client.
136      *
137      * @param message The new diagnostic context information.
138      */
139     public static void push(final String message) {
140         org.apache.logging.log4j.ThreadContext.push(message);
141     }
142 
143     /**
144      * Remove the diagnostic context for this thread.
145      * <p/>
146      * <p>Each thread that created a diagnostic context by calling
147      * {@link #push} should call this method before exiting. Otherwise,
148      * the memory used by the <b>thread</b> cannot be reclaimed by the
149      * VM.
150      * <p/>
151      * <p>As this is such an important problem in heavy duty systems and
152      * because it is difficult to always guarantee that the remove
153      * method is called before exiting a thread, this method has been
154      * augmented to lazily remove references to dead threads. In
155      * practice, this means that you can be a little sloppy and
156      * occasionally forget to call {@code remove} before exiting a
157      * thread. However, you must call <code>remove</code> sometime. If
158      * you never call it, then your application is sure to run out of
159      * memory.
160      */
161     public static void remove() {
162         org.apache.logging.log4j.ThreadContext.removeStack();
163     }
164 
165     /**
166      * Set maximum depth of this diagnostic context. If the current
167      * depth is smaller or equal to <code>maxDepth</code>, then no
168      * action is taken.
169      * <p/>
170      * <p>This method is a convenient alternative to multiple {@link
171      * #pop} calls. Moreover, it is often the case that at the end of
172      * complex call sequences, the depth of the NDC is
173      * unpredictable. The <code>setMaxDepth</code> method circumvents
174      * this problem.
175      * <p/>
176      * <p>For example, the combination
177      * <pre>
178      * void foo() {
179      * &nbsp;  int depth = NDC.getDepth();
180      * <p/>
181      * &nbsp;  ... complex sequence of calls
182      * <p/>
183      * &nbsp;  NDC.setMaxDepth(depth);
184      * }
185      * </pre>
186      * <p/>
187      * ensures that between the entry and exit of foo the depth of the
188      * diagnostic stack is conserved.
189      *
190      * @see #getDepth
191      * @param maxDepth The maximum depth of the stack.
192      */
193     public static void setMaxDepth(final int maxDepth) {
194         org.apache.logging.log4j.ThreadContext.trim(maxDepth);
195     }
196 }