链路追踪

Tracing 中间件使用 OpenTelemetry 实现了链路追踪。

配置

有两种方法可用于使用WithTracerProvider() and WithPropagator()进行配置。

WithTracerProvider

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

WithTracerProvider 用于设置 provider,它接收的参数为 trace.TracerProvider

WithPropagator

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

WithPropagator 用于设置 text map propagator,它接收的参数为 propagation.TextMapPropagator

使用方法

server 中使用 tracing 采集数据

  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. // 设置全局trace
  13. func initTracer(url string) error {
  14. // 创建 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. // 将基于父span的采样率设置为100%
  21. tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))),
  22. // 始终确保在生产中批量处理
  23. tracesdk.WithBatcher(exp),
  24. // 在资源中记录有关此应用程序的信息
  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. }

client 中使用 tracing 采集数据

  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. // 设置全局trace
  15. func initTracer(url string) error {
  16. // 创建 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. // 将基于父span的采样率设置为100%
  23. tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))),
  24. // 始终确保再生成中批量处理
  25. tracesdk.WithBatcher(exp),
  26. // 在资源中记录有关此应用程序的信息
  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. // 如果本项目没有初始化initTracer 请初始化
  38. return grpc.DialInsecure(
  39. context.Background(),
  40. grpc.WithMiddleware(
  41. tracing.Client(),
  42. ),
  43. )
  44. }

References