使用 OpenTelemetry 在不同进程中运行链接跨度

问题描述 投票:0回答:1

我刚刚开始使用 OpenTelemetry,并为此创建了两个(微)服务:Standard 和 GeoMap。

最终用户向标准服务发送请求,标准服务又向 GeoMap 发送请求以获取信息,然后将结果返回给最终用户。我使用 gRPC 进行所有通信。

我已经这样设置了我的功能:

对于标准:

func (s *server) GetStandard(ctx context.Context, in *pb.GetStandardRequest) (*pb.GetStandardResponse, error) {

    newCtx, span := otel.Tracer(name).Start(ctx, "GetStandard")
    span.SpanContext()
    defer span.End()

    countryInfo, err := geoMapServiceClient.GetCountry(newCtx,
        &pb.GetCountryRequest{
            Name: in.Name,
        })

    ....
    
    return &pb.GetStandardResponse{
        Standard: standard,
    }, nil

}

对于地理地图

func (s *geomapService) GetCountry(ctx context.Context, in *pb.GetCountryRequest) (*pb.GetCountryResponse, error) {

    _, span := otel.Tracer(name).Start(ctx, "GetCountry")
    defer span.End()

    span.SetAttributes(attribute.String("country", in.Name))

    ...

    return &pb.GetCountryResponse{
        Country: &country,
    }, nil

}

这两个服务都配置为将其跟踪发送到 Jaeger 后端:

func tracerProvider(url string) (*tracesdk.TracerProvider, error) {
    // Create the Jaeger exporter
    exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
    if err != nil {
        return nil, err
    }
    tp := tracesdk.NewTracerProvider(
        tracesdk.WithBatcher(exp),
        tracesdk.WithResource(resource.NewWithAttributes(
            semconv.SchemaURL,
            semconv.ServiceName(service),
            attribute.String("environment", environment),
            attribute.Int64("ID", id),
        )),
    )
    return tp, nil
}

func main() {

    tp, err := tracerProvider("http://localhost:14268/api/traces")
    if err != nil {
        log.Fatal(err)
    }

    defer func() {
        if err := tp.Shutdown(context.Background()); err != nil {
            log.Fatal(err)
        }
    }()

    otel.SetTracerProvider(tp)
    
    ...
}

我希望 GeoMap 服务中生成的跨度是标准服务的子跨度(因为标准服务通过 geoMapServiceClient 发出请求)。然而这些跨度在 Jaeger 中是完全不相关的:

我在这里缺少什么?

编辑:

我已经成功地按照@Peter 在评论中建议的方式包含了拦截器。现在跨度相互链接,我可以看到来自 StandardService 的父跨度正在向 GeoMapService 发出请求:

但是,我在函数调用中定义了一个属性(请参阅

span.SetAttributes(attribute.String("country", in.Name))
),但我无法从子范围内看到该值。

为此,我必须切换到服务 GeoMap 生成的其他跟踪:

实际上我不需要有两个不同的跟踪,我希望所有内容都在同一个跟踪中(一个最终用户查询应该产生一个跟踪)。我应该如何从这里更改我的代码?

go open-telemetry
1个回答
0
投票

你的孩子跨度无法知道它的父母来自哪里。为此,您需要您的服务将正确的 HTTP 标头注入到您的 gRPC 请求中,并随后将其读回。

OpenTelemetry 提供了一个 propagators API,它允许您做到这一点。

虽然您可以在代码中手动执行此操作以注入/提取标头,但不建议这样做。 如果您将 otelgrpc 拦截器添加到您的应用程序中,该传播将自动完成,并且您的跨度将成为彼此的子级。

© www.soinside.com 2019 - 2024. All rights reserved.