1 16 17 20 package org.apache.log4j; 21 22 import java.util.Hashtable ; 23 import java.util.Stack ; 24 import java.util.Enumeration ; 25 import java.util.Vector ; 26 27 import org.apache.log4j.helpers.LogLog; 28 29 100 101 public class NDC { 102 103 109 113 static Hashtable ht = new Hashtable (); 114 115 static int pushCounter = 0; 118 static final int REAP_THRESHOLD = 5; 124 125 private NDC() {} 127 128 129 138 public 139 static 140 void clear() { 141 Stack stack = (Stack ) ht.get(Thread.currentThread()); 142 if(stack != null) 143 stack.setSize(0); 144 } 145 146 147 161 public 162 static 163 Stack cloneStack() { 164 Object o = ht.get(Thread.currentThread()); 165 if(o == null) 166 return null; 167 else { 168 Stack stack = (Stack ) o; 169 return (Stack ) stack.clone(); 170 } 171 } 172 173 174 194 public 195 static 196 void inherit(Stack stack) { 197 if(stack != null) 198 ht.put(Thread.currentThread(), stack); 199 } 200 201 202 206 static 207 public 208 String get() { 209 Stack s = (Stack ) ht.get(Thread.currentThread()); 210 if(s != null && !s.isEmpty()) 211 return ((DiagnosticContext) s.peek()).fullMessage; 212 else 213 return null; 214 } 215 216 222 public 223 static 224 int getDepth() { 225 Stack stack = (Stack ) ht.get(Thread.currentThread()); 226 if(stack == null) 227 return 0; 228 else 229 return stack.size(); 230 } 231 232 private 233 static 234 void lazyRemove() { 235 236 Vector v; 240 241 synchronized(ht) { 242 if(++pushCounter <= REAP_THRESHOLD) { 244 return; } else { 246 pushCounter = 0; } 248 249 int misses = 0; 250 v = new Vector (); 251 Enumeration enumeration = ht.keys(); 252 while(enumeration.hasMoreElements() && (misses <= 4)) { 257 Thread t = (Thread ) enumeration.nextElement(); 258 if(t.isAlive()) { 259 misses++; 260 } else { 261 misses = 0; 262 v.addElement(t); 263 } 264 } 265 } 267 int size = v.size(); 268 for(int i = 0; i < size; i++) { 269 Thread t = (Thread ) v.elementAt(i); 270 LogLog.debug("Lazy NDC removal for thread [" + t.getName() + "] ("+ 271 ht.size() + ")."); 272 ht.remove(t); 273 } 274 } 275 276 286 public 287 static 288 String pop() { 289 Thread key = Thread.currentThread(); 290 Stack stack = (Stack ) ht.get(key); 291 if(stack != null && !stack.isEmpty()) 292 return ((DiagnosticContext) stack.pop()).message; 293 else 294 return ""; 295 } 296 297 307 public 308 static 309 String peek() { 310 Thread key = Thread.currentThread(); 311 Stack stack = (Stack ) ht.get(key); 312 if(stack != null && !stack.isEmpty()) 313 return ((DiagnosticContext) stack.peek()).message; 314 else 315 return ""; 316 } 317 318 325 public 326 static 327 void push(String message) { 328 Thread key = Thread.currentThread(); 329 Stack stack = (Stack ) ht.get(key); 330 331 if(stack == null) { 332 DiagnosticContext dc = new DiagnosticContext(message, null); 333 stack = new Stack (); 334 ht.put(key, stack); 335 stack.push(dc); 336 } else if (stack.isEmpty()) { 337 DiagnosticContext dc = new DiagnosticContext(message, null); 338 stack.push(dc); 339 } else { 340 DiagnosticContext parent = (DiagnosticContext) stack.peek(); 341 stack.push(new DiagnosticContext(message, parent)); 342 } 343 } 344 345 364 static 365 public 366 void remove() { 367 ht.remove(Thread.currentThread()); 368 369 lazyRemove(); 371 } 372 373 400 static 401 public 402 void setMaxDepth(int maxDepth) { 403 Stack stack = (Stack ) ht.get(Thread.currentThread()); 404 if(stack != null && maxDepth < stack.size()) 405 stack.setSize(maxDepth); 406 } 407 408 private static class DiagnosticContext { 410 411 String fullMessage; 412 String message; 413 414 DiagnosticContext(String message, DiagnosticContext parent) { 415 this.message = message; 416 if(parent != null) { 417 fullMessage = parent.fullMessage + ' ' + message; 418 } else { 419 fullMessage = message; 420 } 421 } 422 } 423 } 424 425 | Popular Tags |