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 @SuppressWarnings("rawtypes") 056 public static Stack cloneStack() { 057 final Stack<String> stack = new Stack<String>(); 058 for (final String element : org.apache.logging.log4j.ThreadContext.cloneStack().asList()) { 059 stack.push(element); 060 } 061 return stack; 062 } 063 064 065 /** 066 * Inherit the diagnostic context of another thread. 067 * <p/> 068 * <p>The parent thread can obtain a reference to its diagnostic 069 * context using the {@link #cloneStack} method. It should 070 * communicate this information to its child so that it may inherit 071 * the parent's diagnostic context. 072 * <p/> 073 * <p>The parent's diagnostic context is cloned before being 074 * inherited. In other words, once inherited, the two diagnostic 075 * contexts can be managed independently. 076 * <p/> 077 * <p>In java, a child thread cannot obtain a reference to its 078 * parent, unless it is directly handed the reference. Consequently, 079 * there is no client-transparent way of inheriting diagnostic 080 * contexts. Do you know any solution to this problem? 081 * 082 * @param stack The diagnostic context of the parent thread. 083 */ 084 public static void inherit(final Stack<String> stack) { 085 org.apache.logging.log4j.ThreadContext.setStack(stack); 086 } 087 088 089 /** 090 * <font color="#FF4040"><b>Never use this method directly.</b> 091 * @return The string value of the specified key. 092 */ 093 public static String get() { 094 return org.apache.logging.log4j.ThreadContext.peek(); 095 } 096 097 /** 098 * Get the current nesting depth of this diagnostic context. 099 * @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 }