aboutsummaryrefslogtreecommitdiff
path: root/kamon-spray
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2014-01-31 09:01:18 -0300
committerIvan Topolnjak <ivantopo@gmail.com>2014-01-31 09:01:18 -0300
commit59c01d880379dfc48c6d82da13ef628a587a9bbb (patch)
treedd323caa93133a98da5f76be332dfdbf76280ea5 /kamon-spray
parenta15e17d2462105ad8b72054be58dc9e8f9dc64ed (diff)
downloadKamon-59c01d880379dfc48c6d82da13ef628a587a9bbb.tar.gz
Kamon-59c01d880379dfc48c6d82da13ef628a587a9bbb.tar.bz2
Kamon-59c01d880379dfc48c6d82da13ef628a587a9bbb.zip
remake of trace context and allow different tracing levels
Diffstat (limited to 'kamon-spray')
-rw-r--r--kamon-spray/src/main/scala/kamon/spray/Spray.scala37
-rw-r--r--kamon-spray/src/main/scala/kamon/spray/UowDirectives.scala5
-rw-r--r--kamon-spray/src/main/scala/spray/can/client/ClientRequestTracing.scala50
-rw-r--r--kamon-spray/src/main/scala/spray/can/server/ServerRequestTracing.scala37
-rw-r--r--kamon-spray/src/test/scala/kamon/spray/ClientRequestTracingSpec.scala5
-rw-r--r--kamon-spray/src/test/scala/kamon/spray/ServerRequestTracingSpec.scala2
6 files changed, 85 insertions, 51 deletions
diff --git a/kamon-spray/src/main/scala/kamon/spray/Spray.scala b/kamon-spray/src/main/scala/kamon/spray/Spray.scala
new file mode 100644
index 00000000..4dc98d85
--- /dev/null
+++ b/kamon-spray/src/main/scala/kamon/spray/Spray.scala
@@ -0,0 +1,37 @@
+/*
+ * =========================================================================================
+ * Copyright © 2013 the kamon project <http://kamon.io/>
+ *
+ * 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 kamon.spray
+
+import akka.actor.{ ExtendedActorSystem, ExtensionIdProvider, ExtensionId }
+import akka.actor
+import kamon.Kamon
+import spray.http.HttpRequest
+
+object Spray extends ExtensionId[SprayExtension] with ExtensionIdProvider {
+ def lookup(): ExtensionId[_ <: actor.Extension] = Spray
+ def createExtension(system: ExtendedActorSystem): SprayExtension = new SprayExtension(system)
+}
+
+class SprayExtension(private val system: ExtendedActorSystem) extends Kamon.Extension {
+ private val config = system.settings.config.getConfig("kamon.spray")
+
+ val includeTraceToken: Boolean = config.getBoolean("include-trace-token-header")
+ val traceTokenHeaderName: String = config.getString("trace-token-header-name")
+
+ // Later we should expose a way for the user to customize this.
+ def assignHttpClientRequestName(request: HttpRequest): String = request.uri.authority.host.address
+}
diff --git a/kamon-spray/src/main/scala/kamon/spray/UowDirectives.scala b/kamon-spray/src/main/scala/kamon/spray/UowDirectives.scala
index 78a5b336..56cc6d5e 100644
--- a/kamon-spray/src/main/scala/kamon/spray/UowDirectives.scala
+++ b/kamon-spray/src/main/scala/kamon/spray/UowDirectives.scala
@@ -20,7 +20,6 @@ import spray.routing._
import java.util.concurrent.atomic.AtomicLong
import scala.util.Try
import java.net.InetAddress
-import kamon.trace.Trace
import spray.http.HttpHeaders.RawHeader
trait UowDirectives extends BasicDirectives {
@@ -28,10 +27,10 @@ trait UowDirectives extends BasicDirectives {
val uowHeader = request.headers.find(_.name == "X-UOW")
val generatedUow = uowHeader.map(_.value).getOrElse(UowDirectives.newUow)
- Trace.transformContext(_.copy(token = generatedUow))
+ //Trace.transformContext(_.copy(token = generatedUow))
request
}
- def respondWithUow = mapHttpResponseHeaders(headers ⇒ Trace.context().map(ctx ⇒ RawHeader("X-UOW", ctx.token) :: headers).getOrElse(headers))
+ //def respondWithUow = mapHttpResponseHeaders(headers ⇒ Trace.context().map(ctx ⇒ RawHeader("X-UOW", ctx.token) :: headers).getOrElse(headers))
}
object UowDirectives {
diff --git a/kamon-spray/src/main/scala/spray/can/client/ClientRequestTracing.scala b/kamon-spray/src/main/scala/spray/can/client/ClientRequestTracing.scala
index a1505a63..c74019dd 100644
--- a/kamon-spray/src/main/scala/spray/can/client/ClientRequestTracing.scala
+++ b/kamon-spray/src/main/scala/spray/can/client/ClientRequestTracing.scala
@@ -20,58 +20,60 @@ import org.aspectj.lang.annotation._
import org.aspectj.lang.ProceedingJoinPoint
import spray.http.{ HttpMessageEnd, HttpRequest }
import spray.http.HttpHeaders.Host
-import kamon.trace.{ TraceContext, Trace, Segments }
-import kamon.trace.Segments.{ ContextAndSegmentCompletionAware, HttpClientRequest }
-import kamon.trace.Trace.SegmentCompletionHandle
+import kamon.trace.{ TraceRecorder, SegmentCompletionHandleAware, TraceContextAware }
+import kamon.metrics.TraceMetrics.HttpClientRequest
+import kamon.Kamon
+import kamon.spray.Spray
@Aspect
class ClientRequestTracing {
@DeclareMixin("spray.can.client.HttpHostConnector.RequestContext")
- def mixin: ContextAndSegmentCompletionAware = new ContextAndSegmentCompletionAware {
- val traceContext: Option[TraceContext] = Trace.context()
- var completionHandle: Option[SegmentCompletionHandle] = None
- }
+ def mixin: SegmentCompletionHandleAware = SegmentCompletionHandleAware.default
@Pointcut("execution(spray.can.client.HttpHostConnector.RequestContext.new(..)) && this(ctx) && args(request, *, *, *)")
- def requestContextCreation(ctx: ContextAndSegmentCompletionAware, request: HttpRequest): Unit = {}
+ def requestContextCreation(ctx: SegmentCompletionHandleAware, request: HttpRequest): Unit = {}
@After("requestContextCreation(ctx, request)")
- def afterRequestContextCreation(ctx: ContextAndSegmentCompletionAware, request: HttpRequest): Unit = {
+ def afterRequestContextCreation(ctx: SegmentCompletionHandleAware, request: HttpRequest): Unit = {
// The RequestContext will be copied when a request needs to be retried but we are only interested in creating the
// completion handle the first time we create one.
// The read to ctx.completionHandle should take care of initializing the aspect timely.
- if (ctx.completionHandle.isEmpty) {
- val requestAttributes = Map[String, String](
- "host" -> request.header[Host].map(_.value).getOrElse("unknown"),
- "path" -> request.uri.path.toString(),
- "method" -> request.method.toString())
- val completionHandle = Trace.startSegment(category = HttpClientRequest, attributes = requestAttributes)
- ctx.completionHandle = Some(completionHandle)
+ if (ctx.segmentCompletionHandle.isEmpty) {
+ TraceRecorder.currentContext.map { traceContext ⇒
+ val requestAttributes = Map[String, String](
+ "host" -> request.header[Host].map(_.value).getOrElse("unknown"),
+ "path" -> request.uri.path.toString(),
+ "method" -> request.method.toString())
+
+ val clientRequestName = Kamon(Spray)(traceContext.system).assignHttpClientRequestName(request)
+ val completionHandle = traceContext.startSegment(HttpClientRequest(clientRequestName), requestAttributes)
+ ctx.segmentCompletionHandle = Some(completionHandle)
+ }
}
}
@Pointcut("execution(* spray.can.client.HttpHostConnector.RequestContext.copy(..)) && this(old)")
- def copyingRequestContext(old: ContextAndSegmentCompletionAware): Unit = {}
+ def copyingRequestContext(old: SegmentCompletionHandleAware): Unit = {}
@Around("copyingRequestContext(old)")
- def aroundCopyingRequestContext(pjp: ProceedingJoinPoint, old: ContextAndSegmentCompletionAware) = {
- Trace.withContext(old.traceContext) {
+ def aroundCopyingRequestContext(pjp: ProceedingJoinPoint, old: SegmentCompletionHandleAware): Any = {
+ TraceRecorder.withTraceContext(old.traceContext) {
pjp.proceed()
}
}
@Pointcut("execution(* spray.can.client.HttpHostConnectionSlot.dispatchToCommander(..)) && args(requestContext, message)")
- def dispatchToCommander(requestContext: ContextAndSegmentCompletionAware, message: Any): Unit = {}
+ def dispatchToCommander(requestContext: SegmentCompletionHandleAware, message: Any): Unit = {}
@Around("dispatchToCommander(requestContext, message)")
- def aroundDispatchToCommander(pjp: ProceedingJoinPoint, requestContext: ContextAndSegmentCompletionAware, message: Any) = {
+ def aroundDispatchToCommander(pjp: ProceedingJoinPoint, requestContext: SegmentCompletionHandleAware, message: Any) = {
requestContext.traceContext match {
case ctx @ Some(_) ⇒
- Trace.withContext(ctx) {
+ TraceRecorder.withTraceContext(ctx) {
if (message.isInstanceOf[HttpMessageEnd])
- requestContext.completionHandle.map(_.complete(Segments.End()))
+ requestContext.segmentCompletionHandle.map(_.finish(Map.empty))
pjp.proceed()
}
@@ -80,4 +82,4 @@ class ClientRequestTracing {
}
}
-} \ No newline at end of file
+}
diff --git a/kamon-spray/src/main/scala/spray/can/server/ServerRequestTracing.scala b/kamon-spray/src/main/scala/spray/can/server/ServerRequestTracing.scala
index f0e52d12..b7479d2b 100644
--- a/kamon-spray/src/main/scala/spray/can/server/ServerRequestTracing.scala
+++ b/kamon-spray/src/main/scala/spray/can/server/ServerRequestTracing.scala
@@ -16,37 +16,34 @@
package spray.can.server
import org.aspectj.lang.annotation._
-import kamon.trace.{ Trace, ContextAware }
-import spray.http.HttpRequest
+import kamon.trace.{ TraceRecorder, TraceContextAware }
import akka.actor.ActorSystem
-import akka.event.Logging.Warning
-import org.aspectj.lang.ProceedingJoinPoint
import spray.http.HttpRequest
import akka.event.Logging.Warning
import scala.Some
+import kamon.Kamon
+import kamon.spray.Spray
@Aspect
class ServerRequestTracing {
@DeclareMixin("spray.can.server.OpenRequestComponent.DefaultOpenRequest")
- def mixinContextAwareToOpenRequest: ContextAware = ContextAware.default
+ def mixinContextAwareToOpenRequest: TraceContextAware = TraceContextAware.default
@Pointcut("execution(spray.can.server.OpenRequestComponent$DefaultOpenRequest.new(..)) && this(openRequest) && args(*, request, *, *)")
- def openRequestInit(openRequest: ContextAware, request: HttpRequest): Unit = {}
+ def openRequestInit(openRequest: TraceContextAware, request: HttpRequest): Unit = {}
@After("openRequestInit(openRequest, request)")
- def afterInit(openRequest: ContextAware, request: HttpRequest): Unit = {
+ def afterInit(openRequest: TraceContextAware, request: HttpRequest): Unit = {
val system: ActorSystem = openRequest.asInstanceOf[OpenRequest].context.actorContext.system
- val config = system.settings.config.getConfig("kamon.spray")
-
- val token = if (config.getBoolean("include-trace-token-header")) {
- val traceTokenHeader = config.getString("trace-token-header-name")
- request.headers.find(_.name == traceTokenHeader).map(_.value)
- } else None
+ val sprayExtension = Kamon(Spray)(system)
val defaultTraceName: String = request.method.value + ": " + request.uri.path
+ val token = if (sprayExtension.includeTraceToken) {
+ request.headers.find(_.name == sprayExtension.traceTokenHeaderName).map(_.value)
+ } else None
- Trace.start(defaultTraceName, token)(system)
+ TraceRecorder.start(defaultTraceName, token)(system)
// Necessary to force initialization of traceContext when initiating the request.
openRequest.traceContext
@@ -57,26 +54,26 @@ class ServerRequestTracing {
@After("openNewRequest()")
def afterOpenNewRequest(): Unit = {
- Trace.clear
+ TraceRecorder.clearContext
}
@Pointcut("execution(* spray.can.server.OpenRequestComponent$DefaultOpenRequest.handleResponseEndAndReturnNextOpenRequest(..)) && target(openRequest)")
- def openRequestCreation(openRequest: ContextAware): Unit = {}
+ def openRequestCreation(openRequest: TraceContextAware): Unit = {}
@After("openRequestCreation(openRequest)")
- def afterFinishingRequest(openRequest: ContextAware): Unit = {
+ def afterFinishingRequest(openRequest: TraceContextAware): Unit = {
val storedContext = openRequest.traceContext
- val incomingContext = Trace.finish()
+ val incomingContext = TraceRecorder.currentContext
+ TraceRecorder.finish()
for (original ← storedContext) {
incomingContext match {
- case Some(incoming) if original.id != incoming.id ⇒
+ case Some(incoming) if original.token != incoming.token ⇒
publishWarning(s"Different ids when trying to close a Trace, original: [$original] - incoming: [$incoming]")
case Some(_) ⇒ // nothing to do here.
case None ⇒
- original.finish
publishWarning(s"Trace context not present while closing the Trace: [$original]")
}
}
diff --git a/kamon-spray/src/test/scala/kamon/spray/ClientRequestTracingSpec.scala b/kamon-spray/src/test/scala/kamon/spray/ClientRequestTracingSpec.scala
index e204cd02..1ed3a787 100644
--- a/kamon-spray/src/test/scala/kamon/spray/ClientRequestTracingSpec.scala
+++ b/kamon-spray/src/test/scala/kamon/spray/ClientRequestTracingSpec.scala
@@ -5,7 +5,6 @@ import akka.actor.ActorSystem
import org.scalatest.WordSpecLike
import spray.httpx.RequestBuilding
import spray.client.pipelining._
-import kamon.trace.{ UowTrace, Trace }
import scala.concurrent.Await
class ClientRequestTracingSpec extends TestKit(ActorSystem("server-request-tracing-spec")) with WordSpecLike with RequestBuilding with TestServer {
@@ -20,10 +19,10 @@ class ClientRequestTracingSpec extends TestKit(ActorSystem("server-request-traci
Get(s"http://127.0.0.1:$port/ok")
// We don't care about the response, just make sure we finish the Trace after the response has been received.
- } map (rsp ⇒ Trace.finish())*/
+ } map (rsp ⇒ Trace.finish())
val trace = expectMsgType[UowTrace]
- println(trace.segments)
+ println(trace.segments)*/
}
}
diff --git a/kamon-spray/src/test/scala/kamon/spray/ServerRequestTracingSpec.scala b/kamon-spray/src/test/scala/kamon/spray/ServerRequestTracingSpec.scala
index 904047ed..d14ea6b1 100644
--- a/kamon-spray/src/test/scala/kamon/spray/ServerRequestTracingSpec.scala
+++ b/kamon-spray/src/test/scala/kamon/spray/ServerRequestTracingSpec.scala
@@ -24,7 +24,7 @@ import scala.concurrent.Await
import scala.concurrent.duration._
import _root_.spray.client.pipelining._
import akka.util.Timeout
-import kamon.trace.{ UowTrace, Trace }
+import kamon.trace.{ UowTrace }
import kamon.Kamon
import org.scalatest.concurrent.{ PatienceConfiguration, ScalaFutures }
import spray.http.HttpHeaders.RawHeader