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 */ 017package org.apache.log4j; 018 019import java.util.Stack; 020 021/** 022 * 023 */ 024public 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<>(); 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}