2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package org.apache.log4j;
20 import org.apache.log4j.helpers.Loader;
21 import org.apache.log4j.helpers.ThreadLocalMap;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.Hashtable;
28 * The MDC class is similar to the {@link NDC} class except that it is
29 * based on a map instead of a stack. It provides <em>mapped
30 * diagnostic contexts</em>. A <em>Mapped Diagnostic Context</em>, or
31 * MDC in short, is an instrument for distinguishing interleaved log
32 * output from different sources. Log output is typically interleaved
33 * when a server handles multiple clients near-simultaneously.
35 * <p><b><em>The MDC is managed on a per thread basis</em></b>. A
36 * child thread automatically inherits a <em>copy</em> of the mapped
37 * diagnostic context of its parent.
39 * <p>The MDC class requires JDK 1.2 or above. Under JDK 1.1 the MDC
40 * will always return empty values but otherwise will not affect or
41 * harm your application.</p>
43 * <p>Attention: the application is required to clean up. In web applications
44 * this can happen with creating a Servlet Filter and overriding the
45 * onFilter method like:</p>
50 * chain.doFilter(request, response);
56 * <p>Please also see: {@link http://logging.apache.org/log4j/1.2/faq.html#mdcmemoryleak}</p>
58 * @author Ceki Gülcü
63 final static MDC mdc = new MDC();
65 static final int HT_SIZE = 7;
71 private Method removeMethod;
74 java1 = Loader.isJava1();
76 tlm = new ThreadLocalMap();
80 removeMethod = ThreadLocal.class.getMethod("remove", null);
81 } catch (NoSuchMethodException e) {
82 // don't do anything - java prior 1.5
87 * Put a context value (the <code>o</code> parameter) as identified
88 * with the <code>key</code> parameter into the current thread's
91 * <p>If the current thread does not have a context map it is
92 * created as a side effect.
94 public static void put(String key, Object o) {
101 * Get the context identified by the <code>key</code> parameter.
103 * <p>This method has no side effects.
105 public static Object get(String key) {
107 return mdc.get0(key);
113 * Remove the the context identified by the <code>key</code>
116 public static void remove(String key) {
124 * Get the current thread's MDC as a hashtable. This method is
125 * intended to be used internally.
127 public static Hashtable getContext() {
129 return mdc.getContext0();
136 * Remove all values from the MDC.
140 public static void clear() {
147 private void put0(String key, Object o) {
148 if (java1 || tlm == null) {
151 Hashtable ht = (Hashtable) ((ThreadLocalMap) tlm).get();
153 ht = new Hashtable(HT_SIZE);
154 ((ThreadLocalMap) tlm).set(ht);
160 private Object get0(String key) {
161 if (java1 || tlm == null) {
164 Hashtable ht = (Hashtable) ((ThreadLocalMap) tlm).get();
165 if (ht != null && key != null) {
173 private void remove0(String key) {
174 if (!java1 && tlm != null) {
175 Hashtable ht = (Hashtable) ((ThreadLocalMap) tlm).get();
178 // clean up if this was the last key
186 private Hashtable getContext0() {
187 if (java1 || tlm == null) {
190 return (Hashtable) ((ThreadLocalMap) tlm).get();
194 private void clear0() {
195 if (!java1 && tlm != null) {
196 Hashtable ht = (Hashtable) ((ThreadLocalMap) tlm).get();
200 if (removeMethod != null) {
201 // java 1.3/1.4 does not have remove - will suffer from a memory leak
203 removeMethod.invoke(tlm, null);
204 } catch (IllegalAccessException e) {
206 } catch (InvocationTargetException e) {