Tracing

We use OpenTelemetry for distributed tracing.

Configuration

There are two methods for configuration WithTracerProvider() and WithPropagator().

WithTracerProvider

  1. func WithTracerProvider(provider trace.TracerProvider) Option {
  2. return func(opts *options) {
  3. opts.TracerProvider = provider
  4. }
  5. }

WithTracerProvider is for setting the provider, it accepts trace.TracerProvider

WithPropagator

  1. func WithPropagator(propagator propagation.TextMapPropagator) Option {
  2. return func(opts *options) {
  3. opts.Propagator = propagator
  4. }
  5. }

WithPropagator is for setting the text map propagator, it accepts propagation.TextMapPropagator

Usage

Tracing for Server

  1. package server
  2. import (
  3. "github.com/go-kratos/kratos/v2/middleware/tracing"
  4. "github.com/go-kratos/kratos/v2/transport/grpc"
  5. "go.opentelemetry.io/otel"
  6. "go.opentelemetry.io/otel/attribute"
  7. "go.opentelemetry.io/otel/exporters/jaeger"
  8. "go.opentelemetry.io/otel/sdk/resource"
  9. tracesdk "go.opentelemetry.io/otel/sdk/trace"
  10. semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
  11. )
  12. // Set global trace provider
  13. func initTracer(url string) error {
  14. // Create the Jaeger exporter
  15. exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
  16. if err != nil {
  17. return err
  18. }
  19. tp := tracesdk.NewTracerProvider(
  20. // Set the sampling rate based on the parent span to 100%
  21. tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))),
  22. // Always be sure to batch in production.
  23. tracesdk.WithBatcher(exp),
  24. // Record information about this application in an Resource.
  25. tracesdk.WithResource(resource.NewSchemaless(
  26. semconv.ServiceNameKey.String("kratos-trace"),
  27. attribute.String("exporter", "jaeger"),
  28. attribute.Float64("float", 312.23),
  29. )),
  30. )
  31. otel.SetTracerProvider(tp)
  32. return nil
  33. }
  34. // NewGRPCServer new a gRPC server.
  35. func NewGRPCServer(c *conf.Server, executor *service.ExecutorService) *grpc.Server {
  36. err := initTracer("http://localhost:14268/api/traces")
  37. if err != nil {
  38. panic(err)
  39. }
  40. //tr := otel.Tracer("component-main")
  41. var opts = []grpc.ServerOption{
  42. grpc.Middleware(
  43. tracing.Server(),
  44. ),
  45. }
  46. // ...
  47. }

Tracing for Client

  1. package client
  2. import (
  3. "context"
  4. "github.com/go-kratos/kratos/v2/middleware/tracing"
  5. "github.com/go-kratos/kratos/v2/transport/grpc"
  6. "go.opentelemetry.io/otel"
  7. "go.opentelemetry.io/otel/attribute"
  8. "go.opentelemetry.io/otel/exporters/jaeger"
  9. "go.opentelemetry.io/otel/sdk/resource"
  10. tracesdk "go.opentelemetry.io/otel/sdk/trace"
  11. semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
  12. googlegrpc "google.golang.org/grpc"
  13. )
  14. // Set global trace provider
  15. func initTracer(url string) error {
  16. // Create the Jaeger exporter
  17. exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
  18. if err != nil {
  19. return err
  20. }
  21. tp := tracesdk.NewTracerProvider(
  22. // Set the sampling rate based on the parent span to 100%
  23. tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))),
  24. // Always be sure to batch in production.
  25. tracesdk.WithBatcher(exp),
  26. // Record information about this application in an Resource.
  27. tracesdk.WithResource(resource.NewSchemaless(
  28. semconv.ServiceNameKey.String("kratos-trace"),
  29. attribute.String("exporter", "jaeger"),
  30. attribute.Float64("float", 312.23),
  31. )),
  32. )
  33. otel.SetTracerProvider(tp)
  34. return nil
  35. }
  36. func grpcCli() (*googlegrpc.ClientConn, error) {
  37. // If the project does not initialize initTracer, please initialize.
  38. return grpc.DialInsecure(
  39. context.Background(),
  40. grpc.WithMiddleware(
  41. tracing.Client(),
  42. ),
  43. )
  44. }

References