func()

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
	}
}