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 * <p>This method is equivalent to calling the {@link #setMaxDepth} 035 * method with a zero <code>maxDepth</code> argument. 036 */ 037 public static void clear() { 038 org.apache.logging.log4j.ThreadContext.clearStack(); 039 } 040 041 042 /** 043 * Clone the diagnostic context for the current thread. 044 * <p/> 045 * <p>Internally a diagnostic context is represented as a stack. A 046 * given thread can supply the stack (i.e. diagnostic context) to a 047 * child thread so that the child can inherit the parent thread's 048 * diagnostic context. 049 * <p/> 050 * <p>The child thread uses the {@link #inherit inherit} method to 051 * inherit the parent's diagnostic context. 052 * 053 * @return Stack A clone of the current thread's diagnostic context. 054 */ 055 public static Stack cloneStack() { 056 final Stack<String> stack = new Stack<String>(); 057 for (final String element : org.apache.logging.log4j.ThreadContext.cloneStack().asList()) { 058 stack.push(element); 059 } 060 return stack; 061 } 062 063 064 /** 065 * Inherit the diagnostic context of another thread. 066 * <p/> 067 * <p>The parent thread can obtain a reference to its diagnostic 068 * context using the {@link #cloneStack} method. It should 069 * communicate this information to its child so that it may inherit 070 * the parent's diagnostic context. 071 * <p/> 072 * <p>The parent's diagnostic context is cloned before being 073 * inherited. In other words, once inherited, the two diagnostic 074 * contexts can be managed independently. 075 * <p/> 076 * <p>In java, a child thread cannot obtain a reference to its 077 * parent, unless it is directly handed the reference. Consequently, 078 * there is no client-transparent way of inheriting diagnostic 079 * contexts. Do you know any solution to this problem? 080 * 081 * @param stack The diagnostic context of the parent thread. 082 */ 083 public static void inherit(final Stack<String> stack) { 084 org.apache.logging.log4j.ThreadContext.setStack(stack); 085 } 086 087 088 /** 089 * <font color="#FF4040"><b>Never use this method directly.</b> 090 * @return The string value of the specified key. 091 */ 092 public static String get() { 093 return org.apache.logging.log4j.ThreadContext.peek(); 094 } 095 096 /** 097 * Get the current nesting depth of this diagnostic context. 098 * @return int The number of elements in the call stack. 099 * @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(final 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 {@code 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(final int maxDepth) { 194 org.apache.logging.log4j.ThreadContext.trim(maxDepth); 195 } 196 }