    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         * 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<String>();
    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    }