in module/apmot/tracer.go [137:190]
func (t *otTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
switch format {
case opentracing.TextMap, opentracing.HTTPHeaders:
var traceparentHeaderValue string
var tracestateHeaderValues []string
switch carrier := carrier.(type) {
case opentracing.HTTPHeadersCarrier:
traceparentHeaderValue = http.Header(carrier).Get(apmhttp.W3CTraceparentHeader)
if traceparentHeaderValue == "" {
traceparentHeaderValue = http.Header(carrier).Get(apmhttp.ElasticTraceparentHeader)
}
tracestateHeaderValues = http.Header(carrier)[apmhttp.TracestateHeader]
case opentracing.TextMapReader:
carrier.ForeachKey(func(key, val string) error {
switch textproto.CanonicalMIMEHeaderKey(key) {
case apmhttp.W3CTraceparentHeader:
traceparentHeaderValue = val
case apmhttp.ElasticTraceparentHeader:
// The W3C header value always trumps the Elastic one,
// hence we only set the value if not set already.
if traceparentHeaderValue == "" {
traceparentHeaderValue = val
}
case apmhttp.TracestateHeader:
tracestateHeaderValues = append(tracestateHeaderValues, val)
}
return nil
})
default:
return nil, opentracing.ErrInvalidCarrier
}
if traceparentHeaderValue == "" {
return nil, opentracing.ErrSpanContextNotFound
}
traceContext, err := apmhttp.ParseTraceparentHeader(traceparentHeaderValue)
if err != nil {
return nil, err
}
traceContext.State, _ = apmhttp.ParseTracestateHeader(tracestateHeaderValues...)
return &spanContext{tracer: t, traceContext: traceContext}, nil
case opentracing.Binary:
reader, ok := carrier.(io.Reader)
if !ok {
return nil, opentracing.ErrInvalidCarrier
}
traceContext, err := binaryExtract(reader)
if err != nil {
return nil, err
}
return &spanContext{tracer: t, traceContext: traceContext}, nil
default:
return nil, opentracing.ErrUnsupportedFormat
}
}