001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017 package org.apache.log4j;
018
019 import java.util.Stack;
020
021 /**
022 *
023 */
024 public final class NDC {
025
026 private NDC() {
027 }
028
029 /**
030 * Clear any nested diagnostic information if any. This method is
031 * useful in cases where the same thread can be potentially used
032 * over and over in different unrelated contexts.
033 * <p>
034 * This method is equivalent to calling the {@link #setMaxDepth}
035 * method with a zero <code>maxDepth</code> argument.
036 * </p>
037 */
038 public static void clear() {
039 org.apache.logging.log4j.ThreadContext.clearStack();
040 }
041
042
043 /**
044 * Clone the diagnostic context for the current thread.
045 * <p>
046 * Internally a diagnostic context is represented as a stack. A
047 * given thread can supply the stack (i.e. diagnostic context) to a
048 * child thread so that the child can inherit the parent thread's
049 * diagnostic context.
050 * </p>
051 * <p>
052 * The child thread uses the {@link #inherit inherit} method to
053 * inherit the parent's diagnostic context.
054 * </p>
055 * @return Stack A clone of the current thread's diagnostic context.
056 */
057 @SuppressWarnings("rawtypes")
058 public static Stack cloneStack() {
059 final Stack<String> stack = new Stack<String>();
060 for (final String element : org.apache.logging.log4j.ThreadContext.cloneStack().asList()) {
061 stack.push(element);
062 }
063 return stack;
064 }
065
066
067 /**
068 * Inherit the diagnostic context of another thread.
069 * <p>
070 * The parent thread can obtain a reference to its diagnostic
071 * context using the {@link #cloneStack} method. It should
072 * communicate this information to its child so that it may inherit
073 * the parent's diagnostic context.
074 * </p>
075 * <p>
076 * The parent's diagnostic context is cloned before being
077 * inherited. In other words, once inherited, the two diagnostic
078 * contexts can be managed independently.
079 * </p>
080 * <p>
081 * In java, a child thread cannot obtain a reference to its
082 * parent, unless it is directly handed the reference. Consequently,
083 * there is no client-transparent way of inheriting diagnostic
084 * contexts. Do you know any solution to this problem?
085 * </p>
086 * @param stack The diagnostic context of the parent thread.
087 */
088 public static void inherit(final Stack<String> stack) {
089 org.apache.logging.log4j.ThreadContext.setStack(stack);
090 }
091
092
093 /**
094 * <strong style="color:#FF4040">Never use this method directly.</strong>
095 *
096 * @return The string value of the specified key.
097 */
098 public static String get() {
099 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 }