Skip to content

Instantly share code, notes, and snippets.

@huntc
Last active July 23, 2020 08:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save huntc/e527e0fd3f71b400ba8bbc8afd545b01 to your computer and use it in GitHub Desktop.
Save huntc/e527e0fd3f71b400ba8bbc8afd545b01 to your computer and use it in GitHub Desktop.
Illustrates the migration of Open Tracing context propagation (injectors/extractors) to Open Telemetry. `DurableQueue.Headers` is a `Seq[(String, ByteString)]`.
/**
* AS IT WAS WITH OPENTRACING
* Utilities to transform headers of a Durable Queue message into
* Open Tracing span contexts and vice-versa.
*/
object Propagation {
/**
* Return a span context from headers and a tracer.
*/
def spanContext(headers: DurableQueue.Headers, tracer: Tracer): SpanContext = {
val spanHeaders = headers.map { case (k, v) => k -> v.utf8String }.toMap.asJava
tracer.extract(Format.Builtin.TEXT_MAP, new TextMapAdapter(spanHeaders))
}
/**
* Return headers given a span context and a tracer.
*/
def headers(spanContext: SpanContext, tracer: Tracer): DurableQueue.Headers = {
val headers = new util.HashMap[String, String]()
tracer.inject(
spanContext,
Format.Builtin.TEXT_MAP,
new TextMapAdapter(headers)
)
headers.asScala.map {
case (k, v) => k -> ByteString(v)
}.toList
}
}
/**
* AS IT NOW IS WITH OPEN TELEMETRY
* Utilities to transform headers of a Durable Queue message into
* Open Telemetry contexts and vice-versa.
*/
object Propagation {
/**
* Return a new context from headers and a context.
*/
def context(headers: DurableQueue.Headers, context: Context): Context =
OpenTelemetry.getPropagators.getHttpTextFormat.extract(
context,
headers,
(carrier: DurableQueue.Headers, key: String) =>
carrier.find(_._1 == key).map(_._2.utf8String).orNull
)
/**
* Return headers given a context.
*/
def headers(context: Context): DurableQueue.Headers = {
val headers = new util.HashMap[String, String]()
OpenTelemetry.getPropagators.getHttpTextFormat.inject(
context,
headers,
(carrier: util.HashMap[String, String], key: String, value: String) => carrier.put(key, value)
)
headers.asScala.map {
case (k, v) => k -> ByteString(v)
}.toList
}
}
@huntc
Copy link
Author

huntc commented Jul 23, 2020

Context propagation feels quite different in Open Telemetry. For example, you must associate a context with a span by obtaining a scope explicitly e.g. via tracer.withSpan. With OpenTracing, the scope was provided. Here's how the above injection of headers takes place:

      val span   = tracer.spanBuilder("some-span").startSpan()
      span.end()
      val _ = Using.resource(tracer.withSpan(span)) { _ =>
        val durabaleQueueHeaders = Propagation.headers(Context.current())
       ...
      }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment