package tracing import ( "context" "github.com/go-kratos/kratos/v2/middleware" "github.com/go-kratos/kratos/v2/transport" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/trace" ) // Option is tracing option. type Option func(*options) type options struct { TracerProvider trace.TracerProvider Propagator propagation.TextMapPropagator } // WithPropagator with tracer propagator. func WithPropagator(propagator propagation.TextMapPropagator) Option { return func(opts *options) { opts.Propagator = propagator } } // WithTracerProvider with tracer provider. func WithTracerProvider(provider trace.TracerProvider) Option { return func(opts *options) { opts.TracerProvider = provider } } // Server returns a new server middleware for OpenTelemetry. func Server(opts ...Option) middleware.Middleware { tracer := NewTracer(trace.SpanKindServer, opts...) return func(handler middleware.Handler) middleware.Handler { return func(ctx context.Context, req interface{}) (reply interface{}, err error) { if tr, ok := transport.FromServerContext(ctx); ok { var span trace.Span ctx, span = tracer.Start(ctx, tr.Kind().String(), tr.Operation(), tr.RequestHeader()) defer func() { tracer.End(ctx, span, err) }() } return handler(ctx, req) } } } // Client returns a new client middleware for OpenTelemetry. func Client(opts ...Option) middleware.Middleware { tracer := NewTracer(trace.SpanKindClient, opts...) return func(handler middleware.Handler) middleware.Handler { return func(ctx context.Context, req interface{}) (reply interface{}, err error) { if tr, ok := transport.FromClientContext(ctx); ok { var span trace.Span ctx, span = tracer.Start(ctx, tr.Kind().String(), tr.Operation(), tr.RequestHeader()) defer func() { tracer.End(ctx, span, err) }() } return handler(ctx, req) } } }