You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.6 KiB
95 lines
2.6 KiB
package tracing |
|
|
|
import ( |
|
"context" |
|
|
|
"github.com/go-kratos/kratos/v2/log" |
|
|
|
"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 { |
|
tracerName string |
|
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. |
|
// Deprecated: use otel.SetTracerProvider(provider) instead. |
|
func WithTracerProvider(provider trace.TracerProvider) Option { |
|
return func(opts *options) { |
|
opts.tracerProvider = provider |
|
} |
|
} |
|
|
|
// WithTracerName with tracer name |
|
func WithTracerName(tracerName string) Option { |
|
return func(opts *options) { |
|
opts.tracerName = tracerName |
|
} |
|
} |
|
|
|
// 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.Operation(), tr.RequestHeader()) |
|
setServerSpan(ctx, span, req) |
|
defer func() { tracer.End(ctx, span, reply, 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.Operation(), tr.RequestHeader()) |
|
setClientSpan(ctx, span, req) |
|
defer func() { tracer.End(ctx, span, reply, err) }() |
|
} |
|
return handler(ctx, req) |
|
} |
|
} |
|
} |
|
|
|
// TraceID returns a traceid valuer. |
|
func TraceID() log.Valuer { |
|
return func(ctx context.Context) interface{} { |
|
if span := trace.SpanContextFromContext(ctx); span.HasTraceID() { |
|
return span.TraceID().String() |
|
} |
|
return "" |
|
} |
|
} |
|
|
|
// SpanID returns a spanid valuer. |
|
func SpanID() log.Valuer { |
|
return func(ctx context.Context) interface{} { |
|
if span := trace.SpanContextFromContext(ctx); span.HasSpanID() { |
|
return span.SpanID().String() |
|
} |
|
return "" |
|
} |
|
}
|
|
|