We use OpenTelemetry for distributed tracing.
There are two methods for configuration WithTracerProvider() and WithPropagator().
WithTracerProviderfunc WithTracerProvider(provider trace.TracerProvider) Option { return func(opts *options) { opts.TracerProvider = provider }}WithTracerProvider is for setting the provider, it accepts trace.TracerProvider
WithPropagatorfunc 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.