Skip to content

Gin Context implementation breaks context.Context contract #3888

@dlinkov-roblox

Description

@dlinkov-roblox

Description

As also described in this issue, open-telemetry/opentelemetry-go-contrib#5277, the existing OpenTelemetry packages do not interact very well with gin.Context. It was pointed out here that this is an example of gin.Context not fulfilling the following specification of context.Context.WithValue: The provided key must be comparable and should not be of type string or any other built-in type to avoid collisions between packages using context. Users of WithValue should define their own types for keys.

The two pieces of code that are having colliding values in the context are here for OpenTelemetry, and here for Gin.

How to reproduce

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
	oteltrace "go.opentelemetry.io/otel/sdk/trace"
	"go.opentelemetry.io/otel/trace"
)

func main() {
	sampler := oteltrace.AlwaysSample()
	exporter, _ := stdouttrace.New(stdouttrace.WithPrettyPrint())

	tp := oteltrace.NewTracerProvider(
		oteltrace.WithBatcher(exporter),
		oteltrace.WithSampler(sampler),
	)
	otel.SetTracerProvider(tp)
	r := gin.New()
	r.GET("/health_check", otelgin.Middleware("example-service"), HealthCheckHandler)
	r.Run(":9000")
}

func HealthCheckHandler(c *gin.Context) {
	span := trace.SpanFromContext(c)
	c.JSON(http.StatusOK, gin.H{"span_id": span.SpanContext().SpanID()})
}

Expectations

$ curl http://localhost:9000/health_check
<A span ID that is not all zeros>

Actual result

$ curl -i http://localhost:9000/hello/world
<A span ID that is all zeros>

Note that this is an issue as the span context will not be propagated properly unless a user passes c.Request.Context() explicitly. Since a gin.Context implements the context.Context interface, this is a subtle bug that would not be caught by the type system.

Environment

  • go version: 1.19
  • gin version (or commit ref): 1.9.1
  • operating system: Mac OS Sonoma

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions