Add internal/tracing: env-gated OTel setup, span/log helpers, decorators
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
51
internal/tracing/transport.go
Normal file
51
internal/tracing/transport.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"k8s.io/client-go/transport"
|
||||
)
|
||||
|
||||
// RestConfigWrapper returns a rest.Config.Wrap-compatible wrapper that adds
|
||||
// a client span to every Kubernetes API request already running inside a
|
||||
// trace. Requests with no parent span pass through untouched: informer
|
||||
// list/watch long-polls, leader-election renewals, and metrics authn would
|
||||
// otherwise each become meaningless (and in the watch case, minutes-long)
|
||||
// root spans. client-go applies Wrap innermost, so the span sees the final
|
||||
// authenticated request.
|
||||
func RestConfigWrapper(opts ...Option) transport.WrapperFunc {
|
||||
o := newOptions(opts)
|
||||
return func(rt http.RoundTripper) http.RoundTripper {
|
||||
otelOpts := []otelhttp.Option{
|
||||
// Explicit propagators: deterministic regardless of global
|
||||
// state. The apiserver ignores incoming traceparent (by
|
||||
// design), so injection is harmless there.
|
||||
otelhttp.WithPropagators(propagation.NewCompositeTextMapPropagator(
|
||||
propagation.TraceContext{}, propagation.Baggage{})),
|
||||
}
|
||||
if o.tp != nil {
|
||||
otelOpts = append(otelOpts, otelhttp.WithTracerProvider(o.tp))
|
||||
}
|
||||
return &parentGatedTransport{
|
||||
traced: otelhttp.NewTransport(rt, otelOpts...),
|
||||
plain: rt,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parentGatedTransport enforces the parent-span requirement itself rather
|
||||
// than relying on otelhttp filter semantics for transports.
|
||||
type parentGatedTransport struct {
|
||||
traced http.RoundTripper
|
||||
plain http.RoundTripper
|
||||
}
|
||||
|
||||
func (t *parentGatedTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
if trace.SpanContextFromContext(r.Context()).IsValid() {
|
||||
return t.traced.RoundTrip(r)
|
||||
}
|
||||
return t.plain.RoundTrip(r)
|
||||
}
|
||||
Reference in New Issue
Block a user