We use OpenTelemetry for distributed tracing.
There are two methods for configuration WithTracerProvider()
and WithPropagator()
.
WithTracerProvider
func WithTracerProvider(provider trace.TracerProvider) Option { return func(opts *options) { opts.TracerProvider = provider }}
WithTracerProvider
is for setting the provider, it accepts trace.TracerProvider
WithPropagator
func WithPropagator(propagator propagation.TextMapPropagator) Option { return func(opts *options) { opts.Propagator = propagator }}
WithPropagator
is for setting the text map propagator, it accepts propagation.TextMapPropagator
package server
import ( "github.com/go-kratos/kratos/v2/middleware/tracing" "github.com/go-kratos/kratos/v2/transport/grpc"
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/jaeger" "go.opentelemetry.io/otel/sdk/resource" tracesdk "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0")
// Set global trace providerfunc initTracer(url string) error { // Create the Jaeger exporter exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))) if err != nil { return err } tp := tracesdk.NewTracerProvider( // Set the sampling rate based on the parent span to 100% tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))), // Always be sure to batch in production. tracesdk.WithBatcher(exp), // Record information about this application in an Resource. tracesdk.WithResource(resource.NewSchemaless( semconv.ServiceNameKey.String("kratos-trace"), attribute.String("exporter", "jaeger"), attribute.Float64("float", 312.23), )), ) otel.SetTracerProvider(tp) return nil}
// NewGRPCServer new a gRPC server.func NewGRPCServer(c *conf.Server, executor *service.ExecutorService) *grpc.Server { err := initTracer("http://localhost:14268/api/traces") if err != nil { panic(err) } //tr := otel.Tracer("component-main") var opts = []grpc.ServerOption{ grpc.Middleware( tracing.Server(), ), } // ...}
package client
import ( "context"
"github.com/go-kratos/kratos/v2/middleware/tracing" "github.com/go-kratos/kratos/v2/transport/grpc"
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/jaeger" "go.opentelemetry.io/otel/sdk/resource" tracesdk "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" googlegrpc "google.golang.org/grpc")
// Set global trace providerfunc initTracer(url string) error { // Create the Jaeger exporter exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))) if err != nil { return err } tp := tracesdk.NewTracerProvider( // Set the sampling rate based on the parent span to 100% tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))), // Always be sure to batch in production. tracesdk.WithBatcher(exp), // Record information about this application in an Resource. tracesdk.WithResource(resource.NewSchemaless( semconv.ServiceNameKey.String("kratos-trace"), attribute.String("exporter", "jaeger"), attribute.Float64("float", 312.23), )), ) otel.SetTracerProvider(tp) return nil}
func grpcCli() (*googlegrpc.ClientConn, error) { // If the project does not initialize initTracer, please initialize. return grpc.DialInsecure( context.Background(), grpc.WithMiddleware( tracing.Client(), ), )}
If you don’t want to modify the code manually, you can also use Agent for automatic collection of OpenTelemetry data, such as Alibaba Go Auto Instrumentation (which will later be officially donated to OpenTelemetry Official Repository).
You can refer to the documentation to compile your Kratos application.