github.com/zly-app/zapp@v1.3.3/pkg/utils/trace.go (about) 1 package utils 2 3 import ( 4 "context" 5 "strings" 6 7 "github.com/opentracing/opentracing-go" 8 ) 9 10 var Trace = &traceCli{} 11 12 type traceCli struct{} 13 14 // 将span存入ctx 15 func (*traceCli) SaveSpan(ctx context.Context, span opentracing.Span) context.Context { 16 return opentracing.ContextWithSpan(ctx, span) 17 } 18 19 // 从ctx中获取span 20 func (*traceCli) GetSpan(ctx context.Context) opentracing.Span { 21 return opentracing.SpanFromContext(ctx) 22 } 23 24 // 开始一个span 25 func (*traceCli) StartSpan(operationName string) opentracing.Span { 26 return opentracing.StartSpan(operationName) 27 } 28 29 // 获取或生成子span 30 func (*traceCli) GetChildSpan(ctx context.Context, operationName string) opentracing.Span { 31 parentSpan := opentracing.SpanFromContext(ctx) 32 if parentSpan != nil { 33 return opentracing.StartSpan(operationName, opentracing.ChildOf(parentSpan.Context())) 34 } 35 return opentracing.StartSpan(operationName) 36 } 37 38 // 获取或生成跟随span 39 func (*traceCli) GetFollowSpan(ctx context.Context, operationName string) opentracing.Span { 40 parentSpan := opentracing.SpanFromContext(ctx) 41 if parentSpan != nil { 42 return opentracing.StartSpan(operationName, opentracing.FollowsFrom(parentSpan.Context())) 43 } 44 return opentracing.StartSpan(operationName) 45 } 46 47 // 获取TraceID 48 func (c *traceCli) GetTraceID(span opentracing.Span) string { 49 if span == nil { 50 return "" 51 } 52 53 // 支持 otel 中获取 traceID 54 { 55 ctx := opentracing.ContextWithSpan(context.Background(), span) 56 sc := Otel.GetSpan(ctx).SpanContext() 57 if sc.IsValid() { 58 return sc.TraceID().String() 59 } 60 } 61 62 trace := span.Tracer() 63 if trace == nil { 64 return "" 65 } 66 67 carrier := opentracing.TextMapCarrier{} 68 err := trace.Inject(span.Context(), opentracing.TextMap, carrier) 69 if err != nil { 70 return "" 71 } 72 73 traceID := c.getJaegerTraceID(carrier) 74 if traceID == "" { 75 traceID = c.getZipKinTraceID(carrier) 76 } 77 return traceID 78 } 79 80 func (c *traceCli) GetTraceIDWithContext(ctx context.Context) (string, string) { 81 // 支持 otel 中获取 traceID 82 { 83 sc := Otel.GetSpan(ctx).SpanContext() 84 if sc.IsValid() { 85 return sc.TraceID().String(), sc.SpanID().String() 86 } 87 } 88 89 span := c.GetSpan(ctx) 90 return c.GetTraceID(span), "" 91 } 92 93 func (*traceCli) getJaegerTraceID(carrier opentracing.TextMapCarrier) string { 94 const TraceID = "uber-trace-id" 95 values := strings.SplitN(carrier[TraceID], ":", 2) 96 if len(values) >= 1 { 97 return values[0] 98 } 99 return "" 100 } 101 102 func (*traceCli) getZipKinTraceID(carrier opentracing.TextMapCarrier) string { 103 const TraceID = "x-b3-traceid" 104 return carrier[TraceID] 105 }