continued work on MDC support

This commit is contained in:
Ceki Gulcu 2007-07-03 18:29:13 +00:00
parent 3f4e079e37
commit 64f2f15ef7
14 changed files with 306 additions and 81 deletions

View File

@ -39,6 +39,9 @@ import org.slf4j.spi.MDCAdapter;
* @author Ceki Gülcü
*/
public class MDC {
static final String NULL_MDCA_URL = "http://www.slf4j.org/codes.html#null_MDCA";
static final String NO_STATIC_MDC_BINDER_URL = "http://www.slf4j.org/codes.html#no_static_mdc_binder";
static MDCAdapter mdcAdapter;
private MDC() {
@ -47,9 +50,17 @@ public class MDC {
static {
try {
mdcAdapter = StaticMDCBinder.SINGLETON.getMDCA();
} catch(NoClassDefFoundError ncde) {
String msg = ncde.getMessage();
if(msg != null && msg.indexOf("org/slf4j/impl/StaticMDCBinder") != -1) {
Util.reportFailure("Failed to load class \"org.slf4j.impl.StaticMDCBinder\".");
Util.reportFailure("See "+NO_STATIC_MDC_BINDER_URL+" for further details.");
}
throw ncde;
} catch (Exception e) {
// we should never get here
Util.reportFailure("Could not instantiate instance of class ["
Util.reportFailure("Could not bind with an instance of class ["
+ StaticMDCBinder.SINGLETON.getMDCAdapterClassStr() + "]", e);
}
}
@ -61,6 +72,9 @@ public class MDC {
* method delegates all work to the MDC of the underlying logging system.
*/
public static void put(String key, String val) {
if(mdcAdapter == null) {
throw new IllegalStateException("MDCAdapter cannot be null. See also "+NULL_MDCA_URL);
}
mdcAdapter.put(key, val);
}
@ -71,6 +85,9 @@ public class MDC {
* @return the string value identified by the <code>key</code> parameter.
*/
public static String get(String key) {
if(mdcAdapter == null) {
throw new IllegalStateException("MDCAdapter cannot be null. See also "+NULL_MDCA_URL);
}
return mdcAdapter.get(key);
}
@ -79,13 +96,19 @@ public class MDC {
* the underlying system's MDC implementation.
*/
public static void remove(String key) {
if(mdcAdapter == null) {
throw new IllegalStateException("MDCAdapter cannot be null. See also "+NULL_MDCA_URL);
}
mdcAdapter.remove(key);
}
/**
* Clear all entries in the MDC of the underlying implementation.
*/
public void clear() {
public static void clear() {
if(mdcAdapter == null) {
throw new IllegalStateException("MDCAdapter cannot be null. See also "+NULL_MDCA_URL);
}
mdcAdapter.clear();
}

View File

@ -4,13 +4,22 @@ import junit.framework.TestCase;
public class NoBindingTest extends TestCase {
public void test() {
public void testLogger() {
try {
Logger logger = LoggerFactory.getLogger(NoBindingTest.class);
logger.debug("hello");
fail("slf4j-api does not ship with a binding");
} catch(NoClassDefFoundError e) {
Logger logger = LoggerFactory.getLogger(NoBindingTest.class);
logger.debug("hello");
fail("slf4j-api does not ship with a binding");
} catch (NoClassDefFoundError e) {
}
}
public void testMDC() {
try {
MDC.put("k", "v");
fail("slf4j-api does not ship with a binding");
} catch (NoClassDefFoundError e) {
}
}
}

View File

@ -0,0 +1,34 @@
package org.slf4j.impl;
import org.slf4j.helpers.NOPMakerAdapter;
import org.slf4j.spi.MDCAdapter;
/**
* This implementation is bound to {@link NOPMakerAdapter}.
*
* @author Ceki G&uuml;lc&uuml;
*/
public class StaticMDCBinder {
/**
* The unique instance of this class.
*/
public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
private StaticMDCBinder() {
}
/**
* Currently this method always returns an instance of
* {@link StaticMDCBinder}.
*/
public MDCAdapter getMDCA() {
return new NOPMakerAdapter();
}
public String getMDCAdapterClassStr() {
return NOPMakerAdapter.class.getName();
}
}

View File

@ -118,4 +118,11 @@ public class InvocationTest extends TestCase {
logger.warn(blue, "hello {} and {} ", "world", "universe");
logger.error(blue, "hello {} and {} ", "world", "universe");
}
public void testMDC() {
MDC.put("k", "v");
MDC.remove("k");
assertNull(MDC.get("k"));
MDC.clear();
}
}

View File

@ -18,7 +18,6 @@ public class StaticMDCBinder {
public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
private StaticMDCBinder() {
throw new UnsupportedOperationException("This code should never make it into the jar");
}
/**

View File

@ -118,4 +118,11 @@ public class InvocationTest extends TestCase {
logger.warn(blue, "hello {} and {} ", "world", "universe");
logger.error(blue, "hello {} and {} ", "world", "universe");
}
public void testMDC() {
MDC.put("k", "v");
MDC.remove("k");
assertNull(MDC.get("k"));
MDC.clear();
}
}

View File

@ -0,0 +1,33 @@
package org.slf4j.impl;
import org.slf4j.spi.MDCAdapter;
/**
* This implementation is bound to {@link Log4jMDCAdapter}.
*
* @author Ceki G&uuml;lc&uuml;
*/
public class StaticMDCBinder {
/**
* The unique instance of this class.
*/
public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
private StaticMDCBinder() {
}
/**
* Currently this method always returns an instance of
* {@link StaticMDCBinder}.
*/
public MDCAdapter getMDCA() {
return new Log4jMDCAdapter();
}
public String getMDCAdapterClassStr() {
return Log4jMDCAdapter.class.getName();
}
}

View File

@ -0,0 +1,34 @@
package org.slf4j.impl;
import org.slf4j.helpers.NOPMakerAdapter;
import org.slf4j.spi.MDCAdapter;
/**
* This implementation is bound to {@link NOPMakerAdapter}.
*
* @author Ceki G&uuml;lc&uuml;
*/
public class StaticMDCBinder {
/**
* The unique instance of this class.
*/
public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
private StaticMDCBinder() {
}
/**
* Currently this method always returns an instance of
* {@link StaticMDCBinder}.
*/
public MDCAdapter getMDCA() {
return new NOPMakerAdapter();
}
public String getMDCAdapterClassStr() {
return NOPMakerAdapter.class.getName();
}
}

View File

@ -118,4 +118,11 @@ public class InvocationTest extends TestCase {
logger.warn(blue, "hello {} and {} ", "world", "universe");
logger.error(blue, "hello {} and {} ", "world", "universe");
}
public void testMDC() {
MDC.put("k", "v");
MDC.remove("k");
assertNull(MDC.get("k"));
MDC.clear();
}
}

View File

@ -1,34 +1,25 @@
/*
* Copyright (c) 2004-2005 SLF4J.ORG
* Copyright (c) 2004-2005 QOS.ch
*
/*
* Copyright (c) 2004-2007 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
* OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
* SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
* of the copyright holder.
*
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.slf4j.impl;

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2004-2007 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.slf4j.impl;
import org.slf4j.helpers.NOPMakerAdapter;
import org.slf4j.spi.MDCAdapter;
/**
* This implementation is bound to {@link NOPMakerAdapter}.
*
* @author Ceki G&uuml;lc&uuml;
*/
public class StaticMDCBinder {
/**
* The unique instance of this class.
*/
public static final StaticMDCBinder SINGLETON = new StaticMDCBinder();
private StaticMDCBinder() {
}
/**
* Currently this method always returns an instance of
* {@link StaticMDCBinder}.
*/
public MDCAdapter getMDCA() {
return new NOPMakerAdapter();
}
public String getMDCAdapterClassStr() {
return NOPMakerAdapter.class.getName();
}
}

View File

@ -1,36 +1,28 @@
/*
* Copyright (c) 2004-2005 SLF4J.ORG
* Copyright (c) 2004-2005 QOS.ch
*
/*
* Copyright (c) 2004-2007 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
* OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
* SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Except as contained in this notice, the name of a copyright holder
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
* of the copyright holder.
*
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.slf4j.impl;
import org.slf4j.IMarkerFactory;

View File

@ -1,6 +1,5 @@
/*
* Copyright (c) 2004-2005 SLF4J.ORG
* Copyright (c) 2004-2005 QOS.CH
* Copyright (c) 2004-2007 QOS.CH
*
* All rights reserved.
*
@ -118,4 +117,11 @@ public class InvocationTest extends TestCase {
logger.warn(blue, "hello {} and {} ", "world", "universe");
logger.error(blue, "hello {} and {} ", "world", "universe");
}
public void testMDC() {
MDC.put("k", "v");
MDC.remove("k");
assertNull(MDC.get("k"));
MDC.clear();
}
}

View File

@ -20,9 +20,8 @@ prefix='';
<div id="content">
<center>
<h2>SLF4J warning or error messages and their meanings</h2>
<h3>Ceki G&#252;lc&#252; <br/>
created May 2006, last updated on May 2006</h3>
<h2>SLF4J warning or error messages and their meanings</h2>
</center>
@ -47,7 +46,7 @@ prefix='';
<p>This is a relatively common occurrence with recent versions of
Tomcat, especially if you place <em>jcl104-over-slf4j.jar</em> in
<em>WEB-INF/lib</em> directory of your web-application instead of
<em>$TOMCAT_HOME/common/lib</em> where $TOMCAT_HOME stands for the
<em>$TOMCAT_HOME/common/lib</em>, where $TOMCAT_HOME stands for the
directory where Tomcat is installed. In order to fully benefit
from the stability offered by <em>jcl104-over-slf4j.jar</em>, we
recommend that you place <em>jcl104-over-slf4j.jar</em> in
@ -59,19 +58,7 @@ prefix='';
href="http://bugzilla.slf4j.org/show_bug.cgi?id=22">bug
#22</a>.</p>
<a name="null_LF">
</a>
<h3>Logging factory implementation cannot be null</h3>
<p>This error is reported when the <code>LoggerFactory</code>
class could not find an appropriate binding, indicating that no
appropriate SLF4J binding could be found. Placing one of
<em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>,
<em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or
<em>logback-classic.jar</em> on the class path should prove to be
an effective remedy.
</p>
<a name="StaticLoggerBinder">
</a>
@ -82,13 +69,51 @@ prefix='';
<p>This error is reported when the
<code>org.slf4j.impl.StaticLoggerBinder</code> class could not be
loaded into memory. This happens when no appropriate SLF4J
binding could be found on the class path. Placing one of
binding could be found on the class path. Placing one (and only
one) of <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>,
<em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or
<em>logback-classic.jar</em> on the class path should solve the
problem.
</p>
<a name="null_LF">
</a>
<h3>Logging factory implementation cannot be null</h3>
<p>This error is reported when the <code>LoggerFactory</code>
class could not find an appropriate binding. Placing one (and only
one) of <em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>,
<em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or
<em>logback-classic.jar</em> on the class path should prove to be
an effective remedy.
</p>
<a name="no_static_mdc_binder">
</a>
<h3>Failed to load class "org.slf4j.impl.StaticMDCBinder".</h3>
<p>This error indicates that appropriate SLF4J binding could be
found on the class path. Placing one (and only one) of
<em>slf4j-nop.jar</em>, <em>slf4j-simple.jar</em>,
<em>slf4j-log4j12.jar</em>, <em>slf4j-jdk14.jar</em> or
<em>logback-classic.jar</em> on the class path should solve the
problem.
</p>
<a name="null_MDCA">
</a>
<h3>MDCAdapter cannot be null</h3>
<p>This error is reported when <code>org.slf4j.MDC</code> class
has not been initialized correctly. Same cause and remedy as the
previously listed item.
</p>
</div>
</body>