package base import ( "github.com/gin-gonic/gin" "github.com/opentracing/opentracing-go" jaeger "github.com/uber/jaeger-client-go" "github.com/uber/jaeger-client-go/utils" ) // enum list const ( TraceContextKey string = "traceContext" RequestIDKey string = "requestId" ) // InitTracer 生成全局tracer,链接agent,如果agent不可用,使用logger report // "jaeger-agent:5775", 0 func InitTracer() { var report jaeger.Reporter transport, err := jaeger.NewUDPTransportWithParams(jaeger.UDPTransportParams{ AgentClientUDPParams: utils.AgentClientUDPParams{ HostPort: "jaeger-agent:5775", MaxPacketSize: 0, Logger: jaeger.NullLogger, }, }) if err != nil { report = jaeger.NewNullReporter() } else { report = jaeger.NewRemoteReporter(transport) } tracer, _ := jaeger.NewTracer(GetServiceName(), jaeger.NewConstSampler(true), report, jaeger.TracerOptions.CustomHeaderKeys(&jaeger.HeadersConfig{ JaegerDebugHeader: jaeger.JaegerDebugHeader, JaegerBaggageHeader: jaeger.JaegerBaggageHeader, TraceContextHeaderName: "trace-id", TraceBaggageHeaderPrefix: "srg-", })) opentracing.SetGlobalTracer(tracer) return } // TracerStartSpan for API func TracerStartSpan(parent opentracing.SpanContext, operationName string, tags map[string]interface{}) opentracing.Span { var options []opentracing.StartSpanOption if parent != nil { options = append(options, opentracing.ChildOf(parent)) } span := opentracing.StartSpan(operationName, options...) for k, v := range tags { span.SetTag(k, v) } return span } // TracerContext create one new func TracerContext(ctx *gin.Context, operationName string, tags map[string]interface{}) *gin.Context { if ctx == nil { return nil } var parent opentracing.SpanContext if ctx != nil { tempSpan, exist := ctx.Get(TraceContextKey) if exist && tempSpan != nil { parent = tempSpan.(opentracing.Span).Context() } } newOne := TracerStartSpan(parent, operationName, tags) newC := ctx.Copy() newC.Set(TraceContextKey, newOne) one, ok := newOne.Context().(jaeger.SpanContext) if ok { newC.Set(RequestIDKey, one.String()) } return newC } // GetRequestIdFromTrace use trace id as request id func GetRequestIdFromTrace(ctx *gin.Context) string { var spanContext jaeger.SpanContext if ctx != nil { tempSpan, exist := ctx.Get(TraceContextKey) if exist && tempSpan != nil { spanContext = tempSpan.(opentracing.Span).Context().(jaeger.SpanContext) return spanContext.String() } } return "" } // GetRequestId for API func GetRequestId(ctx *gin.Context) string { if ctx == nil { return "" } requestID, exist := ctx.Get(RequestIDKey) if exist { return requestID.(string) } return "" } type traceLogger struct{} func (logger *traceLogger) Error(msg string) { ErrorLogger(nil, msg) } func (logger *traceLogger) Infof(msg string, args ...interface{}) { DebugfLogger(nil, msg, args...) } // TracerToString for API func TracerToString(ctx *gin.Context) string { return GetRequestIdFromTrace(ctx) } // StringToTracer for API //func StringToTracer(g *gin.Engine, input string, name string, tags map[string]interface{}) *gin.Context { // newC := gin.CreateNewContext(g) // if len(input) == 0 { // return TracerContext(newC, name, tags) // } // span, err := jaeger.ContextFromString(input) // if err != nil { // return TracerContext(newC, name, tags) // } // // newOne := TracerStartSpan(span, name, tags) // newC.Set(TraceContextKey, newOne) // one, ok := newOne.Context().(jaeger.SpanContext) // if ok { // newC.Set(RequestIDKey, one.String()) // } // // return newC //} // //// TracerForGRPCServiceFromString for API //func TracerForGRPCServiceFromString(g *gin.Engine, traceID string, service, grpcHandle string) *gin.Context { // return StringToTracer(g, traceID, "GRPC_"+service+"."+grpcHandle, map[string]interface{}{ // ext.SpanKindRPCServer.Key: ext.SpanKindRPCServer.Value, // }) //} // //// TracerForGRPCClientFromString for API //func TracerForGRPCClientFromString(g *gin.Engine, traceID string, service, grpcHandle string) *gin.Context { // return StringToTracer(g, traceID, "GRPC_"+service+"."+grpcHandle, map[string]interface{}{ // ext.SpanKindRPCClient.Key: ext.SpanKindRPCClient.Value, // }) //} // //// TracerForRMQServiceFromString for API //func TracerForRMQServiceFromString(g *gin.Engine, traceID string, service, grpcHandle string) *gin.Context { // return StringToTracer(g, traceID, "RMQ_"+service+"."+grpcHandle, map[string]interface{}{ // ext.SpanKindRPCServer.Key: ext.SpanKindRPCServer.Value, // }) //} // //// TracerForRMQClientFromString for API //func TracerForRMQClientFromString(g *gin.Engine, traceID string, service, grpcHandle string) *gin.Context { // return StringToTracer(g, traceID, "RMQ_"+service+"."+grpcHandle, map[string]interface{}{ // ext.SpanKindRPCClient.Key: ext.SpanKindRPCClient.Value, // }) //} //