Permalink
Browse files

+ core: include Tags and Status in TraceInfo and SegmentInfo and closes

  • Loading branch information...
1 parent b4bd658 commit 3a57f32a55841527939019fe5fefa8349d352a02 @dpsoft dpsoft committed Jul 27, 2016
@@ -61,7 +61,7 @@ private[kamon] class MetricsOnlyContext(traceName: String,
_elapsedTime = traceElapsedTime
if (Kamon.metrics.shouldTrack(name, TraceMetrics.category)) {
- val traceEntity = Kamon.metrics.entity(TraceMetrics, name)
+ val traceEntity = Kamon.metrics.entity(TraceMetrics, name, _tags.toMap)
traceEntity.elapsedTime.record(traceElapsedTime.nanos)
if (withError) traceEntity.errors.increment()
}
@@ -125,7 +125,7 @@ private[kamon] class MetricsOnlyContext(traceName: String,
segmentTags: Map[String, String]) extends Segment {
private val _startTimestamp = RelativeNanoTimestamp.now
- protected val _tags = TrieMap.empty[String, String] ++= segmentTags
+ private val _tags = TrieMap.empty[String, String] ++= segmentTags
@volatile private var _segmentName = segmentName
@volatile private var _elapsedTime = NanoInterval.default
@@ -110,9 +110,7 @@ case object EmptyTraceContext extends TraceContext {
def startSegment(segmentName: String, category: String, library: String, tags: Map[String, String]): Segment = EmptySegment
def addMetadata(key: String, value: String): Unit = {}
def startTimestamp = new RelativeNanoTimestamp(0L)
- def addTags(tags: Map[String, String]): Unit = {}
def addTag(key: String, value: String): Unit = {}
- def removeTags(tags: Map[String, String]): Unit = {}
def removeTag(key: String, value: String): Boolean = false
case object EmptySegment extends Segment {
@@ -194,5 +194,5 @@ private[kamon] object TracerModuleImpl {
new TracerModuleImpl(metricsExtension, config)
}
-case class TraceInfo(name: String, token: String, timestamp: NanoTimestamp, elapsedTime: NanoInterval, metadata: Map[String, String], segments: List[SegmentInfo])
-case class SegmentInfo(name: String, category: String, library: String, timestamp: NanoTimestamp, elapsedTime: NanoInterval, metadata: Map[String, String], tags: Map[String, String])
+case class TraceInfo(name: String, token: String, timestamp: NanoTimestamp, elapsedTime: NanoInterval, metadata: Map[String, String], tags: Map[String, String], segments: List[SegmentInfo], status: Status)
+case class SegmentInfo(name: String, category: String, library: String, timestamp: NanoTimestamp, elapsedTime: NanoInterval, metadata: Map[String, String], tags: Map[String, String], status: Status)
@@ -1,6 +1,6 @@
/*
* =========================================================================================
- * Copyright © 2013-2014 the kamon project <http://kamon.io/>
+ * Copyright © 2013-2016 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
@@ -57,6 +57,11 @@ private[trace] class TracingContext(traceName: String,
traceInfoSink(this)
}
+ override def finishWithError(cause: Throwable): Unit = {
+ super.finishWithError(cause)
+ traceInfoSink(this)
+ }
+
override def finishSegment(segmentName: String, category: String, library: String, duration: NanoInterval, tags: Map[String, String], isFinishedWithError: Boolean = false): Unit = {
_openSegments.decrementAndGet()
super.finishSegment(segmentName, category, library, duration, tags, isFinishedWithError)
@@ -79,7 +84,7 @@ private[trace] class TracingContext(traceName: String,
log.warning("Segment [{}] will be left out of TraceInfo because it was still open.", segment.name)
}
- TraceInfo(name, token, _startTimestamp, elapsedTime, _metadata.toMap, segmentsInfo.result())
+ TraceInfo(name, token, _startTimestamp, elapsedTime, _metadata.toMap, tags, segmentsInfo.result(), status)
}
class TracingSegment(segmentName: String,
@@ -98,7 +103,7 @@ private[trace] class TracingContext(traceName: String,
// expensive and inaccurate, but we can do that once for the trace and calculate all the segments relative to it.
val segmentStartTimestamp = new NanoTimestamp((this.startTimestamp.nanos - traceRelativeTimestamp.nanos) + traceStartTimestamp.nanos)
- SegmentInfo(this.name, category, library, segmentStartTimestamp, this.elapsedTime, metadata.toMap, _tags.toMap)
+ SegmentInfo(this.name, category, library, segmentStartTimestamp, this.elapsedTime, metadata.toMap, tags, status)
}
}
}
@@ -20,6 +20,7 @@ import kamon.Kamon
import kamon.testkit.BaseKamonSpec
import scala.concurrent.duration._
+import scala.util.control.NoStackTrace
class SimpleTraceSpec extends BaseKamonSpec("simple-trace-spec") {
@@ -42,6 +43,71 @@ class SimpleTraceSpec extends BaseKamonSpec("simple-trace-spec") {
traceInfo.segments.find(_.name == "segment-two") should be('defined)
}
+ "send a TraceInfo when the trace has finished with error and all segments are finished" in {
+ Kamon.tracer.subscribe(testActor)
+
+ Tracer.withContext(newContext("simple-trace-with-error-and-without-segments")) {
+ Tracer.currentContext.startSegment("segment-one", "test-segment", "test").finish()
+ Tracer.currentContext.startSegment("segment-two", "test-segment", "test").finish()
+ Tracer.currentContext.finishWithError(TraceException("awesome-trace-error"))
+ }
+
+ val traceInfo = expectMsgType[TraceInfo]
+ Kamon.tracer.unsubscribe(testActor)
+
+ traceInfo.name should be("simple-trace-with-error-and-without-segments")
+ traceInfo.status should be(Status.FinishedWithError)
+ traceInfo.segments.size should be(2)
+ traceInfo.segments.find(_.name == "segment-one") should be('defined)
+ traceInfo.segments.find(_.name == "segment-two") should be('defined)
+ }
+
+ "send a TraceInfo when the trace has finished with error and all segments are finished with error" in {
+ Kamon.tracer.subscribe(testActor)
+
+ Tracer.withContext(newContext("simple-trace-with-error-and-without-segments")) {
+ Tracer.currentContext.startSegment("segment-one-finished-with-error", "test-segment", "test").finishWithError(SegmentException("awesome-segment-exception"))
+ Tracer.currentContext.startSegment("segment-two-finished-with-error", "test-segment", "test").finishWithError(SegmentException("awesome-segment-exception"))
+ Tracer.currentContext.finishWithError(TraceException("awesome-trace-error"))
+ }
+
+ val traceInfo = expectMsgType[TraceInfo]
+ Kamon.tracer.unsubscribe(testActor)
+
+ traceInfo.name should be("simple-trace-with-error-and-without-segments")
+ traceInfo.status should be(Status.FinishedWithError)
+ traceInfo.segments.size should be(2)
+
+ val segmentOne = traceInfo.segments.find(_.name == "segment-one-finished-with-error")
+ val segmentTwo = traceInfo.segments.find(_.name == "segment-two-finished-with-error")
+
+ segmentOne.get.status should be(Status.FinishedWithError)
+ segmentTwo.get.status should be(Status.FinishedWithError)
+ }
+
+ "send a TraceInfo when the trace has finished and all segments are finished and both contains tags" in {
+ Kamon.tracer.subscribe(testActor)
+
+ Tracer.withContext(newContext("simple-trace-without-segments", "awesome-token", Map("environment" -> "production"))) {
+ Tracer.currentContext.startSegment("segment-one", "test-segment", "test", Map("segment-one-info" -> "info")).finish()
+ Tracer.currentContext.startSegment("segment-two", "test-segment", "test", Map("segment-two-info" -> "info")).finish()
+ Tracer.currentContext.finish()
+ }
+
+ val traceInfo = expectMsgType[TraceInfo]
+ Kamon.tracer.unsubscribe(testActor)
+
+ traceInfo.name should be("simple-trace-without-segments")
+ traceInfo.tags should be(Map("environment" -> "production"))
+ traceInfo.segments.size should be(2)
+
+ val segmentOne = traceInfo.segments.find(_.name == "segment-one")
+ val segmentTwo = traceInfo.segments.find(_.name == "segment-two")
+
+ segmentOne.get.tags should be(Map("segment-one-info" -> "info"))
+ segmentTwo.get.tags should be(Map("segment-two-info" -> "info"))
+ }
+
"incubate the tracing context if there are open segments after finishing" in {
Kamon.tracer.subscribe(testActor)
@@ -68,3 +134,6 @@ class SimpleTraceSpec extends BaseKamonSpec("simple-trace-spec") {
}
}
+
+case class TraceException(message: String) extends RuntimeException(message) with NoStackTrace
+case class SegmentException(message: String) extends RuntimeException(message) with NoStackTrace

0 comments on commit 3a57f32

Please sign in to comment.