diff options
author | Ivan Topolnjak <ivantopo@gmail.com> | 2017-07-14 14:12:47 +0200 |
---|---|---|
committer | Ivan Topolnjak <ivantopo@gmail.com> | 2017-07-14 14:12:47 +0200 |
commit | 34010efc7b273e50d805a277646f14aa96aaa8b2 (patch) | |
tree | 8f7a6f00eac4e0a4cb60c9093b3c5d06ed982662 /kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala | |
parent | 52c4503b6aea2309feeb550b7db2e5fa627dedc8 (diff) | |
download | Kamon-34010efc7b273e50d805a277646f14aa96aaa8b2.tar.gz Kamon-34010efc7b273e50d805a277646f14aa96aaa8b2.tar.bz2 Kamon-34010efc7b273e50d805a277646f14aa96aaa8b2.zip |
wip
Diffstat (limited to 'kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala')
-rw-r--r-- | kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala | 170 |
1 files changed, 118 insertions, 52 deletions
diff --git a/kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala b/kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala index 8e3a446b..23eb40db 100644 --- a/kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala +++ b/kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala @@ -17,82 +17,137 @@ package kamon.trace import java.net.{URLDecoder, URLEncoder} +import java.nio.ByteBuffer import java.util.concurrent.ThreadLocalRandom +import kamon.trace.SpanContext.{Baggage, SamplingDecision, Source} + import scala.collection.JavaConverters._ -import io.opentracing.propagation.TextMap import kamon.util.HexCodec trait SpanContextCodec[T] { def inject(spanContext: SpanContext, carrier: T): Unit - def extract(carrier: T, sampler: Sampler): SpanContext + def extract(carrier: T): Option[SpanContext] +} + +trait TextMap { + def get(key: String): Option[String] + def put(key: String, value: String): Unit + def values: Iterator[(String, String)] } + object SpanContextCodec { - val TextMap: SpanContextCodec[TextMap] = new TextMapSpanCodec( - traceIDKey = "TRACE_ID", - parentIDKey = "PARENT_ID", - spanIDKey = "SPAN_ID", - sampledKey = "SAMPLED", - baggagePrefix = "BAGGAGE_", - baggageValueEncoder = identity, - baggageValueDecoder = identity - ) - - val ZipkinB3: SpanContextCodec[TextMap] = new TextMapSpanCodec( - traceIDKey = "X-B3-TraceId", - parentIDKey = "X-B3-ParentSpanId", - spanIDKey = "X-B3-SpanId", - sampledKey = "X-B3-Sampled", - baggagePrefix = "X-B3-Baggage-", - baggageValueEncoder = urlEncode, - baggageValueDecoder = urlDecode - ) + trait Format[C] + object Format { + case object TextMap extends Format[TextMap] + case object HttpHeaders extends Format[TextMap] + case object Binary extends Format[ByteBuffer] + } + +// val ExtendedB3: SpanContextCodec[TextMap] = new TextMapSpanCodec( +// traceIDKey = "X-B3-TraceId", +// parentIDKey = "X-B3-ParentSpanId", +// spanIDKey = "X-B3-SpanId", +// sampledKey = "X-B3-Sampled", +// baggageKey = "X-Kamon-Baggage-", +// baggageValueEncoder = urlEncode, +// baggageValueDecoder = urlDecode +// ) private def urlEncode(s: String): String = URLEncoder.encode(s, "UTF-8") private def urlDecode(s: String): String = URLDecoder.decode(s, "UTF-8") - private class TextMapSpanCodec(traceIDKey: String, parentIDKey: String, spanIDKey: String, sampledKey: String, baggagePrefix: String, - baggageValueEncoder: String => String, baggageValueDecoder: String => String) extends SpanContextCodec[TextMap] { + private class ExtendedB3(identityProvider: IdentityProvider) extends SpanContextCodec[TextMap] { + import ExtendedB3.Headers + override def inject(spanContext: SpanContext, carrier: TextMap): Unit = { - carrier.put(traceIDKey, encodeLong(spanContext.traceID)) - carrier.put(parentIDKey, encodeLong(spanContext.parentID)) - carrier.put(spanIDKey, encodeLong(spanContext.spanID)) + carrier.put(Headers.TraceIdentifier, baggageValueEncoder(spanContext.traceID.string)) + carrier.put(parentIDKey, baggageValueEncoder(spanContext.parentID.string)) + carrier.put(spanIDKey, baggageValueEncoder(spanContext.spanID.string)) - spanContext.baggageItems().iterator().asScala.foreach { entry => - carrier.put(baggagePrefix + entry.getKey, baggageValueEncoder(entry.getValue)) + spanContext.baggage.getAll().foreach { + case (key, value) => carrier.put(baggageKey + key, baggageValueEncoder(value)) } } - override def extract(carrier: TextMap, sampler: Sampler): SpanContext = { - var traceID: String = null - var parentID: String = null - var spanID: String = null - var sampled: String = null - var baggage: Map[String, String] = Map.empty - - carrier.iterator().asScala.foreach { entry => - if(entry.getKey.equals(traceIDKey)) - traceID = baggageValueDecoder(entry.getValue) - else if(entry.getKey.equals(parentIDKey)) - parentID = baggageValueDecoder(entry.getValue) - else if(entry.getKey.equals(spanIDKey)) - spanID = baggageValueDecoder(entry.getValue) - else if(entry.getKey.equals(sampledKey)) - sampled = entry.getValue - else if(entry.getKey.startsWith(baggagePrefix)) - baggage = baggage + (entry.getKey.substring(baggagePrefix.length) -> baggageValueDecoder(entry.getValue)) - } + override def extract(carrier: TextMap): Option[SpanContext] = { + val traceID = carrier.get(Headers.TraceIdentifier) + .map(identityProvider.traceIdentifierGenerator().from) + .getOrElse(IdentityProvider.NoIdentifier) + + val spanID = carrier.get(Headers.SpanIdentifier) + .map(identityProvider.spanIdentifierGenerator().from) + .getOrElse(IdentityProvider.NoIdentifier) + + if(traceID != IdentityProvider.NoIdentifier && spanID != IdentityProvider.NoIdentifier) { + val parentID = carrier.get(Headers.ParentSpanIdentifier) + .map(identityProvider.spanIdentifierGenerator().from) + .getOrElse(IdentityProvider.NoIdentifier) + + val samplingDecision = carrier.get(Headers.Flags).orElse(carrier.get(Headers.Sampled)) match { + case Some(sampled) if sampled == "1" => SamplingDecision.Sample + case Some(sampled) if sampled == "0" => SamplingDecision.DoNotSample + case _ => SamplingDecision.Unknown + } + + + + + Some(SpanContext(traceID, spanID, parentID, samplingDecision, ???, Source.Remote)) + + } else None + + val minimalSpanContext = + for { + traceID <- carrier.get(traceIDKey).map(identityProvider.traceIdentifierGenerator().from) + spanID <- carrier.get(spanIDKey).map(identityProvider.spanIdentifierGenerator().from) + } yield { + + + } + + + +// var traceID: String = null +// var parentID: String = null +// var spanID: String = null +// var sampled: String = null +// var baggage: Map[String, String] = Map.empty +// +// carrier.iterator().asScala.foreach { entry => +// if(entry.getKey.equals(traceIDKey)) +// traceID = baggageValueDecoder(entry.getValue) +// else if(entry.getKey.equals(parentIDKey)) +// parentID = baggageValueDecoder(entry.getValue) +// else if(entry.getKey.equals(spanIDKey)) +// spanID = baggageValueDecoder(entry.getValue) +// else if(entry.getKey.equals(sampledKey)) +// sampled = entry.getValue +// else if(entry.getKey.startsWith(baggagePrefix)) +// baggage = baggage + (entry.getKey.substring(baggagePrefix.length) -> baggageValueDecoder(entry.getValue)) +// } +// +// if(traceID != null && spanID != null) { +// val actualParent = if(parentID == null) 0L else decodeLong(parentID) +// val isSampled = if(sampled == null) sampler.decide(ThreadLocalRandom.current().nextLong()) else sampled.equals("1") +// +// new SpanContext(decodeLong(traceID), decodeLong(spanID), actualParent, isSampled, baggage) +// } else null +// +// None + } - if(traceID != null && spanID != null) { - val actualParent = if(parentID == null) 0L else decodeLong(parentID) - val isSampled = if(sampled == null) sampler.decide(ThreadLocalRandom.current().nextLong()) else sampled.equals("1") + private def encodeBaggage(baggage: Baggage): String = { + if(baggage.getAll().nonEmpty) { - new SpanContext(decodeLong(traceID), decodeLong(spanID), actualParent, isSampled, baggage) - } else null + baggage.getAll().foreach { + case (key, value) => + } + } else "" } private def decodeLong(input: String): Long = @@ -102,4 +157,15 @@ object SpanContextCodec { HexCodec.toLowerHex(input) } + + object ExtendedB3 { + object Headers { + val TraceIdentifier = "X-B3-TraceId" + val ParentSpanIdentifier = "X-B3-ParentSpanId" + val SpanIdentifier = "X-B3-SpanId" + val Sampled = "X-B3-Sampled" + val Flags = "X-B3-Flags" + val Baggage = "X-B3-Extra-Baggage" + } + } } |