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         * &nbsp;  int depth = NDC.getDepth();
181         * <p/>
182         * &nbsp;  ... complex sequence of calls
183         * <p/>
184         * &nbsp;  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    }