From 962ec71ac9b119badb434a747484ca675cf1268b Mon Sep 17 00:00:00 2001 From: Ivan Topolnjak Date: Sat, 26 Aug 2017 22:30:11 +0200 Subject: add Span.addError(..) --- .../src/test/scala/kamon/trace/LocalSpanSpec.scala | 2 +- .../src/test/scala/kamon/trace/SpanMetrics.scala | 31 ++++++++++++++---- kamon-core/src/main/scala/kamon/trace/Span.scala | 38 +++++++++++++++++++--- 3 files changed, 58 insertions(+), 13 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 966fdbad..05c1c53a 100644 --- a/kamon-core-tests/src/test/scala/kamon/trace/LocalSpanSpec.scala +++ b/kamon-core-tests/src/test/scala/kamon/trace/LocalSpanSpec.scala @@ -44,7 +44,7 @@ class LocalSpanSpec extends WordSpec with Matchers with BeforeAndAfterAll with E } } - "pass all the tags, annotations and baggage to the FinishedSpan instance when started and finished" in { + "pass all the tags to the FinishedSpan instance when started and finished" in { Kamon.buildSpan("full-span") .withTag("builder-string-tag", "value") .withTag("builder-boolean-tag-true", true) diff --git a/kamon-core-tests/src/test/scala/kamon/trace/SpanMetrics.scala b/kamon-core-tests/src/test/scala/kamon/trace/SpanMetrics.scala index 40813a25..4425ac92 100644 --- a/kamon-core-tests/src/test/scala/kamon/trace/SpanMetrics.scala +++ b/kamon-core-tests/src/test/scala/kamon/trace/SpanMetrics.scala @@ -19,6 +19,8 @@ import kamon.Kamon.buildSpan import kamon.testkit.{MetricInspection, Reconfigure} import org.scalatest.{Matchers, WordSpecLike} +import scala.util.control.NoStackTrace + class SpanMetrics extends WordSpecLike with Matchers with MetricInspection with Reconfigure { sampleAlways() @@ -46,14 +48,19 @@ class SpanMetrics extends WordSpecLike with Matchers with MetricInspection with buildSpan(operation) .start() - .addTag("error", true) + .addError("Terrible Error") + .finish() + + buildSpan(operation) + .start() + .addError("Terrible Error with Throwable", new Throwable with NoStackTrace) .finish() val histogram = Span.Metrics.ProcessingTime.refine(Map(operationTag, noErrorTag)) histogram.distribution().count shouldBe 0 val errorHistogram = Span.Metrics.ProcessingTime.refine(Map(operationTag, errorTag)) - errorHistogram.distribution().count shouldBe 1 + errorHistogram.distribution().count shouldBe 2 } "add a parentOperation tag to the metrics if span metrics scoping is enabled" in { @@ -66,20 +73,25 @@ class SpanMetrics extends WordSpecLike with Matchers with MetricInspection with buildSpan(operation) .asChildOf(parent) .start() - .addTag("error", false) .finish() buildSpan(operation) .asChildOf(parent) .start() - .addTag("error", true) + .addError("Terrible Error") + .finish() + + buildSpan(operation) + .asChildOf(parent) + .start() + .addError("Terrible Error with Throwable", new Throwable with NoStackTrace) .finish() val histogram = Span.Metrics.ProcessingTime.refine(Map(operationTag, noErrorTag, parentOperationTag)) histogram.distribution().count shouldBe 1 val errorHistogram = Span.Metrics.ProcessingTime.refine(Map(operationTag, errorTag, parentOperationTag)) - errorHistogram.distribution().count shouldBe 1 + errorHistogram.distribution().count shouldBe 2 } "not add any parentOperation tag to the metrics if span metrics scoping is disabled" in withoutSpanScopingEnabled { @@ -92,13 +104,18 @@ class SpanMetrics extends WordSpecLike with Matchers with MetricInspection with buildSpan(operation) .asChildOf(parent) .start() - .addTag("error", false) .finish() buildSpan(operation) .asChildOf(parent) .start() - .addTag("error", true) + .addError("Terrible Error") + .finish() + + buildSpan(operation) + .asChildOf(parent) + .start() + .addError("Terrible Error with Throwable", new Throwable with NoStackTrace) .finish() val histogram = Span.Metrics.ProcessingTime.refine(Map(operationTag, noErrorTag, parentOperationTag)) diff --git a/kamon-core/src/main/scala/kamon/trace/Span.scala b/kamon-core/src/main/scala/kamon/trace/Span.scala index cb1be8dc..dcaf0a84 100644 --- a/kamon-core/src/main/scala/kamon/trace/Span.scala +++ b/kamon-core/src/main/scala/kamon/trace/Span.scala @@ -41,6 +41,10 @@ trait Span { def addMetricTag(key: String, value: String): Span + def addError(error: String): Span + + def addError(error: String, throwable: Throwable): Span + def setOperationName(name: String): Span def disableMetricsCollection(): Span @@ -64,6 +68,8 @@ object Span { 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 addError(error: String): Span = this + override def addError(error: String, throwable: Throwable): Span = this override def setOperationName(name: String): Span = this override def disableMetricsCollection(): Span = this override def finish(finishTimestampMicros: Long): Unit = {} @@ -83,6 +89,7 @@ object Span { private var collectMetrics: Boolean = true private var open: Boolean = true private val sampled: Boolean = spanContext.samplingDecision == SamplingDecision.Sample + private var hasError: Boolean = false private var operationName: String = initialOperationName private var spanTags: Map[String, Span.TagValue] = initialSpanTags @@ -121,6 +128,28 @@ object Span { this } + override def addError(error: String): Span = synchronized { + if(sampled && open) { + hasError = true + spanTags = spanTags ++ Map( + "error" -> TagValue.True, + "error.object" -> TagValue.String(error) + ) + } + this + } + + override def addError(error: String, throwable: Throwable): Span = synchronized { + if(sampled && open) { + hasError = true + spanTags = spanTags ++ Map( + "error" -> TagValue.True, + "error.object" -> TagValue.String(throwable.getMessage()) + ) + } + this + } + override def disableMetricsCollection(): Span = synchronized { collectMetrics = false this @@ -152,17 +181,14 @@ object Span { private def recordSpanMetrics(endTimestampMicros: Long): Unit = { val elapsedTime = endTimestampMicros - startTimestampMicros - val isError = spanTags.get("error").map { - case boolean: TagValue.Boolean => boolean.text - case _ => TagValue.False.text - } getOrElse(TagValue.False.text) + val isErrorText = if(hasError) TagValue.True.text else TagValue.False.text if(scopeSpanMetrics) parent.foreach(parentSpan => customMetricTags = customMetricTags + ("parentOperation" -> parentSpan.asInstanceOf[Local].operationName)) val metricTags = Map( "operation" -> operationName, - "error" -> isError + "error" -> isErrorText ) ++ customMetricTags Span.Metrics.ProcessingTime.refine(metricTags).record(elapsedTime) @@ -184,6 +210,8 @@ object Span { 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 addError(error: String): Span = this + override def addError(error: String, throwable: Throwable): Span = this override def setOperationName(name: String): Span = this override def disableMetricsCollection(): Span = this override def finish(finishTimestampMicros: Long): Unit = {} -- cgit v1.2.3