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 * int depth = NDC.getDepth();
181 * <p/>
182 * ... complex sequence of calls
183 * <p/>
184 * 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 }