aboutsummaryrefslogtreecommitdiff
path: root/kamon-play
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2015-01-12 01:45:27 +0100
committerIvan Topolnjak <ivantopo@gmail.com>2015-01-24 23:19:01 +0100
commit01a34f67ff75419c440f2e69c0a0db888a670a34 (patch)
tree9c4dee4e9c13c26937356950f9e4927c3f9dfb7d /kamon-play
parent4a47e92d23af371f1d50b40af6cbe00a5ffc0105 (diff)
downloadKamon-01a34f67ff75419c440f2e69c0a0db888a670a34.tar.gz
Kamon-01a34f67ff75419c440f2e69c0a0db888a670a34.tar.bz2
Kamon-01a34f67ff75419c440f2e69c0a0db888a670a34.zip
! all: improve the metric recorders infrastructure
Diffstat (limited to 'kamon-play')
-rw-r--r--kamon-play/src/main/resources/reference.conf2
-rw-r--r--kamon-play/src/main/scala/kamon/play/Play.scala10
-rw-r--r--kamon-play/src/main/scala/kamon/play/action/KamonTraceActions.scala4
-rw-r--r--kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala25
-rw-r--r--kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala7
-rw-r--r--kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala31
-rw-r--r--kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala32
7 files changed, 60 insertions, 51 deletions
diff --git a/kamon-play/src/main/resources/reference.conf b/kamon-play/src/main/resources/reference.conf
index 5ad070ce..7456bbb4 100644
--- a/kamon-play/src/main/resources/reference.conf
+++ b/kamon-play/src/main/resources/reference.conf
@@ -21,6 +21,6 @@ kamon {
# to traces and client http segments.
name-generator = kamon.play.DefaultPlayNameGenerator
- dispatcher = ${kamon.default-dispatcher}
+ dispatcher = "akka.actor.default-dispatcher"
}
} \ No newline at end of file
diff --git a/kamon-play/src/main/scala/kamon/play/Play.scala b/kamon-play/src/main/scala/kamon/play/Play.scala
index 6c6cbf4c..7ca81028 100644
--- a/kamon-play/src/main/scala/kamon/play/Play.scala
+++ b/kamon-play/src/main/scala/kamon/play/Play.scala
@@ -20,7 +20,7 @@ import akka.actor.{ ExtendedActorSystem, Extension, ExtensionId, ExtensionIdProv
import akka.event.Logging
import kamon.Kamon
import kamon.http.HttpServerMetrics
-import kamon.metric.Metrics
+import kamon.metric.{ Entity, Metrics }
import play.api.libs.ws.WSRequest
import play.api.mvc.RequestHeader
@@ -36,8 +36,14 @@ class PlayExtension(private val system: ExtendedActorSystem) extends Kamon.Exten
log.info(s"Starting the Kamon(Play) extension")
private val config = system.settings.config.getConfig("kamon.play")
+ val httpServerMetrics = {
+ val metricsExtension = Metrics.get(system)
+ val factory = metricsExtension.instrumentFactory(HttpServerMetrics.category)
+ val entity = Entity("play-server", HttpServerMetrics.category)
+
+ Metrics.get(system).register(entity, new HttpServerMetrics(factory)).recorder
+ }
- val httpServerMetrics = Kamon(Metrics)(system).register(HttpServerMetrics, HttpServerMetrics.Factory).get
val defaultDispatcher = system.dispatchers.lookup(config.getString("dispatcher"))
val includeTraceToken: Boolean = config.getBoolean("automatic-trace-token-propagation")
val traceTokenHeaderName: String = config.getString("trace-token-header-name")
diff --git a/kamon-play/src/main/scala/kamon/play/action/KamonTraceActions.scala b/kamon-play/src/main/scala/kamon/play/action/KamonTraceActions.scala
index 36eabf8e..715cac5e 100644
--- a/kamon-play/src/main/scala/kamon/play/action/KamonTraceActions.scala
+++ b/kamon-play/src/main/scala/kamon/play/action/KamonTraceActions.scala
@@ -16,13 +16,13 @@
package kamon.play.action
-import kamon.trace.TraceRecorder
+import kamon.trace.TraceContext
import play.api.mvc._
import scala.concurrent.Future
case class TraceName[A](name: String)(action: Action[A]) extends Action[A] {
def apply(request: Request[A]): Future[Result] = {
- TraceRecorder.rename(name)
+ TraceContext.currentContext.rename(name)
action(request)
}
lazy val parser = action.parser
diff --git a/kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala b/kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala
index 1bafa8ff..38f499b4 100644
--- a/kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala
+++ b/kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala
@@ -18,7 +18,7 @@ package kamon.play.instrumentation
import kamon.Kamon
import kamon.play.{ Play, PlayExtension }
import kamon.trace.TraceLocal.{ HttpContextKey, HttpContext }
-import kamon.trace.{ TraceLocal, TraceContextAware, TraceRecorder }
+import kamon.trace._
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation._
import play.api.Routes
@@ -41,15 +41,17 @@ class RequestInstrumentation {
@Before("call(* play.api.GlobalSettings.onRouteRequest(..)) && args(requestHeader)")
def beforeRouteRequest(requestHeader: RequestHeader): Unit = {
- val system = Akka.system()
- val playExtension = Kamon(Play)(system)
- val defaultTraceName = playExtension.generateTraceName(requestHeader)
+ implicit val system = Akka.system()
+ val playExtension = Kamon(Play)
+ val tracer = Kamon(Tracer)
+ val defaultTraceName = playExtension.generateTraceName(requestHeader)
val token = if (playExtension.includeTraceToken) {
requestHeader.headers.toSimpleMap.find(_._1 == playExtension.traceTokenHeaderName).map(_._2)
} else None
- TraceRecorder.start(defaultTraceName, token)(system)
+ val newContext = token.map(t ⇒ tracer.newContext(defaultTraceName, t)).getOrElse(tracer.newContext(defaultTraceName))
+ TraceContext.setCurrentContext(newContext)
}
@Around("call(* play.api.GlobalSettings.doFilter(*)) && args(next)")
@@ -59,11 +61,10 @@ class RequestInstrumentation {
val executor = Kamon(Play)(Akka.system()).defaultDispatcher
def onResult(result: Result): Result = {
- TraceRecorder.withTraceContextAndSystem { (ctx, system) ⇒
+ TraceContext.map { ctx ⇒
ctx.finish()
- val playExtension = Kamon(Play)(system)
-
+ val playExtension = ctx.lookupExtension(Play)
recordHttpServerMetrics(result.header, ctx.name, playExtension)
if (playExtension.includeTraceToken) result.withHeaders(playExtension.traceTokenHeaderName -> ctx.token)
@@ -75,7 +76,7 @@ class RequestInstrumentation {
storeDiagnosticData(requestHeader)
//override the current trace name
- normaliseTraceName(requestHeader).map(TraceRecorder.rename)
+ normaliseTraceName(requestHeader).map(TraceContext.currentContext.rename)
// Invoke the action
next(requestHeader).map(onResult)(executor)
@@ -85,8 +86,8 @@ class RequestInstrumentation {
@Before("call(* play.api.GlobalSettings.onError(..)) && args(request, ex)")
def beforeOnError(request: TraceContextAware, ex: Throwable): Unit = {
- TraceRecorder.withTraceContextAndSystem { (ctx, system) ⇒
- recordHttpServerMetrics(InternalServerError.header, ctx.name, Kamon(Play)(system))
+ TraceContext.map { ctx ⇒
+ recordHttpServerMetrics(InternalServerError.header, ctx.name, ctx.lookupExtension(Play))
}
}
@@ -102,7 +103,7 @@ class RequestInstrumentation {
}
object RequestInstrumentation {
- import kamon.metric.Metrics.AtomicGetOrElseUpdateForTriemap
+ import kamon.util.TriemapAtomicGetOrElseUpdate.Syntax
import java.util.Locale
import scala.collection.concurrent.TrieMap
diff --git a/kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala b/kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala
index fca13c4c..fc58f9da 100644
--- a/kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala
+++ b/kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala
@@ -16,9 +16,8 @@
package kamon.play.instrumentation
-import kamon.Kamon
import kamon.play.Play
-import kamon.trace.{ SegmentCategory, TraceRecorder }
+import kamon.trace.{ TraceContext, SegmentCategory }
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.{ Around, Aspect, Pointcut }
import play.api.libs.ws.{ WSRequest, WSResponse }
@@ -33,8 +32,8 @@ class WSInstrumentation {
@Around("onExecuteRequest(request)")
def aroundExecuteRequest(pjp: ProceedingJoinPoint, request: WSRequest): Any = {
- TraceRecorder.withTraceContextAndSystem { (ctx, system) ⇒
- val playExtension = Kamon(Play)(system)
+ TraceContext.map { ctx ⇒
+ val playExtension = ctx.lookupExtension(Play)
val executor = playExtension.defaultDispatcher
val segmentName = playExtension.generateHttpClientSegmentName(request)
val segment = ctx.startSegment(segmentName, SegmentCategory.HttpClient, Play.SegmentLibraryName)
diff --git a/kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala b/kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala
index 564d5abe..0feecb82 100644
--- a/kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala
+++ b/kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala
@@ -17,10 +17,11 @@ package kamon.play
import kamon.Kamon
import kamon.http.HttpServerMetrics
-import kamon.metric.{ CollectionContext, Metrics, TraceMetrics }
+import kamon.metric.{ Metrics, TraceMetrics }
+import kamon.metric.instrument.CollectionContext
import kamon.play.action.TraceName
import kamon.trace.TraceLocal.HttpContextKey
-import kamon.trace.{ TraceLocal, TraceRecorder }
+import kamon.trace.{ TraceLocal, TraceContext }
import org.scalatestplus.play._
import play.api.DefaultGlobal
import play.api.http.Writeable
@@ -118,7 +119,7 @@ class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
"respond to the Async Action with X-Trace-Token and the renamed trace" in {
val result = Await.result(route(FakeRequest(GET, "/async-renamed").withHeaders(traceTokenHeader)).get, 10 seconds)
- TraceRecorder.currentContext.name must be("renamed-trace")
+ TraceContext.currentContext.name must be("renamed-trace")
Some(result.header.headers(traceTokenHeaderName)) must be(expectedToken)
}
@@ -129,17 +130,17 @@ class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
"response to the getRouted Action and normalise the current TraceContext name" in {
Await.result(WS.url("http://localhost:19001/getRouted").get(), 10 seconds)
- Kamon(Metrics)(Akka.system()).storage.get(TraceMetrics("getRouted.get")) must not be empty
+ Kamon(Metrics)(Akka.system()).find("getRouted.get", "trace") must not be empty
}
"response to the postRouted Action and normalise the current TraceContext name" in {
Await.result(WS.url("http://localhost:19001/postRouted").post("content"), 10 seconds)
- Kamon(Metrics)(Akka.system()).storage.get(TraceMetrics("postRouted.post")) must not be empty
+ Kamon(Metrics)(Akka.system()).find("postRouted.post", "trace") must not be empty
}
"response to the showRouted Action and normalise the current TraceContext name" in {
Await.result(WS.url("http://localhost:19001/showRouted/2").get(), 10 seconds)
- Kamon(Metrics)(Akka.system()).storage.get(TraceMetrics("show.some.id.get")) must not be empty
+ Kamon(Metrics)(Akka.system()).find("show.some.id.get", "trace") must not be empty
}
"include HttpContext information for help to diagnose possible errors" in {
@@ -154,7 +155,7 @@ class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
"record http server metrics for all processed requests" in {
val collectionContext = CollectionContext(100)
- Kamon(Metrics)(Akka.system()).register(HttpServerMetrics, HttpServerMetrics.Factory).get.collect(collectionContext)
+ Kamon(Metrics)(Akka.system()).find("play-server", "http-server").get.collect(collectionContext)
for (repetition ← 1 to 10) {
Await.result(route(FakeRequest(GET, "/default").withHeaders(traceTokenHeader)).get, 10 seconds)
@@ -168,13 +169,13 @@ class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
Await.result(routeWithOnError(FakeRequest(GET, "/error").withHeaders(traceTokenHeader)).get, 10 seconds)
}
- val snapshot = Kamon(Metrics)(Akka.system()).register(HttpServerMetrics, HttpServerMetrics.Factory).get.collect(collectionContext)
- snapshot.countsPerTraceAndStatusCode("GET: /default")("200").count must be(10)
- snapshot.countsPerTraceAndStatusCode("GET: /notFound")("404").count must be(5)
- snapshot.countsPerTraceAndStatusCode("GET: /error")("500").count must be(5)
- snapshot.countsPerStatusCode("200").count must be(10)
- snapshot.countsPerStatusCode("404").count must be(5)
- snapshot.countsPerStatusCode("500").count must be(5)
+ val snapshot = Kamon(Metrics)(Akka.system()).find("play-server", "http-server").get.collect(collectionContext)
+ snapshot.counter("GET: /default_200").get.count must be(10)
+ snapshot.counter("GET: /notFound_404").get.count must be(5)
+ snapshot.counter("GET: /error_500").get.count must be(5)
+ snapshot.counter("200").get.count must be(10)
+ snapshot.counter("404").get.count must be(5)
+ snapshot.counter("500").get.count must be(5)
}
}
@@ -186,7 +187,7 @@ class RequestInstrumentationSpec extends PlaySpec with OneServerPerSuite {
object TraceLocalFilter extends Filter {
override def apply(next: (RequestHeader) ⇒ Future[Result])(header: RequestHeader): Future[Result] = {
- TraceRecorder.withTraceContext(TraceRecorder.currentContext) {
+ TraceContext.withContext(TraceContext.currentContext) {
TraceLocal.store(TraceLocalKey)(header.headers.get(traceLocalStorageKey).getOrElse("unknown"))
diff --git a/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala b/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
index 3629c1d1..3dec2ebf 100644
--- a/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
+++ b/kamon-play/src/test/scala/kamon/play/WSInstrumentationSpec.scala
@@ -17,9 +17,8 @@
package kamon.play
import kamon.Kamon
-import kamon.metric.TraceMetrics.TraceMetricsSnapshot
-import kamon.metric.{ Metrics, TraceMetrics }
-import kamon.trace.{ SegmentCategory, SegmentMetricIdentity, TraceRecorder }
+import kamon.metric.{ Metrics, EntitySnapshot, TraceMetrics }
+import kamon.trace.{ Tracer, TraceContext, SegmentCategory }
import org.scalatest.{ Matchers, WordSpecLike }
import org.scalatestplus.play.OneServerPerSuite
import play.api.libs.ws.WS
@@ -33,7 +32,7 @@ import scala.concurrent.Await
import scala.concurrent.duration._
class WSInstrumentationSpec extends WordSpecLike with Matchers with OneServerPerSuite {
-
+ import kamon.metric.TraceMetricsSpec.SegmentSyntax
System.setProperty("config.file", "./kamon-play/src/test/resources/conf/application.conf")
implicit override lazy val app = FakeApplication(withRoutes = {
@@ -47,29 +46,32 @@ class WSInstrumentationSpec extends WordSpecLike with Matchers with OneServerPer
Await.result(route(FakeRequest(GET, "/inside")).get, 10 seconds)
val snapshot = takeSnapshotOf("GET: /inside")
- snapshot.elapsedTime.numberOfMeasurements should be(1)
- snapshot.segments.size should be(1)
- snapshot.segments(SegmentMetricIdentity("http://localhost:19001/async", SegmentCategory.HttpClient, Play.SegmentLibraryName)).numberOfMeasurements should be(1)
+ snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
+ // snapshot.segments.size should be(1)
+ // snapshot.segment("http://localhost:19001/async", SegmentCategory.HttpClient, Play.SegmentLibraryName).numberOfMeasurements should be(1)
}
"propagate the TraceContext outside an Action and complete the WS request" in {
- TraceRecorder.withNewTraceContext("trace-outside-action") {
+ TraceContext.withContext(newContext("trace-outside-action")) {
Await.result(WS.url("http://localhost:19001/outside").get(), 10 seconds)
- TraceRecorder.finish()
- }(Akka.system())
+ TraceContext.currentContext.finish()
+ }
val snapshot = takeSnapshotOf("trace-outside-action")
- snapshot.elapsedTime.numberOfMeasurements should be(1)
+ snapshot.histogram("elapsed-time").get.numberOfMeasurements should be(1)
snapshot.segments.size should be(1)
- snapshot.segments(SegmentMetricIdentity("http://localhost:19001/outside", SegmentCategory.HttpClient, Play.SegmentLibraryName)).numberOfMeasurements should be(1)
+ snapshot.segment("http://localhost:19001/outside", SegmentCategory.HttpClient, Play.SegmentLibraryName).numberOfMeasurements should be(1)
}
}
- def takeSnapshotOf(traceName: String): TraceMetricsSnapshot = {
- val recorder = Kamon(Metrics)(Akka.system()).register(TraceMetrics(traceName), TraceMetrics.Factory)
+ def newContext(name: String): TraceContext =
+ Kamon(Tracer)(Akka.system).newContext(name)
+
+ def takeSnapshotOf(traceName: String): EntitySnapshot = {
+ val recorder = Kamon(Metrics)(Akka.system()).register(TraceMetrics, traceName).get.recorder
val collectionContext = Kamon(Metrics)(Akka.system()).buildDefaultCollectionContext
- recorder.get.collect(collectionContext)
+ recorder.collect(collectionContext)
}
def callWSinsideController(url: String) = Action.async {