链路跟踪

Kitex 提供了对 OpenTelemetry 和 OpenTracing 的支持,也支持用户自定义链路跟踪。

背景

Kitex 支持流行的链路追踪标准 OpenTelemetry 和 OpenTracing,允许开发者选择合适的工具来适应他们的监控生态,用户可以轻松地在微服务架构中实现请求的全链路监控。这样的监控对于调试、性能分析以及故障排查是至关重要的。

OpenTelemetry

obs-opentelemetry 扩展集成了 OpenTelemetry 标准的 Tracing。

使用示例

Client

import (
    ...
    "github.com/kitex-contrib/obs-opentelemetry/provider"
    "github.com/kitex-contrib/obs-opentelemetry/tracing"
)

func main(){
    serviceName := "echo-client"

    p := provider.NewOpenTelemetryProvider(
        provider.WithServiceName(serviceName),
        provider.WithExportEndpoint("localhost:4317"),
        provider.WithInsecure(),
    )
    defer p.Shutdown(context.Background())

    c, err := echo.NewClient(
        "echo",
        client.WithSuite(tracing.NewClientSuite()),
        // Please keep the same as provider.WithServiceName
        client.WithClientBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: serviceName}),
    )
    if err != nil {
        klog.Fatal(err)
    }

}

Server

import (
    ...
    "github.com/kitex-contrib/obs-opentelemetry/provider"
    "github.com/kitex-contrib/obs-opentelemetry/tracing"
)


func main()  {
    serviceName := "echo"

    p := provider.NewOpenTelemetryProvider(
        provider.WithServiceName(serviceName),
        provider.WithExportEndpoint("localhost:4317"),
        provider.WithInsecure(),
    )
    defer p.Shutdown(context.Background())

    svr := echo.NewServer(
        new(EchoImpl),
        server.WithSuite(tracing.NewServerSuite()),
        // Please keep the same as provider.WithServiceName
        server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: serviceName}),
    )
    if err := svr.Run(); err != nil {
        klog.Fatalf("server stopped with error:", err)
    }
}

OpenTracing

tracer-opentracing 拓展集成了 OpenTracing 标准的链路追踪。

使用示例

Client

import (
	"github.com/cloudwego/kitex/client"
	"github.com/cloudwego/kitex-examples/kitex_gen/api/echo"
	internal_opentracing "github.com/kitex-contrib/tracer-opentracing"
)
...
tracer := internal_opentracing.NewDefaultClientSuite()
client, err := echo.NewClient("echo", client.WithSuite(tracer))
if err != nil {
	log.Fatal(err)
}

Server

import (
  "github.com/cloudwego/kitex/server"
  "github.com/cloudwego/kitex-examples/kitex_gen/api/echo"
  internal_opentracing "github.com/kitex-contrib/tracer-opentracing"
)
...
tracer := internal_opentracing.NewDefaultServerSuite()
svr, err := echo.NewServer(new(EchoImpl), server.WithSuite(tracer))
if err := svr.Run(); err != nil {
	log.Println("server stopped with error:", err)
} else {
	log.Println("server stopped")
}

自定义 Opentracing Tracer 和 Operation Name

通过 NewDefaultServerSuiteNewDefaultClientSuite 会创建出默认使用 OpenTracing GlobalTracer 的 Suite。若需自定义 Opentracing Tracer 和 Operation Name,可选择使用 NewServerSuiteNewClientSuite 方法创建 Suite。

以 Client 端为例(Server 端类似):

import (
	...
	"github.com/opentracing/opentracing-go"
	"github.com/cloudwego/kitex/pkg/endpoint"
	"github.com/cloudwego/kitex/pkg/rpcinfo"
  internal_opentracing "github.com/kitex-contrib/tracer-opentracing"
  ...
)
...
myTracer := opentracing.GlobalTracer()
operationNameFunc := func(ctx context.Context) string {
	endpoint := rpcinfo.GetRPCInfo(ctx).To()
	return endpoint.ServiceName() + "::" + endpoint.Method()
}
...
client, err := echo.NewClient("echo", client.WithSuite(internal_opentracing.NewClientSuite(myTracer, operationNameFunc)))
if err != nil {
	log.Fatal(err)
}

支持的组件

Redis

tracer-opentracing 提供了 Redis Hook,可以快速集成 Redis 链路追踪。使用方式如下:

import (
    ...
    "github.com/go-redis/redis/v8"
    internal_opentracing "github.com/kitex-contrib/tracer-opentracing"
    ...
)

func main() {
    ...
    rdb := redis.NewClient(&redis.Options{...})
  	// add the hook provided by tracer-opentracing to instrument Redis client
    rdb.AddHook(internal_opentracing.NewTracingHook())
    ...
}

自定义 Tracer

框架提供了 Tracer 接口,可以实现该接口来自定义 Tracer :

type Tracer interface {
	Start(ctx context.Context) context.Context
	Finish(ctx context.Context)
}

详细文档请阅读 监控拓展 章节。

自定义跟踪事件

Kitex 提供了一些默认的跟踪事件,例如 RPC 调用开始、RPC 调用结束等,有关内置的跟踪事件请参考 埋点 章节。除此之外,也可以手动添加更多的追踪数据,以收集更详细的链路信息。跟踪事件通过创建和结束 span 来记录,可以使用对应组件的原生 API 来完成。

以 OpenTelemetry 为例,可以这样使用:

ctx, span := otel.Tracer("client").Start(ctx, "root")
defer span.End()

更多内容请参考:OpenTelemetry Creating SpansOpenTracing Golang API