Skip to content

Tracing

We use OpenTelemetry for distributed tracing.

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

func WithTracerProvider(provider trace.TracerProvider) Option {
return func(opts *options) {
opts.TracerProvider = provider
}
}

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

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 provider
func 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 provider
func 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.