All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ratpack.logging.MDCInterceptor Maven / Gradle / Ivy

There is a newer version: 2.0.0-rc-1
Show newest version
/*
 * Copyright 2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ratpack.logging;

import org.slf4j.MDC;
import ratpack.exec.ExecInterceptor;
import ratpack.exec.Execution;
import ratpack.util.Types;

import java.util.HashMap;
import java.util.Map;

/**
 * Intercept execution and add support for SLF4J MDC described in the manual.
 * 

* 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 {@code log4j2} configuration that assumes {@code value} as MDC context map value: * {@code * * * * } *

* When interceptor is registered with {@link ratpack.exec.ExecControl#addInterceptor}, it is possible to directly use SLF4J MDC API. * The {@link ratpack.exec.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. *

{@code
 * 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 values = new ArrayList();
 *     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);
 *   }
 * }
 * }
* * @see ratpack.exec.ExecControl#addInterceptor(ratpack.exec.ExecInterceptor, ratpack.func.NoArgAction) */ public class MDCInterceptor implements ExecInterceptor { private static class MDCMap extends HashMap { } public MDCInterceptor() { } public void intercept(Execution execution, ExecType type, Runnable continuation) { MDCMap map = execution.maybeGet(MDCMap.class).orElse(null); if (map == null) { map = new MDCMap(); execution.add(map); } MDC.setContextMap(map); continuation.run(); map.clear(); Map ctxMap = Types.cast(MDC.getCopyOfContextMap()); if (ctxMap != null && ctxMap.size() > 0) { map.putAll(ctxMap); MDC.clear(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy