From 9b6878da2fbfb1328e972a885a6fdc077e08aaf9 Mon Sep 17 00:00:00 2001 From: Ivan Topolnjak Date: Tue, 18 Jul 2017 10:01:38 +0200 Subject: introduce types for Span tags --- .../src/main/scala/kamon/trace/ActiveSpan.scala | 6 +++ .../src/main/scala/kamon/trace/Sampler.scala | 6 +-- kamon-core/src/main/scala/kamon/trace/Span.scala | 47 +++++++++++++++++----- kamon-core/src/main/scala/kamon/trace/Tracer.scala | 16 +++++++- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/kamon-core/src/main/scala/kamon/trace/ActiveSpan.scala b/kamon-core/src/main/scala/kamon/trace/ActiveSpan.scala index 3753cd7e..68ef2254 100644 --- a/kamon-core/src/main/scala/kamon/trace/ActiveSpan.scala +++ b/kamon-core/src/main/scala/kamon/trace/ActiveSpan.scala @@ -37,6 +37,12 @@ object ActiveSpan { override def addSpanTag(key: String, value: String): Span = wrappedSpan.addSpanTag(key, value) + override def addSpanTag(key: String, value: Long): Span = + wrappedSpan.addSpanTag(key, value) + + override def addSpanTag(key: String, value: Boolean): Span = + wrappedSpan.addSpanTag(key, value) + override def addMetricTag(key: String, value: String): Span = wrappedSpan.addMetricTag(key, value) diff --git a/kamon-core/src/main/scala/kamon/trace/Sampler.scala b/kamon-core/src/main/scala/kamon/trace/Sampler.scala index e2aefe22..3f366175 100644 --- a/kamon-core/src/main/scala/kamon/trace/Sampler.scala +++ b/kamon-core/src/main/scala/kamon/trace/Sampler.scala @@ -19,7 +19,7 @@ import java.util.concurrent.ThreadLocalRandom import kamon.trace.SpanContext.SamplingDecision trait Sampler { - def decide(operationName: String, builderTags: Map[String, String]): SamplingDecision + def decide(operationName: String, builderTags: Map[String, Span.TagValue]): SamplingDecision } object Sampler { @@ -37,7 +37,7 @@ object Sampler { } class Constant(decision: SamplingDecision) extends Sampler { - override def decide(operationName: String, builderTags: Map[String, String]): SamplingDecision = decision + override def decide(operationName: String, builderTags: Map[String, Span.TagValue]): SamplingDecision = decision override def toString: String = s"Sampler.Constant(decision = $decision)" @@ -47,7 +47,7 @@ object Sampler { val upperBoundary = Long.MaxValue * probability val lowerBoundary = -upperBoundary - override def decide(operationName: String, builderTags: Map[String, String]): SamplingDecision = { + override def decide(operationName: String, builderTags: Map[String, Span.TagValue]): SamplingDecision = { val random = ThreadLocalRandom.current().nextLong() if(random >= lowerBoundary && random <= upperBoundary) SamplingDecision.Sample else SamplingDecision.DoNotSample } diff --git a/kamon-core/src/main/scala/kamon/trace/Span.scala b/kamon-core/src/main/scala/kamon/trace/Span.scala index ffe7bed7..ce09a36e 100644 --- a/kamon-core/src/main/scala/kamon/trace/Span.scala +++ b/kamon-core/src/main/scala/kamon/trace/Span.scala @@ -35,6 +35,10 @@ trait BaseSpan { def addSpanTag(key: String, value: String): Span + def addSpanTag(key: String, value: Long): Span + + def addSpanTag(key: String, value: Boolean): Span + def addMetricTag(key: String, value: String): Span def addBaggage(key: String, value: String): Span @@ -64,8 +68,7 @@ trait Span extends BaseSpan { def annotate(timestampMicroseconds: Long, name: String, fields: Map[String, String]): Span = annotate(Span.Annotation(timestampMicroseconds, name, fields)) - - + } object Span { @@ -76,6 +79,8 @@ object Span { override def annotate(annotation: Annotation): Span = this override def addSpanTag(key: String, value: String): Span = this + override def addSpanTag(key: String, value: Long): Span = this + override def addSpanTag(key: String, value: Boolean): Span = this override def addMetricTag(key: String, value: String): Span = this override def addBaggage(key: String, value: String): Span = this override def getBaggage(key: String): Option[String] = None @@ -96,7 +101,7 @@ object Span { * @param startTimestampMicros * @param reporterRegistry */ - final class Real(spanContext: SpanContext, initialOperationName: String, initialTags: Map[String, String], + final class Real(spanContext: SpanContext, initialOperationName: String, initialTags: Map[String, Span.TagValue], startTimestampMicros: Long, reporterRegistry: ReporterRegistryImpl, tracer: Tracer) extends Span { private var collectMetrics: Boolean = true @@ -104,7 +109,7 @@ object Span { private val sampled: Boolean = spanContext.samplingDecision == SamplingDecision.Sample private var operationName: String = initialOperationName - private var spanTags = initialTags + private var spanTags: Map[String, Span.TagValue] = initialTags private var customMetricTags = Map.empty[String, String] private var annotations = List.empty[Span.Annotation] @@ -116,7 +121,21 @@ object Span { override def addSpanTag(key: String, value: String): Span = synchronized { if(sampled && open) - spanTags = spanTags + (key -> value) + spanTags = spanTags + (key -> TagValue.String(value)) + this + } + + override def addSpanTag(key: String, value: Long): Span = synchronized { + if(sampled && open) + spanTags = spanTags + (key -> TagValue.Number(value)) + this + } + + override def addSpanTag(key: String, value: Boolean): Span = synchronized { + if(sampled && open) { + val tagValue = if (value) TagValue.True else TagValue.False + spanTags = spanTags + (key -> tagValue) + } this } @@ -174,7 +193,7 @@ object Span { latencyHistogram.record(elapsedTime) spanTags.get("error").foreach { errorTag => - if(errorTag != null && errorTag.equals(Span.BooleanTagTrueValue)) { + if(errorTag != null && errorTag.equals(TagValue.True)) { Span.Metrics.SpanErrorCount.refine(metricTags).increment() } } @@ -182,20 +201,26 @@ object Span { } object Real { - def apply(spanContext: SpanContext, initialOperationName: String, initialTags: Map[String, String], + def apply(spanContext: SpanContext, initialOperationName: String, initialTags: Map[String, Span.TagValue], startTimestampMicros: Long, reporterRegistry: ReporterRegistryImpl, tracer: Tracer): Real = new Real(spanContext, initialOperationName, initialTags, startTimestampMicros, reporterRegistry, tracer) } + sealed trait TagValue + object TagValue { + sealed trait Boolean extends TagValue + case object True extends Boolean + case object False extends Boolean + + case class String(string: java.lang.String) extends TagValue + case class Number(number: Long) extends TagValue + } object Metrics { val SpanProcessingTimeMetric = Kamon.histogram("span.processing-time", MeasurementUnit.time.microseconds) val SpanErrorCount = Kamon.counter("span.error-count") } - val BooleanTagTrueValue = "1" - val BooleanTagFalseValue = "0" - case class Annotation(timestampMicros: Long, name: String, fields: Map[String, String]) case class FinishedSpan( @@ -203,7 +228,7 @@ object Span { operationName: String, startTimestampMicros: Long, endTimestampMicros: Long, - tags: Map[String, String], + tags: Map[String, Span.TagValue], annotations: Seq[Annotation] ) } \ No newline at end of file diff --git a/kamon-core/src/main/scala/kamon/trace/Tracer.scala b/kamon-core/src/main/scala/kamon/trace/Tracer.scala index c10974f5..d7ca5609 100644 --- a/kamon-core/src/main/scala/kamon/trace/Tracer.scala +++ b/kamon-core/src/main/scala/kamon/trace/Tracer.scala @@ -21,6 +21,7 @@ import java.nio.ByteBuffer import com.typesafe.config.Config import kamon.ReporterRegistryImpl import kamon.metric.MetricLookup +import kamon.trace.Span.TagValue import kamon.trace.SpanContext.{SamplingDecision, Source} import kamon.trace.Tracer.SpanBuilder import kamon.util.Clock @@ -114,7 +115,7 @@ object Tracer { final class SpanBuilder(operationName: String, tracer: Tracer.Default, reporterRegistry: ReporterRegistryImpl) { private var parentContext: SpanContext = _ private var startTimestamp = 0L - private var initialTags = Map.empty[String, String] + private var initialTags = Map.empty[String, Span.TagValue] private var useActiveSpanAsParent = true def asChildOf(parentContext: SpanContext): SpanBuilder = { @@ -126,7 +127,18 @@ object Tracer { asChildOf(parentSpan.context()) def withSpanTag(key: String, value: String): SpanBuilder = { - this.initialTags = this.initialTags + (key -> value) + this.initialTags = this.initialTags + (key -> TagValue.String(value)) + this + } + + def withSpanTag(key: String, value: Long): SpanBuilder = { + this.initialTags = this.initialTags + (key -> TagValue.Number(value)) + this + } + + def withSpanTag(key: String, value: Boolean): SpanBuilder = { + val tagValue = if (value) TagValue.True else TagValue.False + this.initialTags = this.initialTags + (key -> tagValue) this } -- cgit v1.2.3