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  }