Closed pepea23 closed 1 week ago
cc @hanyuancheung
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?
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
}
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
thank you :)
when implementing use otel tracing like this 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 trace_id and span_id is empty
GetTraceIds function image
Environment go version: 1.22.4 gin version (or commit ref): github.com/gin-gonic/gin v1.10.0