如何在 OpenTelemetry otelgin 中间件中获取 traceid 或完整上下文以将其提供给 grpc 客户端?

How to get in OpenTelemetry otelgin middleware the traceid or full context to provide it to grpc clients?

Atm,我在 go 中处理了一堆我想跟踪的分布式微服务。我有一个通过 REST 工作的“api-gateway”,然后通过 gRPC 调用所需的微服务。

我通过 OpenTelemetry 进行的跟踪适用于 grpc 路径,但是 otelgin 中间件似乎没有提供任何上下文,我可以进一步使用 grpc 服务中的相同 traceid 进行跟踪。

我默认使用 gin,然后像这样注入 otelgin 中间件。

r := gin.Default()
r.Use(middleware.Middleware(
    "Service-Name-XYZ",
))

就我查看中间件代码而言,应该有一个可跟踪的上下文,我可以将其提供给 grpc 客户端以将其跨度添加到跟踪中,但不知何故 traceparenttracestate 似乎完全错过了 gin context,因此 grpc 客户端无法采取 opentelemetry 上下文传播的操作。

据我所知,中间件使用默认设置 TracerProvider 和我在 InitTracer 函数中设置的 TextMapPropagator,后者在 main.go 中调用。

func InitTracer() func(context.Context) error {

headers := map[string]string{
    "signoz-access-token": signozToken,
}

secureOption := otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, ""))
if len(insecure) > 0 {
    secureOption = otlptracegrpc.WithInsecure()
}

exporter, err := otlptrace.New(
    context.Background(),
    otlptracegrpc.NewClient(
        secureOption,
        otlptracegrpc.WithEndpoint(collectorURL),
        otlptracegrpc.WithHeaders(headers),
    ),
)

if err != nil {
    log.Fatal(err)
}
resources, err := resource.New(
    context.Background(),
    resource.WithAttributes(
        attribute.String("service.name", serviceName),
        attribute.String("library.language", "go"),
    ),
)
if err != nil {
    log.Printf("Could not set resources: ", err)
}

otel.SetTracerProvider(
    sdktrace.NewTracerProvider(
        sdktrace.WithSampler(sdktrace.AlwaysSample()),
        sdktrace.WithSpanProcessor(sdktrace.NewBatchSpanProcessor(exporter)),
        sdktrace.WithSyncer(exporter),
        sdktrace.WithResource(resources),
    ),
)

otel.SetTextMapPropagator(
    propagation.NewCompositeTextMapPropagator(
        propagation.TraceContext{},
        propagation.Baggage{},
    ),
)
return exporter.Shutdown
}

所以我的问题是:

我是否遗漏了什么或者 otelgin 没有提供任何我可以提供给 grpc 客户端使用的可追踪上下文?

如果您使用 otelgin middleware,可跟踪上下文将通过 ginContext.Request.Context() 传播。因此,您可以将此请求上下文而不是 ginContext 传递给您的 gRPC 客户端以传播跟踪。