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