I'm trying to figure out the proper way to propagate a context.Context
for the purposes of tracing with OpenTelemetry when using Gin.
I currently have a gin
handler that calls a function and passes a *gin.Context
, like so:
func (m Handler) doSomething(ginCtx *gin.Context, name string) {
ctx, span := otel.Tracer("mytracer").Start(ginCtx.Request.Context(), "doSomething")
defer span.End()
// ...
}
This actually results in incorrect spans, since before doSomething()
is called, I create a new context.Context
in the calling function with the parent span information (similar to the snippet above).
In most of my code, I'm passing around a context.Context
, but figured I could make use of gin's Context
. Otherwise I have to pass both types of contexts:
func (m Handler) doSomething(ctx context.Context, ginCtx *gin.Context, name string) {
ctx, span := otel.Tracer("mytracer").Start(ctx, "doSomething")
defer span.End()
// ...
}
This feels wrong since the Request
stored in the *gin.Context
is out of sync with what I'm passing around as a parameter via context.Context
. However, I'm afraid to set the Request
on the *gin.Context
with a new Request
that has the updated Context
because
- It's only for this function and I'd have to un-set it (maybe through a
defer()
?) - It doesn't seem like it'd be thread-safe (though I assume I'd need to
Copy()
the gin Context in this scenario anyway)
Is the proper way to handle this just Copy
ing the *gin.Context
and modifying the Request with the new context.Context
, then passing the *gin.Context
around instead of context.Context
?
I don't know what the implications are of Copy
ing a gin.Context
from the text:
Copy returns a copy of the current context that can be safely used outside the request's scope. This has to be used when the context has to be passed to a goroutine.
Can I still Abort()
through a copied *gin.Context
, and is the old one still usable after copying? I just need something that behaves like a stack in the same way that passing context.Context
s around does, where simply returning from the function "pops" the context off and I'm left with the old one.