X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar%2Forg%2Fapache%2Flog4j%2FNDC.java;fp=srcjar%2Forg%2Fapache%2Flog4j%2FNDC.java;h=0000000000000000000000000000000000000000;hb=0e684f72690bd6532272a39ab6c188a27559fd09;hp=3b25e9970708a1f8c177b49088d34e44fbe2ad9e;hpb=91fb50c7dfcda9dcb3399d284f252075e89d54ff;p=jalview.git diff --git a/srcjar/org/apache/log4j/NDC.java b/srcjar/org/apache/log4j/NDC.java deleted file mode 100644 index 3b25e99..0000000 --- a/srcjar/org/apache/log4j/NDC.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * 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; - -/** - 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, - -

- -

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 { - - // The synchronized keyword is not used in this class. This may seem - // dangerous, especially since the class will be used by - // multiple-threads. In particular, all threads share the same - // hashtable (the "ht" variable). This is OK since java hashtables - // are thread safe. Same goes for Stacks. - - // More importantly, when inheriting diagnostic contexts the child - // thread is handed a clone of the parent's NDC. It follows that - // each thread has its own NDC (i.e. stack). - - static Hashtable ht = new Hashtable(); - - static int pushCounter = 0; // the number of times push has been called - // after the latest call to lazyRemove - - // The number of times we allow push to be called before we call lazyRemove - // 5 is a relatively small number. As such, lazyRemove is not called too - // frequently. We thus avoid the cost of creating an Enumeration too often. - // The higher this number, the longer is the avarage period for which all - // logging calls in all threads are blocked. - static final int REAP_THRESHOLD = 5; - - // No instances allowed. - private NDC() {} - - /** - * Get NDC stack for current thread. - * @return NDC stack for current thread. - */ - private static Stack getCurrentStack() { - if (ht != null) { - return (Stack) ht.get(Thread.currentThread()); - } - return null; - } - - - /** - 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() { - Stack stack = getCurrentStack(); - if(stack != null) { - stack.setSize(0); - } - } - - - /** - 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() { - Stack stack = getCurrentStack(); - if(stack == null) { - return null; - } else { - return (Stack) stack.clone(); - } - } - - - /** - 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) { - if(stack != null) { - ht.put(Thread.currentThread(), stack); - } - } - - - /** - Never use this method directly, use the {@link - org.apache.log4j.spi.LoggingEvent#getNDC} method instead. - */ - static - public - String get() { - Stack s = getCurrentStack(); - if(s != null && !s.isEmpty()) { - return ((DiagnosticContext) s.peek()).fullMessage; - } else { - return null; - } - } - - /** - * Get the current nesting depth of this diagnostic context. - * - * @see #setMaxDepth - * @since 0.7.5 - */ - public - static - int getDepth() { - Stack stack = getCurrentStack(); - if(stack == null) { - return 0; - } else { - return stack.size(); - } - } - - private - static - void lazyRemove() { - if (ht == null) { - return; - } - - // The synchronization on ht is necessary to prevent JDK 1.2.x from - // throwing ConcurrentModificationExceptions at us. This sucks BIG-TIME. - // One solution is to write our own hashtable implementation. - Vector v; - - synchronized(ht) { - // Avoid calling clean-up too often. - if(++pushCounter <= REAP_THRESHOLD) { - return; // We release the lock ASAP. - } else { - pushCounter = 0; // OK let's do some work. - } - - int misses = 0; - v = new Vector(); - Enumeration enumeration = ht.keys(); - // We give up after 4 straigt missses. That is 4 consecutive - // inspected threads in 'ht' that turn out to be alive. - // The higher the proportion on dead threads in ht, the higher the - // chances of removal. - while(enumeration.hasMoreElements() && (misses <= 4)) { - Thread t = (Thread) enumeration.nextElement(); - if(t.isAlive()) { - misses++; - } else { - misses = 0; - v.addElement(t); - } - } - } // synchronized - - int size = v.size(); - for(int i = 0; i < size; i++) { - Thread t = (Thread) v.elementAt(i); - LogLog.debug("Lazy NDC removal for thread [" + t.getName() + "] ("+ - ht.size() + ")."); - ht.remove(t); - } - } - - /** - 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() { - Stack stack = getCurrentStack(); - if(stack != null && !stack.isEmpty()) { - return ((DiagnosticContext) stack.pop()).message; - } else { - 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() { - Stack stack = getCurrentStack(); - if(stack != null && !stack.isEmpty()) { - return ((DiagnosticContext) stack.peek()).message; - } else { - 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) { - Stack stack = getCurrentStack(); - - if(stack == null) { - DiagnosticContext dc = new DiagnosticContext(message, null); - stack = new Stack(); - Thread key = Thread.currentThread(); - ht.put(key, stack); - stack.push(dc); - } else if (stack.isEmpty()) { - DiagnosticContext dc = new DiagnosticContext(message, null); - stack.push(dc); - } else { - DiagnosticContext parent = (DiagnosticContext) stack.peek(); - stack.push(new DiagnosticContext(message, parent)); - } - } - - /** - 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() { - if (ht != null) { - ht.remove(Thread.currentThread()); - - // Lazily remove dead-thread references in ht. - lazyRemove(); - } - } - - /** - 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) { - Stack stack = getCurrentStack(); - if(stack != null && maxDepth < stack.size()) { - stack.setSize(maxDepth); - } - } - - // ===================================================================== - private static class DiagnosticContext { - - String fullMessage; - String message; - - DiagnosticContext(String message, DiagnosticContext parent) { - this.message = message; - if(parent != null) { - fullMessage = parent.fullMessage + ' ' + message; - } else { - fullMessage = message; - } - } - } -} -