From 583552adbbf796d61514d1a86d2513b667bf3e94 Mon Sep 17 00:00:00 2001 From: Ivan Topolnjak Date: Fri, 17 Nov 2017 14:46:30 +0100 Subject: add marks API for Spans --- .../src/test/scala/kamon/trace/LocalSpanSpec.scala | 20 +++++--- kamon-core/src/main/scala/kamon/trace/Span.scala | 58 +++++++++++++++------- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/kamon-core-tests/src/test/scala/kamon/trace/LocalSpanSpec.scala b/kamon-core-tests/src/test/scala/kamon/trace/LocalSpanSpec.scala index 05c1c53a..5d636d16 100644 --- a/kamon-core-tests/src/test/scala/kamon/trace/LocalSpanSpec.scala +++ b/kamon-core-tests/src/test/scala/kamon/trace/LocalSpanSpec.scala @@ -18,7 +18,7 @@ package kamon.trace import kamon.testkit.{MetricInspection, Reconfigure, TestSpanReporter} import kamon.util.Registration import kamon.Kamon -import kamon.trace.Span.{Annotation, TagValue} +import kamon.trace.Span.TagValue import org.scalatest.concurrent.Eventually import org.scalatest.{BeforeAndAfterAll, Matchers, OptionValues, WordSpec} import org.scalatest.time.SpanSugar._ @@ -44,7 +44,7 @@ class LocalSpanSpec extends WordSpec with Matchers with BeforeAndAfterAll with E } } - "pass all the tags to the FinishedSpan instance when started and finished" in { + "pass all the tags and marks to the FinishedSpan instance when started and finished" in { Kamon.buildSpan("full-span") .withTag("builder-string-tag", "value") .withTag("builder-boolean-tag-true", true) @@ -52,10 +52,12 @@ class LocalSpanSpec extends WordSpec with Matchers with BeforeAndAfterAll with E .withTag("builder-number-tag", 42) .withStartTimestamp(100) .start() - .addTag("span-string-tag", "value") - .addTag("span-boolean-tag-true", true) - .addTag("span-boolean-tag-false", false) - .addTag("span-number-tag", 42) + .tag("span-string-tag", "value") + .tag("span-boolean-tag-true", true) + .tag("span-boolean-tag-false", false) + .tag("span-number-tag", 42) + .mark("my-mark") + .mark(100, "my-custom-timetamp-mark") .setOperationName("fully-populated-span") .finish(200) @@ -74,6 +76,12 @@ class LocalSpanSpec extends WordSpec with Matchers with BeforeAndAfterAll with E "span-boolean-tag-false" -> TagValue.False, "span-number-tag" -> TagValue.Number(42) ) + finishedSpan.marks.map(_.key) should contain allOf( + "my-mark", + "my-custom-timetamp-mark" + ) + finishedSpan.marks.find(_.key == "my-custom-timetamp-mark").value.timestampMicros should be(100) + } } } diff --git a/kamon-core/src/main/scala/kamon/trace/Span.scala b/kamon-core/src/main/scala/kamon/trace/Span.scala index dcaf0a84..16dc1d3d 100644 --- a/kamon-core/src/main/scala/kamon/trace/Span.scala +++ b/kamon-core/src/main/scala/kamon/trace/Span.scala @@ -33,13 +33,17 @@ trait Span { def context(): SpanContext - def addTag(key: String, value: String): Span + def tag(key: String, value: String): Span - def addTag(key: String, value: Long): Span + def tag(key: String, value: Long): Span - def addTag(key: String, value: Boolean): Span + def tag(key: String, value: Boolean): Span - def addMetricTag(key: String, value: String): Span + def tagMetric(key: String, value: String): Span + + def mark(key: String): Span + + def mark(timestampMicros: Long, key: String): Span def addError(error: String): Span @@ -64,10 +68,12 @@ object Span { override val context: SpanContext = SpanContext.EmptySpanContext override def isEmpty(): Boolean = true override def isLocal(): Boolean = true - override def addTag(key: String, value: String): Span = this - override def addTag(key: String, value: Long): Span = this - override def addTag(key: String, value: Boolean): Span = this - override def addMetricTag(key: String, value: String): Span = this + override def tag(key: String, value: String): Span = this + override def tag(key: String, value: Long): Span = this + override def tag(key: String, value: Boolean): Span = this + override def tagMetric(key: String, value: String): Span = this + override def mark(key: String): Span = this + override def mark(timestampMicros: Long, key: String): Span = this override def addError(error: String): Span = this override def addError(error: String, throwable: Throwable): Span = this override def setOperationName(name: String): Span = this @@ -93,24 +99,25 @@ object Span { private var operationName: String = initialOperationName private var spanTags: Map[String, Span.TagValue] = initialSpanTags + private var marks: List[Mark] = Nil private var customMetricTags = initialMetricTags override def isEmpty(): Boolean = false override def isLocal(): Boolean = true - override def addTag(key: String, value: String): Span = synchronized { + override def tag(key: String, value: String): Span = synchronized { if(sampled && open) spanTags = spanTags + (key -> TagValue.String(value)) this } - override def addTag(key: String, value: Long): Span = synchronized { + override def tag(key: String, value: Long): Span = synchronized { if(sampled && open) spanTags = spanTags + (key -> TagValue.Number(value)) this } - override def addTag(key: String, value: Boolean): Span = synchronized { + override def tag(key: String, value: Boolean): Span = synchronized { if(sampled && open) { val tagValue = if (value) TagValue.True else TagValue.False spanTags = spanTags + (key -> tagValue) @@ -118,7 +125,7 @@ object Span { this } - override def addMetricTag(key: String, value: String): Span = synchronized { + override def tagMetric(key: String, value: String): Span = synchronized { if(sampled && open) { spanTags = spanTags + (key -> TagValue.String(value)) @@ -128,6 +135,15 @@ object Span { this } + override def mark(key: String): Span = { + mark(Clock.microTimestamp(), key) + } + + override def mark(timestampMicros: Long, key: String): Span = synchronized { + this.marks = Mark(timestampMicros, key) :: this.marks + this + } + override def addError(error: String): Span = synchronized { if(sampled && open) { hasError = true @@ -177,7 +193,7 @@ object Span { } private def toFinishedSpan(endTimestampMicros: Long): Span.FinishedSpan = - Span.FinishedSpan(spanContext, operationName, startTimestampMicros, endTimestampMicros, spanTags) + Span.FinishedSpan(spanContext, operationName, startTimestampMicros, endTimestampMicros, spanTags, marks) private def recordSpanMetrics(endTimestampMicros: Long): Unit = { val elapsedTime = endTimestampMicros - startTimestampMicros @@ -206,10 +222,12 @@ object Span { final class Remote(val context: SpanContext) extends Span { override def isEmpty(): Boolean = false override def isLocal(): Boolean = false - override def addTag(key: String, value: String): Span = this - override def addTag(key: String, value: Long): Span = this - override def addTag(key: String, value: Boolean): Span = this - override def addMetricTag(key: String, value: String): Span = this + override def tag(key: String, value: String): Span = this + override def tag(key: String, value: Long): Span = this + override def tag(key: String, value: Boolean): Span = this + override def tagMetric(key: String, value: String): Span = this + override def mark(key: String): Span = this + override def mark(timestampMicros: Long, key: String): Span = this override def addError(error: String): Span = this override def addError(error: String, throwable: Throwable): Span = this override def setOperationName(name: String): Span = this @@ -241,18 +259,20 @@ object Span { case class Number(number: Long) extends TagValue } + object Metrics { val ProcessingTime = Kamon.histogram("span.processing-time", MeasurementUnit.time.microseconds) val SpanErrorCount = Kamon.counter("span.error-count") } - case class Annotation(timestampMicros: Long, name: String, fields: Map[String, String]) + case class Mark(timestampMicros: Long, key: String) case class FinishedSpan( context: SpanContext, operationName: String, startTimestampMicros: Long, endTimestampMicros: Long, - tags: Map[String, Span.TagValue] + tags: Map[String, Span.TagValue], + marks: Seq[Span.Mark] ) } \ No newline at end of file -- cgit v1.2.3