MDC.java
1 /* 2 * Copyright 1999-2005 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.log4j; 18 19 import java.util.Hashtable; 20 import org.apache.log4j.helpers.Loader; 21 import org.apache.log4j.helpers.ThreadLocalMap; 22 23 /** 24 The MDC class is similar to the {@link NDC} class except that it is 25 based on a map instead of a stack. It provides <em>mapped 26 diagnostic contexts</em>. A <em>Mapped Diagnostic Context</em>, or 27 MDC in short, is an instrument for distinguishing interleaved log 28 output from different sources. Log output is typically interleaved 29 when a server handles multiple clients near-simultaneously. 30 31 <p><b><em>The MDC is managed on a per thread basis</em></b>. A 32 child thread automatically inherits a <em>copy</em> of the mapped 33 diagnostic context of its parent. 34 35 <p>The MDC class requires JDK 1.2 or above. Under JDK 1.1 the MDC 36 will always return empty values but otherwise will not affect or 37 harm your application. 38 39 @since 1.2 40 41 @author Ceki Gülcü */ 42 public class MDC { 43 44 final static MDC mdc = new MDC(); 45 46 static final int HT_SIZE = 7; 47 48 boolean java1; 49 50 Object tlm; 51 52 private 53 MDC() { 54 java1 = Loader.isJava1(); 55 if(!java1) { 56 tlm = new ThreadLocalMap(); 57 } 58 } 59 60 /** 61 Put a context value (the <code>o</code> parameter) as identified 62 with the <code>key</code> parameter into the current thread's 63 context map. 64 65 <p>If the current thread does not have a context map it is 66 created as a side effect. 67 68 */ 69 static 70 public 71 void put(String key, Object o) { 72 mdc.put0(key, o); 73 } 74 75 /** 76 Get the context identified by the <code>key</code> parameter. 77 78 <p>This method has no side effects. 79 */ 80 static 81 public 82 Object get(String key) { 83 return mdc.get0(key); 84 } 85 86 /** 87 Remove the the context identified by the <code>key</code> 88 parameter. 89 90 */ 91 static 92 public 93 void remove(String key) { 94 mdc.remove0(key); 95 } 96 97 98 /** 99 * Get the current thread's MDC as a hashtable. This method is 100 * intended to be used internally. 101 * */ 102 public static Hashtable getContext() { 103 return mdc.getContext0(); 104 } 105 106 107 private 108 void put0(String key, Object o) { 109 if(java1) { 110 return; 111 } else { 112 Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get(); 113 if(ht == null) { 114 ht = new Hashtable(HT_SIZE); 115 ((ThreadLocalMap)tlm).set(ht); 116 } 117 ht.put(key, o); 118 } 119 } 120 121 private 122 Object get0(String key) { 123 if(java1) { 124 return null; 125 } else { 126 Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get(); 127 if(ht != null && key != null) { 128 return ht.get(key); 129 } else { 130 return null; 131 } 132 } 133 } 134 135 private 136 void remove0(String key) { 137 if(!java1) { 138 Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get(); 139 if(ht != null) { 140 ht.remove(key); 141 } 142 } 143 } 144 145 146 private 147 Hashtable getContext0() { 148 if(java1) { 149 return null; 150 } else { 151 return (Hashtable) ((ThreadLocalMap)tlm).get(); 152 } 153 } 154 }