public class MDCInterceptor extends Object implements ExecInterceptor
Mapped Diagnostic Context (MDC) is a map of key-value pairs provided by client code and then automatically inserted in log messages.
The underlying logging framework has to support MDC logging.
Example log4j2
configuration that assumes value
as MDC context map value:
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg - [%X{value}] %n"/>
</Console>
When interceptor is registered with ExecControl.addInterceptor(ratpack.exec.ExecInterceptor, ratpack.func.NoArgAction)
, it is possible to directly use SLF4J MDC API.
The Execution
, as registry, maintains own map of MDC entries.
Before running the continuation, it checks if internal map contains any entry.
If yes, it puts all of them from internal map to MDC (bounded to current thread).
If internal map is empty, it clears MDC.
After continuation it gets the entries from MDC's context map and stores them in execution's internal map.
import java.util.List;
import java.util.ArrayList;
import ratpack.test.handling.RequestFixture;
import ratpack.test.handling.HandlingResult;
import org.slf4j.MDC;
import static org.junit.Assert.assertTrue;
import ratpack.logging.MDCInterceptor;
public class MDCInterceptorExample {
public static void main(String[] args) throws Exception {
List<String> values = new ArrayList<String>();
HandlingResult result = RequestFixture.requestFixture().handleChain(chain -> {
chain
.handler(ctx ->
ctx.addInterceptor(new MDCInterceptor(), ctx::next)
)
.handler(ctx -> {
MDC.put("value", "foo");
values.add(MDC.get("value"));
ctx.blocking(() -> {
values.add(MDC.get("value"));
return "bar3";
}).then(str -> {
values.add(MDC.get("value"));
ctx.render(str);
});
});
});
assertTrue(values.size() == 3);
}
}
ExecInterceptor.ExecType
Constructor and Description |
---|
MDCInterceptor() |
Modifier and Type | Method and Description |
---|---|
void |
intercept(Execution execution,
ExecInterceptor.ExecType type,
Runnable continuation)
Intercepts the “rest” of the execution on the current thread.
|
public void intercept(Execution execution, ExecInterceptor.ExecType type, Runnable continuation)
ExecInterceptor
The given Runnable
argument represents the rest of the execution to occur on this thread.
This does not necessarily mean the rest of the execution until the work (e.g. responding to a request) is complete.
Execution may involve multiple parallel (but not concurrent) threads of execution because of blocking IO or asynchronous APIs.
All exceptions thrown by this method will be ignored.
intercept
in interface ExecInterceptor
execution
- the execution who's segment is being interceptedtype
- indicates whether this is a compute (e.g. request handling) or blocking IO threadcontinuation
- the “rest” of the execution