github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/go-grpc-middleware/tracing/opentracing/id_extract.go (about) 1 package grpc_opentracing 2 3 import ( 4 "strings" 5 6 grpc_ctxtags "github.com/hxx258456/ccgo/go-grpc-middleware/tags" 7 "github.com/hxx258456/ccgo/grpc/grpclog" 8 opentracing "github.com/opentracing/opentracing-go" 9 ) 10 11 const ( 12 TagTraceId = "trace.traceid" 13 TagSpanId = "trace.spanid" 14 TagSampled = "trace.sampled" 15 jaegerNotSampledFlag = "0" 16 ) 17 18 // injectOpentracingIdsToTags writes trace data to ctxtags. 19 // This is done in an incredibly hacky way, because the public-facing interface of opentracing doesn't give access to 20 // the TraceId and SpanId of the SpanContext. Only the Tracer's Inject/Extract methods know what these are. 21 // Most tracers have them encoded as keys with 'traceid' and 'spanid': 22 // https://github.com/openzipkin/zipkin-go-opentracing/blob/594640b9ef7e5c994e8d9499359d693c032d738c/propagation_ot.go#L29 23 // https://github.com/opentracing/basictracer-go/blob/1b32af207119a14b1b231d451df3ed04a72efebf/propagation_ot.go#L26 24 // Jaeger from Uber use one-key schema with next format '{trace-id}:{span-id}:{parent-span-id}:{flags}' 25 // https://www.jaegertracing.io/docs/client-libraries/#trace-span-identity 26 func injectOpentracingIdsToTags(span opentracing.Span, tags grpc_ctxtags.Tags) { 27 if err := span.Tracer().Inject(span.Context(), opentracing.HTTPHeaders, &tagsCarrier{tags}); err != nil { 28 grpclog.Infof("grpc_opentracing: failed extracting trace info into ctx %v", err) 29 } 30 } 31 32 // tagsCarrier is a really hacky way of 33 type tagsCarrier struct { 34 grpc_ctxtags.Tags 35 } 36 37 func (t *tagsCarrier) Set(key, val string) { 38 key = strings.ToLower(key) 39 if strings.Contains(key, "traceid") { 40 t.Tags.Set(TagTraceId, val) // this will most likely be base-16 (hex) encoded 41 } 42 43 if strings.Contains(key, "spanid") && !strings.Contains(strings.ToLower(key), "parent") { 44 t.Tags.Set(TagSpanId, val) // this will most likely be base-16 (hex) encoded 45 } 46 47 if strings.Contains(key, "sampled") { 48 switch val { 49 case "true", "false": 50 t.Tags.Set(TagSampled, val) 51 } 52 } 53 54 if key == "uber-trace-id" { 55 parts := strings.Split(val, ":") 56 if len(parts) == 4 { 57 t.Tags.Set(TagTraceId, parts[0]) 58 t.Tags.Set(TagSpanId, parts[1]) 59 60 if parts[3] != jaegerNotSampledFlag { 61 t.Tags.Set(TagSampled, "true") 62 } else { 63 t.Tags.Set(TagSampled, "false") 64 } 65 } 66 } 67 }