package tracing import ( "context" "github.com/gin-gonic/gin" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/jaeger" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" tracesdk "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.12.0" "go.opentelemetry.io/otel/trace" ) // NewTracerProvider returns an OpenTelemetry TracerProvider configured to use // the Jaeger exporter that will send spans to the provided url. The returned // TracerProvider will also use a Resource configured with all the information // about the application. func NewTracerProvider(serviceName, version, serviceID, url string) (*tracesdk.TracerProvider, error) { // Create the Jaeger exporter exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))) if err != nil { return nil, err } tp := tracesdk.NewTracerProvider( tracesdk.WithBatcher(exp), tracesdk.WithResource(resource.NewWithAttributes( semconv.SchemaURL, semconv.ServiceNameKey.String(serviceName), semconv.ServiceVersionKey.String(version), semconv.ServiceInstanceIDKey.String(serviceID), )), tracesdk.WithSampler(tracesdk.AlwaysSample()), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) return tp, nil } // func TracingContextWrapper(next http.Handler) http.Handler { // return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // propagator, md := otel.GetTextMapPropagator(), make(metadata.Metadata) // propagator.Inject(r.Context(), propagation.MapCarrier(md)) // r2 := r.WithContext(metadata.NewContext(r.Context(), md)) // next.ServeHTTP(w, r2) // }) // } func NewTracingContextWrapper() gin.HandlerFunc { return func(c *gin.Context) { propagator := otel.GetTextMapPropagator() // 从 Gin 上下文中提取 HTTP 请求头 md := make(map[string]string) propagator.Inject(c.Request.Context(), propagation.HeaderCarrier(c.Request.Header)) propagator.Inject(c.Request.Context(), propagation.MapCarrier(md)) // 创建包含提取的元数据的新 Gin 上下文 ctx := trace.ContextWithSpan(c.Request.Context(), trace.SpanFromContext(c.Request.Context())) ctx = context.WithValue(ctx, "metadata", md) c.Request = c.Request.WithContext(ctx) // 继续处理请求 c.Next() } }