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