package middleware import ( "encoding/json" "strconv" "finclip-app-manager/infrastructure/config" "github.com/gin-gonic/gin" "github.com/openzipkin/zipkin-go" "github.com/openzipkin/zipkin-go/model" zkHttp "github.com/openzipkin/zipkin-go/reporter/http" ) var gTracer *zipkin.Tracer func init() { if config.GetConfig().ZipKinUrl != "" && config.GetConfig().ZipKinSToS { reporter := zkHttp.NewReporter(config.GetConfig().ZipKinUrl) endpoint, err := zipkin.NewEndpoint(config.GetConfig().ServerName, "") if err != nil { log.Errorf("zipkin unable to create local endpoint: %v\n", err) return } nativeTracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint)) if err != nil { log.Errorf("zipkin unable to create tracer: %v\n", err) return } gTracer = nativeTracer } } func AddZipkinTraceSpan(c *gin.Context) { if gTracer != nil { spanContextStr := c.Request.Header.Get("Zipkin-Span-Context") var span zipkin.Span if spanContextStr != "" { var spanContext model.SpanContext json.Unmarshal([]byte(spanContextStr), &spanContext) span = gTracer.StartSpan(c.Request.URL.Path, zipkin.Parent(spanContext)) } else { kongTraceId := c.Request.Header.Get("X-B3-Traceid") kongSpanId := c.Request.Header.Get("X-B3-Spanid") //X-B3-Spanid X-B3-Parentspanid X-B3-Sampled if kongTraceId != "" && kongSpanId != "" { var kongParentSpanContext model.SpanContext spandIdInt, _ := strconv.ParseUint(kongSpanId, 16, 64) kongParentSpanContext.ID = model.ID(spandIdInt) kongTraceIdIntHigh, _ := strconv.ParseUint(kongTraceId[0:16], 16, 64) kongTraceIdIntLow, _ := strconv.ParseUint(kongTraceId[16:], 16, 64) kongParentSpanContext.TraceID.High = kongTraceIdIntHigh kongParentSpanContext.TraceID.Low = kongTraceIdIntLow span = gTracer.StartSpan(c.Request.URL.Path, zipkin.Parent(kongParentSpanContext)) } else { span = gTracer.StartSpan(c.Request.URL.Path) } } if config.GetConfig().ZipKinSToS { //需要调用其他服务 spanBytes, _ := json.Marshal(span.Context()) spanId := span.Context().ID.String() c.Set("zipkin_span_id", spanId) c.Set("zipkin_trace_span_id_"+spanId, string(spanBytes)) } defer span.Finish() } c.Next() }