Skip to content

Commit

Permalink
Added Action and a Filter for MDC. By default logs a UUID for each re…
Browse files Browse the repository at this point in the history
…quest.
  • Loading branch information
rishabh9 committed Feb 17, 2017
1 parent 3db2bf3 commit cd81838
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 39 deletions.
55 changes: 17 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,19 @@ A Mapped Diagnostic Context (MDC) propagation Akka Dispatcher for the asynchrono

#### How To Use

##### Configure Jitpack
1. Add the JitPack repository to your build file - build.sbt
```scala
resolvers += "jitpack" at "https://jitpack.io"
```
2. Add the dependency
```scala
libraryDependencies += "com.github.rishabh9" % "mdc-propagation-dispatcher" % "v0.0.1"
libraryDependencies += "com.github.rishabh9" % "mdc-propagation-dispatcher" % "v0.0.2"
```

##### Create a filter
3. Either add 'MappedDiagnosticContextFilter' to Filters.java
```java
public class MappedDiagnosticContextFilter extends Filter {
import zyx.cba.MappedDiagnosticContextFilter;

private final Executor exec;

/**
* @param mat This object is needed to handle streaming of requests
* and responses.
* @param exec This class is needed to execute code asynchronously.
* It is used below by the <code>thenAsyncApply</code> method.
*/
@Inject
public MappedDiagnosticContextFilter(Materializer mat, Executor exec) {
super(mat);
this.exec = exec;
}

@Override
public CompletionStage<Result> apply(Function<Http.RequestHeader, CompletionStage<Result>> next,
Http.RequestHeader requestHeader) {
MDC.put("X-UUID", java.util.UUID.randomUUID());
return next.apply(requestHeader).thenApplyAsync(
result -> {
MDC.remove("X-UUID");
return result;
},
exec
);
}
}
```

##### Add to Filters.java
```java
@Singleton
public class Filters implements HttpFilters {
private final MappedDiagnosticContextFilter mdcFilter;
Expand All @@ -75,18 +43,29 @@ public class Filters implements HttpFilters {
}
```

##### Update your logging configuration
Or annotate your controllers/methods with 'EnableMDC' annotation
```java
import zyx.cba.EnableMDC;
import play.mvc.Controller;

@EnableMDC
public class MyController extends Controller {
// ...
}
```

4. Update your logging configuration
```xml
<pattern>%d{HH:mm:ss.SSS} %coloredLevel %logger{35} %mdc{X-UUID:--} - %msg%n%rootException</pattern>
```

##### Update your application.conf
5. Update your application.conf
```hocon
play {
akka {
actor {
default-dispatcher {
type = "MDCPropagatingDispatcherConfigurator"
type = "zyx.cba.MDCPropagatingDispatcherConfigurator"
}
}
}
Expand Down
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ retrieveManaged := true

libraryDependencies ++= Seq(
"com.typesafe" % "config" % "1.3.0" % "provided",
"com.typesafe.play" %% "play" % "2.5.10" % "provided",
"org.slf4j" % "slf4j-api" % "1.7.21" % "provided",
"com.typesafe.akka" %% "akka-actor" % "2.4.12" % "provided"
)
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/zyx/cba/EnableMDC.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package zyx.cba;

import play.mvc.With;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author rishabh
*/
@With(MappedDiagnosticContextAction.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableMDC {
boolean value() default true;
}
26 changes: 26 additions & 0 deletions src/main/java/zyx/cba/MappedDiagnosticContextAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package zyx.cba;


import org.slf4j.MDC;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;

import java.util.UUID;
import java.util.concurrent.CompletionStage;

/**
* @author rishabh
*/
public class MappedDiagnosticContextAction extends Action<EnableMDC> {
public CompletionStage<Result> call(Http.Context ctx) {
if (configuration.value()) {
MDC.put("X-UUID", UUID.randomUUID().toString());
}
return delegate.call(ctx).whenComplete((result, throwable) -> {
if (configuration.value()) {
MDC.remove("X-UUID");
}
});
}
}
47 changes: 47 additions & 0 deletions src/main/java/zyx/cba/MappedDiagnosticContextFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package zyx.cba;

import akka.stream.Materializer;
import org.slf4j.MDC;
import play.mvc.Filter;
import play.mvc.Http;
import play.mvc.Result;

import javax.inject.Inject;
import java.util.UUID;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.function.Function;

/**
* @author rishabh
*/
public class MappedDiagnosticContextFilter extends Filter {

private final Executor exec;

/**
* @param mat This object is needed to handle streaming of requests
* and responses.
* @param exec This class is needed to execute code asynchronously.
* It is used below by the <code>thenAsyncApply</code> method.
*/
@Inject
public MappedDiagnosticContextFilter(Materializer mat, Executor exec) {
super(mat);
this.exec = exec;
}

@Override
public CompletionStage<Result> apply(Function<Http.RequestHeader, CompletionStage<Result>> next,
Http.RequestHeader requestHeader) {

MDC.put("X-UUID", UUID.randomUUID().toString());
return next.apply(requestHeader).thenApplyAsync(
result -> {
MDC.remove("X-UUID");
return result;
},
exec
);
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package zyx.cba

import java.util.concurrent.TimeUnit

import akka.dispatch._
Expand All @@ -16,7 +18,7 @@ import scala.concurrent.duration.{Duration, FiniteDuration}
* akka {
* actor {
* default-dispatcher = {
* type = "monitoring.MDCPropagatingDispatcherConfigurator"
* type = "zyx.cba.MDCPropagatingDispatcherConfigurator"
* }
* }
* }
Expand Down

0 comments on commit cd81838

Please sign in to comment.