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 * int depth = NDC.getDepth();
190 *
191 * ... complex sequence of calls
192 *
193 * 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 }