1 /* 2 * Copyright (c) 2004-2007 QOS.ch 3 * All rights reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 package org.slf4j; 26 27 import org.slf4j.helpers.Util; 28 import org.slf4j.impl.StaticMDCBinder; 29 import org.slf4j.spi.MDCAdapter; 30 31 /** 32 * This class hides and serves as a substitute for the underlying logging 33 * system's MDC implementation. 34 * 35 * <p> 36 * If the underlying logging system offers MDC functionality, then SLF4J's MDC, 37 * i.e. this class, will delegate to the underlying system's MDC. Note that at 38 * this time, only two logging systems, namely log4j and logback, offer MDC 39 * functionality. If the undelying system does not support MDC, then SLF4J will 40 * silently drop MDC information. 41 * 42 * <p> 43 * Thus, as a SLF4J user, you can take advantage of MDC in the presence of log4j 44 * or logback, but without forcing log4j or logback as dependencies upon your 45 * users. 46 * 47 * <p> 48 * For more information on MDC please see the <a 49 * href="http://logback.qos.ch/manual/mdc.html">chapter on MDC</a> in the 50 * logback manual. 51 * 52 * <p> 53 * Please note that all methods in this class are static. 54 * 55 * @author Ceki Gülcü 56 * @since 1.4.1 57 */ 58 public class MDC { 59 60 static final String NULL_MDCA_URL = "http://www.slf4j.org/codes.html#null_MDCA"; 61 static final String NO_STATIC_MDC_BINDER_URL = "http://www.slf4j.org/codes.html#no_static_mdc_binder"; 62 static MDCAdapter mdcAdapter; 63 64 private MDC() { 65 } 66 67 static { 68 try { 69 mdcAdapter = StaticMDCBinder.SINGLETON.getMDCA(); 70 } catch (NoClassDefFoundError ncde) { 71 String msg = ncde.getMessage(); 72 if (msg != null && msg.indexOf("org/slf4j/impl/StaticMDCBinder") != -1) { 73 Util 74 .reportFailure("Failed to load class \"org.slf4j.impl.StaticMDCBinder\"."); 75 Util.reportFailure("See " + NO_STATIC_MDC_BINDER_URL 76 + " for further details."); 77 78 } 79 throw ncde; 80 } catch (Exception e) { 81 // we should never get here 82 Util.reportFailure("Could not bind with an instance of class [" 83 + StaticMDCBinder.SINGLETON.getMDCAdapterClassStr() + "]", e); 84 } 85 } 86 87 /** 88 * Put a context value (the <code>val</code> parameter) as identified with 89 * the <code>key</code> parameter into the current thread's context map. 90 * The <code>key</code> parameter cannot be null. The code>val</code> parameter 91 * can be null only if the underlying implementation supports it. 92 * 93 * <p> 94 * This method delegates all work to the MDC of the underlying logging system. 95 * 96 * @throws IllegalArgumentException in case the "key" parameter is null 97 */ 98 public static void put(String key, String val) throws IllegalArgumentException { 99 if (key == null) { 100 throw new IllegalArgumentException("key parameter cannot be null"); 101 } 102 if (mdcAdapter == null) { 103 throw new IllegalStateException("MDCAdapter cannot be null. See also " 104 + NULL_MDCA_URL); 105 } 106 mdcAdapter.put(key, val); 107 } 108 109 /** 110 * Get the context identified by the <code>key</code> parameter. The 111 * <code>key</code> parameter cannot be null. 112 * 113 * <p>This method delegates all work to the MDC of the underlying logging system. 114 * 115 * @return the string value identified by the <code>key</code> parameter. 116 * @throws IllegalArgumentException in case the "key" parameter is null 117 */ 118 public static String get(String key) throws IllegalArgumentException { 119 if (key == null) { 120 throw new IllegalArgumentException("key parameter cannot be null"); 121 } 122 123 if (mdcAdapter == null) { 124 throw new IllegalStateException("MDCAdapter cannot be null. See also " 125 + NULL_MDCA_URL); 126 } 127 return mdcAdapter.get(key); 128 } 129 130 /** 131 * Remove the the context identified by the <code>key</code> parameter using 132 * the underlying system's MDC implementation. The <code>key</code> parameter 133 * cannot be null. This method does nothing if there is no previous value 134 * associated with <code>key</code>. 135 * 136 * @throws IllegalArgumentException in case the "key" parameter is null 137 */ 138 public static void remove(String key) throws IllegalArgumentException { 139 if (key == null) { 140 throw new IllegalArgumentException("key parameter cannot be null"); 141 } 142 143 if (mdcAdapter == null) { 144 throw new IllegalStateException("MDCAdapter cannot be null. See also " 145 + NULL_MDCA_URL); 146 } 147 mdcAdapter.remove(key); 148 } 149 150 /** 151 * Clear all entries in the MDC of the underlying implementation. 152 */ 153 public static void clear() { 154 if (mdcAdapter == null) { 155 throw new IllegalStateException("MDCAdapter cannot be null. See also " 156 + NULL_MDCA_URL); 157 } 158 mdcAdapter.clear(); 159 } 160 161 /** 162 * Returns the MDCAdapter instance currently in use. 163 * 164 * @return the MDcAdapter instance currently in use. 165 * @since 1.4.2 166 */ 167 public static MDCAdapter getMDCAdapter() { 168 return mdcAdapter; 169 } 170 }