Is there a way to retrieve the "root" span of a Go context? #3457
-
Assume we are writing an HTTP backend in Go, and a middleware creates a span for us. There is no parent span created in our process (although there might be a remote parent span defined). I will call this span at the HTTP-level the "process root" span. Then, a few functions deep, we have code where we want to add an attribute to this "process root" span. Just using Is there any way to do this using the existing API? Is there a reason that I would not want to do this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
No, there is no way to achieve this with the current API. |
Beta Was this translation helpful? Give feedback.
-
We do something like this. Here's some example code that might be helpful: // A unique key to store the main OpenTelemetry span for per request
type mainSpanContextKey struct{}
func HTTPMiddleware(handler http.Handler) http.Handler {
handle := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Retrieve the span created by otelhttp.Handler
span := trace.SpanFromContext(ctx)
span.SetAttributes(
attribute.Bool("main", true),
)
// store the span as an object on the request context using a private key
ctx = context.WithValue(ctx, mainSpanContextKey{}, span)
r = r.WithContext(ctx)
handler.ServeHTTP(w, r)
})
options := []otelhttp.Option{
//...
}
return otelhttp.NewHandler(handle, "http", options...)
}
func MainSpanFromContext(ctx context.Context) trace.Span {
span, ok := ctx.Value(mainSpanContextKey{}).(trace.Span)
if !ok {
_, span = trace.NewNoopTracerProvider().Tracer("noop").Start(ctx, "noop")
}
return span
} A similar convention exists in some OpenTelemetry Ruby instrumentations, though this does not seem to be consistent |
Beta Was this translation helpful? Give feedback.
No, there is no way to achieve this with the current API.
However, there is nothing preventing you from setting up your own HTTP handler running on top of the otel one which will store the HTTP span as a "main" one in the context and allow you to retrieve it afterwards.