mirror of https://github.com/qos-ch/slf4j
add support for keyed deques in MDC
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
This commit is contained in:
parent
12b5a6b676
commit
f09e33dd15
|
|
@ -25,6 +25,7 @@
|
|||
package org.slf4j;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.Deque;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.helpers.BasicMDCAdapter;
|
||||
|
|
@ -64,6 +65,7 @@ import org.slf4j.spi.SLF4JServiceProvider;
|
|||
public class MDC {
|
||||
|
||||
static final String NULL_MDCA_URL = "http://www.slf4j.org/codes.html#null_MDCA";
|
||||
private static final String MDC_APAPTER_CANNOT_BE_NULL_MESSAGE = "MDCAdapter cannot be null. See also " + NULL_MDCA_URL;
|
||||
static final String NO_STATIC_MDC_BINDER_URL = "http://www.slf4j.org/codes.html#no_static_mdc_binder";
|
||||
static MDCAdapter mdcAdapter;
|
||||
|
||||
|
|
@ -116,7 +118,7 @@ public class MDC {
|
|||
throw new IllegalArgumentException("key parameter cannot be null");
|
||||
}
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.put(key, val);
|
||||
}
|
||||
|
|
@ -172,7 +174,7 @@ public class MDC {
|
|||
}
|
||||
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
return mdcAdapter.get(key);
|
||||
}
|
||||
|
|
@ -193,7 +195,7 @@ public class MDC {
|
|||
}
|
||||
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.remove(key);
|
||||
}
|
||||
|
|
@ -203,7 +205,7 @@ public class MDC {
|
|||
*/
|
||||
public static void clear() {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.clear();
|
||||
}
|
||||
|
|
@ -217,7 +219,7 @@ public class MDC {
|
|||
*/
|
||||
public static Map<String, String> getCopyOfContextMap() {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
return mdcAdapter.getCopyOfContextMap();
|
||||
}
|
||||
|
|
@ -235,7 +237,7 @@ public class MDC {
|
|||
*/
|
||||
public static void setContextMap(Map<String, String> contextMap) {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException("MDCAdapter cannot be null. See also " + NULL_MDCA_URL);
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.setContextMap(contextMap);
|
||||
}
|
||||
|
|
@ -250,4 +252,48 @@ public class MDC {
|
|||
return mdcAdapter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Push a value into the deque(stack) referenced by 'key'.
|
||||
*
|
||||
* @param key identifies the appropriate stack
|
||||
* @param value the value to push into the stack
|
||||
* @since 2.0.0
|
||||
*/
|
||||
static public void pushByKey(String key, String value) {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
mdcAdapter.pushByKey(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the stack referenced by 'key' and return the value possibly null.
|
||||
*
|
||||
* @param key identifies the deque(stack)
|
||||
* @return the value just popped. May be null/
|
||||
* @since 2.0.0
|
||||
*/
|
||||
static public String popByKey(String key) {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
return mdcAdapter.popByKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the deque(stack) referenced by 'key'. May be null.
|
||||
*
|
||||
* @param key identifies the stack
|
||||
* @return copy of stack referenced by 'key'. May be null.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public Deque<String> getCopyOfDequeByKey(String key) {
|
||||
if (mdcAdapter == null) {
|
||||
throw new IllegalStateException(MDC_APAPTER_CANNOT_BE_NULL_MESSAGE);
|
||||
}
|
||||
return mdcAdapter.getCopyOfDequeByKey(key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import java.util.*;
|
|||
*/
|
||||
public class BasicMDCAdapter implements MDCAdapter {
|
||||
|
||||
private final ThreadLocalMapOfStacks threadLocalMapOfStacks = new ThreadLocalMapOfStacks();
|
||||
private final ThreadLocalMapOfStacks threadLocalMapOfDeques = new ThreadLocalMapOfStacks();
|
||||
|
||||
private final InheritableThreadLocal<Map<String, String>> inheritableThreadLocalMap = new InheritableThreadLocal<Map<String, String>>() {
|
||||
@Override
|
||||
|
|
@ -151,16 +151,20 @@ public class BasicMDCAdapter implements MDCAdapter {
|
|||
|
||||
@Override
|
||||
public void pushByKey(String key, String value) {
|
||||
threadLocalMapOfStacks.pushByKey(key, value);
|
||||
threadLocalMapOfDeques.pushByKey(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String popByKey(String key) {
|
||||
return threadLocalMapOfStacks.popByKey(key);
|
||||
return threadLocalMapOfDeques.popByKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deque<String> getCopyOfStackByKey(String key) {
|
||||
return threadLocalMapOfStacks.getCopyOfStackByKey(key);
|
||||
public Deque<String> getCopyOfDequeByKey(String key) {
|
||||
return threadLocalMapOfDeques.getCopyOfDequeByKey(key);
|
||||
}
|
||||
@Override
|
||||
public void clearDequeByKey(String key) {
|
||||
threadLocalMapOfDeques.clearDequeByKey(key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,8 +71,11 @@ public class NOPMDCAdapter implements MDCAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Deque<String> getCopyOfStackByKey(String key) {
|
||||
public Deque<String> getCopyOfDequeByKey(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clearDequeByKey(String key) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,14 @@ import java.util.Deque;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* A simple implementation of ThreadLocal backed Map containing values of type
|
||||
* Deque<String>.
|
||||
*
|
||||
* @author Ceki Guuml;cü
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class ThreadLocalMapOfStacks {
|
||||
|
||||
final ThreadLocal<Map<String, Deque<String>>> tlMapOfStacks = new ThreadLocal<>();
|
||||
|
|
@ -20,12 +28,12 @@ public class ThreadLocalMapOfStacks {
|
|||
tlMapOfStacks.set(map);
|
||||
}
|
||||
|
||||
Deque<String> stack = map.get(key);
|
||||
if (stack == null) {
|
||||
stack = new ArrayDeque<>();
|
||||
Deque<String> deque = map.get(key);
|
||||
if (deque == null) {
|
||||
deque = new ArrayDeque<>();
|
||||
}
|
||||
stack.push(value);
|
||||
map.put(key, stack);
|
||||
deque.push(value);
|
||||
map.put(key, deque);
|
||||
}
|
||||
|
||||
public String popByKey(String key) {
|
||||
|
|
@ -35,24 +43,44 @@ public class ThreadLocalMapOfStacks {
|
|||
Map<String, Deque<String>> map = tlMapOfStacks.get();
|
||||
if (map == null)
|
||||
return null;
|
||||
Deque<String> stack = map.get(key);
|
||||
if (stack == null)
|
||||
Deque<String> deque = map.get(key);
|
||||
if (deque == null)
|
||||
return null;
|
||||
return stack.pop();
|
||||
return deque.pop();
|
||||
}
|
||||
|
||||
public Deque<String> getCopyOfStackByKey(String key) {
|
||||
public Deque<String> getCopyOfDequeByKey(String key) {
|
||||
if (key == null)
|
||||
return null;
|
||||
|
||||
Map<String, Deque<String>> map = tlMapOfStacks.get();
|
||||
if (map == null)
|
||||
return null;
|
||||
Deque<String> stack = map.get(key);
|
||||
if (stack == null)
|
||||
Deque<String> deque = map.get(key);
|
||||
if (deque == null)
|
||||
return null;
|
||||
|
||||
return new ArrayDeque<String>(stack);
|
||||
return new ArrayDeque<String>(deque);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the deque(stack) referenced by 'key'.
|
||||
*
|
||||
* @param key identifies the stack
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public void clearDequeByKey(String key) {
|
||||
if (key == null)
|
||||
return;
|
||||
|
||||
Map<String, Deque<String>> map = tlMapOfStacks.get();
|
||||
if (map == null)
|
||||
return;
|
||||
Deque<String> deque = map.get(key);
|
||||
if (deque == null)
|
||||
return;
|
||||
deque.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ public interface MDCAdapter {
|
|||
public void setContextMap(Map<String, String> contextMap);
|
||||
|
||||
/**
|
||||
* Push a value into the stack referenced by 'key'.
|
||||
* *
|
||||
* Push a value into the deque(stack) referenced by 'key'.
|
||||
*
|
||||
* @param key identifies the appropriate stack
|
||||
* @param value the value to push into the stack
|
||||
* @since 2.0.0
|
||||
|
|
@ -104,19 +104,30 @@ public interface MDCAdapter {
|
|||
/**
|
||||
* Pop the stack referenced by 'key' and return the value possibly null.
|
||||
*
|
||||
* @param key identifies the stack
|
||||
* @param key identifies the deque(stack)
|
||||
* @return the value just popped. May be null/
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public String popByKey(String key);
|
||||
|
||||
/**
|
||||
* Returns a copy of the stack referenced by 'key'. May be null.
|
||||
* Returns a copy of the deque(stack) referenced by 'key'. May be null.
|
||||
*
|
||||
* @param key identifies the stack
|
||||
* @return copy of stack referenced by 'key'. May be null.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public Deque<String> getCopyOfStackByKey(String key);
|
||||
public Deque<String> getCopyOfDequeByKey(String key);
|
||||
|
||||
|
||||
/**
|
||||
* Clear the deque(stack) referenced by 'key'.
|
||||
*
|
||||
* @param key identifies the stack
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public void clearDequeByKey(String key);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import org.slf4j.spi.MDCAdapter;
|
|||
|
||||
public class Log4jMDCAdapter implements MDCAdapter {
|
||||
|
||||
private final ThreadLocalMapOfStacks threadLocalMapOfStacks = new ThreadLocalMapOfStacks();
|
||||
private final ThreadLocalMapOfStacks threadLocalMapOfDeques = new ThreadLocalMapOfStacks();
|
||||
|
||||
static {
|
||||
if (VersionUtil.getJavaMajorVersion() >= 9) {
|
||||
|
|
@ -113,17 +113,21 @@ public class Log4jMDCAdapter implements MDCAdapter {
|
|||
|
||||
@Override
|
||||
public void pushByKey(String key, String value) {
|
||||
threadLocalMapOfStacks.pushByKey(key, value);
|
||||
threadLocalMapOfDeques.pushByKey(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String popByKey(String key) {
|
||||
return threadLocalMapOfStacks.popByKey(key);
|
||||
return threadLocalMapOfDeques.popByKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Deque<String> getCopyOfStackByKey(String key) {
|
||||
return threadLocalMapOfStacks.getCopyOfStackByKey(key);
|
||||
public Deque<String> getCopyOfDequeByKey(String key) {
|
||||
return threadLocalMapOfDeques.getCopyOfDequeByKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearDequeByKey(String key) {
|
||||
threadLocalMapOfDeques.clearDequeByKey(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue