aboutsummaryrefslogtreecommitdiff
path: root/kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2017-07-14 14:12:47 +0200
committerIvan Topolnjak <ivantopo@gmail.com>2017-07-14 14:12:47 +0200
commit34010efc7b273e50d805a277646f14aa96aaa8b2 (patch)
tree8f7a6f00eac4e0a4cb60c9093b3c5d06ed982662 /kamon-core/src/main/scala/kamon/trace/SpanContextCodec.scala
parent52c4503b6aea2309feeb550b7db2e5fa627dedc8 (diff)
downloadKamon-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.scala170
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"
+ }
+ }
}