Add internal/tracing: env-gated OTel setup, span/log helpers, decorators
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
52
internal/tracing/reconciler.go
Normal file
52
internal/tracing/reconciler.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
)
|
||||
|
||||
// NewReconciler wraps inner so every reconcile runs in a root span named
|
||||
// "Reconcile <kind>" and every log line under it carries the trace context.
|
||||
// Reconciles are triggered by watch events with no incoming trace to
|
||||
// continue, so each one starts a new trace.
|
||||
func NewReconciler(kind string, inner reconcile.Reconciler, opts ...Option) reconcile.Reconciler {
|
||||
return &tracedReconciler{
|
||||
spanName: "Reconcile " + kind,
|
||||
inner: inner,
|
||||
tracer: newOptions(opts).tracer(),
|
||||
}
|
||||
}
|
||||
|
||||
type tracedReconciler struct {
|
||||
spanName string
|
||||
inner reconcile.Reconciler
|
||||
tracer trace.Tracer
|
||||
}
|
||||
|
||||
func (t *tracedReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
|
||||
ctx, span := StartSpan(ctx, t.tracer, t.spanName,
|
||||
trace.WithAttributes(
|
||||
attribute.String("k8s.namespace.name", req.Namespace),
|
||||
attribute.String("k8s.object.name", req.Name),
|
||||
))
|
||||
defer span.End()
|
||||
if id := controller.ReconcileIDFromContext(ctx); id != "" {
|
||||
span.SetAttributes(attribute.String("reconcile.id", string(id)))
|
||||
}
|
||||
|
||||
res, err := t.inner.Reconcile(ctx, req)
|
||||
if err != nil {
|
||||
span.SetStatus(codes.Error, err.Error())
|
||||
return res, err
|
||||
}
|
||||
span.SetStatus(codes.Ok, "")
|
||||
if res.RequeueAfter > 0 {
|
||||
span.SetAttributes(attribute.Int64("reconcile.requeue_after_ms", res.RequeueAfter.Milliseconds()))
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
Reference in New Issue
Block a user