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

Atm, I work on a bunch of distributed microservices in go which I want to trace. I have an "api-gateway" that works via REST and then calls the needed microservice via gRPC.

My tracing via OpenTelemetry works fine for the grpc path but somehow the otelgin middleware seems not to provide any context I could use further to trace with the same traceid in the grpc services.

I use gin default and then inject the otelgin middleware like this.

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

As far as I took a look at the middleware code there should be somehow a tracable context that I can give to the grpc client to add his span to the trace but somehow the traceparent and the tracestate seems to completely miss in the gin context so that the grpc client cant take action of opentelemetry context propagation.

As far as I see the middleware uses the default set TracerProvider and the TextMapPropagator which I set in my InitTracer function which gets called in the 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
}

So my question is:

Do I miss something or does otelgin not provide any tracable context that I can give to the grpc client to work with?



Solution 1:[1]

If you are using otelgin middleware, the traceable context is propagated through ginContext.Request.Context(). So you can pass on this request context instead of ginContext to your gRPC client to propagate trace.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bharat Gadde