open-telemetry / opentelemetry-go-contrib

Collection of extensions for OpenTelemetry-Go.
https://opentelemetry.io/
Apache License 2.0
1.07k stars 505 forks source link

gin context with tracing not work #5765

Closed pepea23 closed 1 week ago

pepea23 commented 2 weeks ago

when implementing use otel tracing like this image image

and apply to router like "router.POST("/v4/*xxxx", gatewayPostHandler, WithTracer())"

then tried to get a trace I found that gin context does not save trace_id and span_id it empty so how to reproduce the problem?

handler function image image trace_id and span_id is empty

GetTraceIds function image image

Environment go version: 1.22.4 gin version (or commit ref): github.com/gin-gonic/gin v1.10.0

dmathieu commented 2 weeks ago

cc @hanyuancheung

dmathieu commented 2 weeks ago

Did you setup otelgin, as documented in this example? https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/instrumentation/github.com/gin-gonic/gin/otelgin/example/server.go#L36

Could you provide us with a small app reproducing the issue?

pepea23 commented 1 week ago

Did you setup otelgin, as documented in this example? https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/instrumentation/github.com/gin-gonic/gin/otelgin/example/server.go#L36

Could you provide us with a small app reproducing the issue?

here is my example reproducing

package main

import (
    "context"
    "log"
    "net/http"
    "strings"

    "github.com/gin-gonic/gin"
    "go.opentelemetry.io/contrib/exporters/autoexport"
    "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
    "go.opentelemetry.io/otel"
    "go.opentelemetry.io/otel/propagation"
    sdktrace "go.opentelemetry.io/otel/sdk/trace"
    "go.opentelemetry.io/otel/trace"
)

var healthcheckPaths = []string{"/healthz", "/healthcheck/liveness", "/v4/healthcheck/liveness"}

func isHealth(c *http.Request) bool {
    for _, healthcheckPath := range healthcheckPaths {
        if strings.HasPrefix(c.URL.Path, healthcheckPath) {
            return false
        }
    }
    return true
}

func init() {
}

func main() {
    cleanup := initTracer()
    defer cleanup(context.Background())
    routers := gin.New()
    InitRouter(routers)

    routers.Use(otelgin.Middleware("gateway-web", otelgin.WithFilter(isHealth)))

    err := routers.Run(":8080")
    if err != nil {
        log.Fatal(err.Error())
    }
}

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

    exporter, err := autoexport.NewSpanExporter(
        context.Background(),
    )
    if err != nil {
        log.Print(err.Error())
    }

    otel.SetTracerProvider(

        sdktrace.NewTracerProvider(
            sdktrace.WithSampler(sdktrace.AlwaysSample()),
            sdktrace.WithBatcher(exporter),
        ),
    )

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

func InitRouter(router *gin.Engine) {
    router.GET("/hello", func(ctx *gin.Context) {
        traceId, spanId := GetTraceIds(ctx)
        log.Print("traceId : ", traceId)
        log.Print("spanId : ", spanId)
        ctx.JSON(200, "hello")
    })
}

func GetTraceIds(ctx *gin.Context) (traceId string, spanId string) {
    spanContext := trace.SpanFromContext(ctx.Request.Context()).SpanContext()
    if spanContext.IsValid() {
        traceId = spanContext.TraceID().String()
        spanId = spanContext.SpanID().String()
    }
    return traceId, spanId
}
dmathieu commented 1 week ago
InitRouter(routers)
routers.Use(otelgin.Middleware("gateway-web", otelgin.WithFilter(isHealth)))

You need to inverse those two. If you define middlewares after your routes, gin executes them after routes (or not at all it seems).

routers.Use(otelgin.Middleware("gateway-web", otelgin.WithFilter(isHealth)))
InitRouter(routers)

Note that this is what our example does. https://github.com/open-telemetry/opentelemetry-go-contrib/blob/2dc32c101833e4d556ceb2ea1ece3712dce7a728/instrumentation/github.com/gin-gonic/gin/otelgin/example/server.go#L35-L36

pepea23 commented 1 week ago

thank you :)