View Javadoc

    1   /*
    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
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    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.
    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&uuml;lc&uuml; */
    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    *  Remove all values from the MDC.
    120    *  @since 1.2.16
    121   */
    122   public static void clear() {
    123     if (mdc != null) {
    124         mdc.clear0();
    125     }
    126   }
    127
    128
    129   private
    130   void put0(String key, Object o) {
    131     if(java1 || tlm == null) {
    132       return;
    133     } else {
    134       Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
    135       if(ht == null) {
    136         ht = new Hashtable(HT_SIZE);
    137         ((ThreadLocalMap)tlm).set(ht);
    138       }
    139       ht.put(key, o);
    140     }
    141   }
    142
    143   private
    144   Object get0(String key) {
    145     if(java1 || tlm == null) {
    146       return null;
    147     } else {
    148       Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
    149       if(ht != null && key != null) {
    150         return ht.get(key);
    151       } else {
    152         return null;
    153       }
    154     }
    155   }
    156
    157   private
    158   void remove0(String key) {
    159     if(!java1 && tlm != null) {
    160       Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
    161       if(ht != null) {
    162         ht.remove(key);
    163       }
    164     }
    165   }
    166
    167
    168   private
    169   Hashtable getContext0() {
    170      if(java1 || tlm == null) {
    171       return null;
    172     } else {
    173       return (Hashtable) ((ThreadLocalMap)tlm).get();
    174     }
    175   }
    176
    177   private
    178   void clear0() {
    179     if(!java1 && tlm != null) {
    180       Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
    181       if(ht != null) {
    182         ht.clear();
    183       }
    184     }
    185   }
    186
    187 }