This repository has been archived by the owner on Dec 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 202
Implement Stackdriver Propagation #1992
Labels
Comments
as we needed this feature, my dear colleague @martinheld implemented the class directly in our service to save time. ( inspired by https://github.com/census-instrumentation/opencensus-node/blob/master/packages/opencensus-propagation-stackdriver/src/stackdriver-format.ts ) unfortunately we didnt find the time afterwards to make a proper PR here. reasons:
however wanted to share the code as it might help people. anyone is invited to take it and maybe someone makes a proper PR for this ! its used simply like val tracer = Tracing.getTracer()
val spanContext = OpencensusStackdriverPropagation.extract(call.request)
val rootSpan = tracer.spanBuilderWithRemoteParent("my-span-name", spanContext).startScopedSpan()
... import io.ktor.request.ApplicationRequest
import io.ktor.request.header
import io.opencensus.trace.SpanContext
import io.opencensus.trace.TraceId
import io.opencensus.trace.SpanId
import io.opencensus.trace.TraceOptions
import io.opencensus.trace.Tracestate
object OpencensusStackdriverPropagation {
val TRACE_CONTEXT_HEADER_NAME = "x-cloud-trace-context"
val TRACE_TRUE = 0x1
fun extract(request: ApplicationRequest): SpanContext? {
val traceContextHeader = request.header(TRACE_CONTEXT_HEADER_NAME)
logger.debug("$TRACE_CONTEXT_HEADER_NAME: $traceContextHeader")
if (traceContextHeader == null) return null
lateinit var traceParams: Triple<String?, String?, Int?>
try {
traceParams = getTraceParams(traceContextHeader)
} catch (e: Exception) {
logger.error(e.message)
return null
}
return getSpanContext(traceParams)
}
private fun getSpanContext(traceParams: Triple<String?, String?, Int?>): SpanContext? {
val (traceId, spanId, options) = traceParams
if (traceId != null && spanId != null && options != null) {
val traceIdObj = TraceId.fromLowerBase16(traceId)
val spanIdObj = SpanId.fromLowerBase16(spanId)
val optionsObj = TraceOptions.fromByte(options.toByte())
val spanContext = SpanContext.create(traceIdObj, spanIdObj, optionsObj, Tracestate.builder().build())
logger.debug("returning SpanContext: $spanContext")
return spanContext
}
return null
}
private fun getTraceParams(traceContextHeader: String): Triple<String?, String?, Int?> {
val regex = """([0-9a-fA-F]+)(?:\/([0-9]+))""".toRegex()
val matchResult = regex.find(traceContextHeader)
if (matchResult == null || matchResult.groups.size <3) {
logger.debug("Parsing tracing context header failed")
return Triple(null, null, null)
}
val(traceId, parsedSpanId) = matchResult.destructured
val spanIdHex = parsedSpanId.toULong().toString(16)
val spanId = "0000000000000000$spanIdHex".takeLast(16)
val options = TRACE_TRUE
return Triple(traceId, spanId, options)
}
} |
Thanks for the tips here @philicious. I was working on this yesterday, and I found the algorithm Zipkin uses for parsing the X-Cloud-Trace-Context header: |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
For distributed tracing in GCP (Google Cloud Platform), the Google LoadBalancers add
x-cloud-trace-context
header with format"X-Cloud-Trace-Context: TRACE_ID/SPAN_ID;o=TRACE_TRUE"
These 3 values need to be set in
SpanContext
The text was updated successfully, but these errors were encountered: