go-micro.dev/v5@v5.12.0/wrapper/trace/opentelemetry/opentelemetry.go (about) 1 package opentelemetry 2 3 import ( 4 "context" 5 "strings" 6 7 "go-micro.dev/v5/metadata" 8 "go.opentelemetry.io/otel" 9 "go.opentelemetry.io/otel/baggage" 10 "go.opentelemetry.io/otel/propagation" 11 "go.opentelemetry.io/otel/trace" 12 ) 13 14 const ( 15 instrumentationName = "github.com/micro/plugins/v5/wrapper/trace/opentelemetry" 16 ) 17 18 // StartSpanFromContext returns a new span with the given operation name and options. If a span 19 // is found in the context, it will be used as the parent of the resulting span. 20 func StartSpanFromContext(ctx context.Context, tp trace.TracerProvider, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) { 21 md, ok := metadata.FromContext(ctx) 22 if !ok { 23 md = make(metadata.Metadata) 24 } 25 propagator, carrier := otel.GetTextMapPropagator(), make(propagation.MapCarrier) 26 for k, v := range md { 27 for _, f := range propagator.Fields() { 28 if strings.EqualFold(k, f) { 29 carrier[f] = v 30 } 31 } 32 } 33 ctx = propagator.Extract(ctx, carrier) 34 spanCtx := trace.SpanContextFromContext(ctx) 35 ctx = baggage.ContextWithBaggage(ctx, baggage.FromContext(ctx)) 36 37 var tracer trace.Tracer 38 var span trace.Span 39 if tp != nil { 40 tracer = tp.Tracer(instrumentationName) 41 } else { 42 tracer = otel.Tracer(instrumentationName) 43 } 44 ctx, span = tracer.Start(trace.ContextWithRemoteSpanContext(ctx, spanCtx), name, opts...) 45 46 carrier = make(propagation.MapCarrier) 47 propagator.Inject(ctx, carrier) 48 for k, v := range carrier { 49 //lint:ignore SA1019 no unicode punctution handle needed 50 md.Set(strings.Title(k), v) 51 } 52 ctx = metadata.NewContext(ctx, md) 53 54 return ctx, span 55 }