org.apache.log4j.NDC Maven / Gradle / Ivy
Show all versions of pax-logging-api Show documentation
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Contributors: Dan Milstein
// Ray Millard
package org.apache.log4j;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Enumeration;
import java.util.Vector;
import org.apache.log4j.helpers.LogLog;
/**
*
* NOTE: This class is added to Pax Logging ONLY TO PROVIDE THE API. There is NO SUPPORT for NDC in Pax Logging.
*
* The NDC class implements nested diagnostic contexts as defined by Neil Harrison in the article "Patterns for
* Logging Diagnostic Messages" part of the book "Pattern Languages of Program Design 3" edited by Martin et al.
*
*
* A Nested Diagnostic Context, or NDC in short, is an instrument to distinguish interleaved log output from different
* sources. Log output is typically interleaved when a server handles multiple clients near-simultaneously.
*
*
* Interleaved log output can still be meaningful if each log entry from different contexts had a distinctive stamp.
* This is where NDCs come into play.
*
*
* Note that NDCs are managed on a per thread basis. NDC
* operations such as {@link #push push}, {@link #pop}, {@link #clear}, {@link #getDepth} and {@link #setMaxDepth}
* affect the NDC of the
* current thread only. NDCs of other threads remain unaffected.
*
*
* For example, a servlet can build a per client request NDC consisting the clients host name and other information
* contained in the the request.
* Cookies are another source of distinctive information. To build an
* NDC one uses the {@link #push push} operation. Simply put,
*
*
*
* - Contexts can be nested.
*
*
*
- When entering a context, call
NDC.push
. As a side effect, if
* there is no nested diagnostic context for the current thread, this method
* will create it.
*
*
*
- When leaving a context, call
NDC.pop
.
*
*
*
- When exiting a thread make sure to call {@link #remove
* NDC.remove()}.
*
*
*
* There is no penalty for forgetting to match each push
operation
* with a corresponding pop
, except the obvious mismatch between
* the real application context and the context set in the NDC.
*
*
* If configured to do so, {@link PatternLayout} and {@link TTCCLayout}
* instances automatically retrieve the nested diagnostic context for the
* current thread without any user intervention. Hence, even if a servlet is
* serving multiple clients simultaneously, the logs emanating from the same
* code (belonging to the same category) can still be distinguished because each
* client request will have a different NDC tag.
*
*
* Heavy duty systems should call the {@link #remove} method when leaving the
* run method of a thread. This ensures that the memory used by the thread can
* be freed by the Java garbage collector. There is a mechanism to lazily remove
* references to dead threads. In practice, this means that you can be a little
* sloppy and sometimes forget to call {@link #remove} before exiting a thread.
*
*
* A thread may inherit the nested diagnostic context of another (possibly
* parent) thread using the {@link #inherit inherit} method. A thread may obtain
* a copy of its NDC with the {@link #cloneStack cloneStack} method and pass the
* reference to any other thread, in particular to a child.
*
* @author Ceki Gülcü
* @since 0.7.0
*/
public class NDC {
// No instances allowed.
private NDC() {
}
/**
* Clear any nested diagnostic information if any. This method is useful in cases where the same thread can be
* potentially used over and over in different unrelated contexts.
*
*
* This method is equivalent to calling the {@link #setMaxDepth} method with a zero maxDepth
argument.
*
* @since 0.8.4c
*/
public static void clear() {
}
/**
* Clone the diagnostic context for the current thread.
*
*
* Internally a diagnostic context is represented as a stack. A given thread can supply the stack (i.e. diagnostic
* context) to a child thread so that the child can inherit the parent thread's diagnostic context.
*
*
* The child thread uses the {@link #inherit inherit} method to inherit the parent's diagnostic context.
*
* @return Stack A clone of the current thread's diagnostic context.
*/
public static Stack cloneStack() {
return new Stack();
}
/**
* Inherit the diagnostic context of another thread.
*
*
* The parent thread can obtain a reference to its diagnostic context using the {@link #cloneStack} method. It
* should communicate this information to its child so that it may inherit the parent's diagnostic context.
*
*
* The parent's diagnostic context is cloned before being inherited. In other words, once inherited, the two
* diagnostic contexts can be managed independently.
*
*
* In java, a child thread cannot obtain a reference to its parent, unless it is directly handed the reference.
* Consequently, there is no client-transparent way of inheriting diagnostic contexts. Do you know any solution to
* this problem?
*
* @param stack The diagnostic context of the parent thread.
*/
public static void inherit(Stack stack) {
}
/**
* Never use this method directly, use the
* {@link org.apache.log4j.spi.LoggingEvent#getNDC} method instead.
*/
static public String get() {
return "";
}
/**
* Get the current nesting depth of this diagnostic context.
*
* @see #setMaxDepth
* @since 0.7.5
*/
public static int getDepth() {
return 0;
}
/**
* Clients should call this method before leaving a diagnostic context.
*
*
* The returned value is the value that was pushed last. If no context is available, then the empty string "" is
* returned.
*
* @return String The innermost diagnostic context.
*/
public static String pop() {
return "";
}
/**
* Looks at the last diagnostic context at the top of this NDC without removing it.
*
*
* The returned value is the value that was pushed last. If no context is available, then the empty string "" is
* returned.
*
* @return String The innermost diagnostic context.
*/
public static String peek() {
return "";
}
/**
* Push new diagnostic context information for the current thread.
*
*
* The contents of the message
parameter is determined solely by the client.
*
* @param message The new diagnostic context information.
*/
public static void push(String message) {
}
/**
* Remove the diagnostic context for this thread.
*
*
* Each thread that created a diagnostic context by calling {@link #push} should call this method before exiting.
* Otherwise, the memory used by the
* thread cannot be reclaimed by the VM.
*
*
* As this is such an important problem in heavy duty systems and because it is difficult to always guarantee that
* the remove method is called before exiting a thread, this method has been augmented to lazily remove references
* to dead threads. In practice, this means that you can be a little sloppy and occasionally forget to call
* {@link #remove} before exiting a thread. However, you must call remove
sometime. If you never call
* it, then your application is sure to run out of memory.
*/
static public void remove() {
}
/**
* Set maximum depth of this diagnostic context. If the current depth is smaller or equal to maxDepth
,
* then no action is taken.
*
*
* This method is a convenient alternative to multiple {@link #pop} calls. Moreover, it is often the case that at
* the end of complex call sequences, the depth of the NDC is unpredictable. The setMaxDepth
method
* circumvents this problem.
*
*
* For example, the combination
*
*
* void foo() {
* int depth = NDC.getDepth();
*
* ... complex sequence of calls
*
* NDC.setMaxDepth(depth);
* }
*
*
* ensures that between the entry and exit of foo the depth of the diagnostic stack is conserved.
*
* @see #getDepth
* @since 0.7.5
*/
static public void setMaxDepth(int maxDepth) {
}
}