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 Stack<String> stack = new Stack<String>(); 57 for (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(Stack 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(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 {@link #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 * int depth = NDC.getDepth(); 180 * <p/> 181 * ... complex sequence of calls 182 * <p/> 183 * 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(int maxDepth) { 194 org.apache.logging.log4j.ThreadContext.trim(maxDepth); 195 } 196 }