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     * &nbsp;  int depth = NDC.getDepth();
190     *
191     * &nbsp;  ... complex sequence of calls
192     *
193     * &nbsp;  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}