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