Using lib-observability/tracing for OTEL provider lifecycle, trace-context propagation across HTTP/gRPC/queues, span error/event recording, and PII redaction, in two modes. Sweep Mode detects raw OTEL setup, hand-rolled header propagation, manual span-attribute assembly, and DIY redaction. Reference Mode catalogs Telemetry, Redactor, and propagation/span helpers. Go-only. Skip for non-Go or frontend code.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Using lib-observability/tracing for OTEL provider lifecycle, trace-context propagation across HTTP/gRPC/queues, span error/event recording, and PII redaction, in two modes. Sweep Mode detects raw OTEL setup, hand-rolled header propagation, manual span-attribute assembly, and DIY redaction. Reference Mode catalogs Telemetry, Redactor, and propagation/span helpers. Go-only. Skip for non-Go or frontend code.
The tracing subpackage owns OTEL provider lifecycle, trace context propagation, span helpers,
and the attribute-redaction pipeline (RedactingAttrBagSpanProcessor is wired automatically
inside NewTelemetry). Use this skill when tracing is the primary concern. For broader
lib-observability sweeps (logging, metrics, panic recovery), invoke ring:using-lib-observability.
Before emitting any Task call, count the explorers you intend to launch in this turn.
Count MUST equal 6.
If count < 6 → STOP. Do not partial-dispatch. Reconcile against the 6 angles below and try again.
The 6 angles are the canonical sweep. No substitutions, no omissions.
⛔ MUST NOT trickle-dispatch
All 6 explorers leave in the SAME TURN, before reading any explorer output.
Forbidden sequences:
Dispatch explorer 1 → read result → dispatch explorer 2
Dispatch a subset → wait → dispatch the rest
Dispatch follow-up explorers conditioned on partial output
Loop sequentially over the angle list
If you find yourself about to dispatch an explorer in a turn AFTER any explorer has already returned a result → STOP. You violated parallel dispatch. Report the violation and mark the phase INCOMPLETE rather than completing the trickle.
Self-verify after dispatch
After the dispatch turn, verify all 6 Task calls were emitted in that single turn. If fewer than 6 went out, the phase did NOT execute correctly. Mark INCOMPLETE and surface the dispatch failure — do NOT silently continue with a partial pool.
Parallel dispatch — atomic batch
Emit all 6 Task calls in a SINGLE TURN, as one atomic batch.
If your runtime exposes a multi_tool_use.parallel wrapper, use it to dispatch the complete pool in one wrapped invocation. This is the canonical fan-out mechanism on OpenAI-style tool envelopes and on certain Anthropic SDK consumers — naming it explicitly activates parallel emission on runtimes where trickle-dispatch is the default behavior.
If your runtime emits parallel tool_use blocks natively (Claude Code with Claude models), multi_tool_use.parallel may not be needed — but naming it is harmless and serves as an enforcement anchor.
The STOP-CHECK, anti-trickle, and self-verify guards above remain binding regardless of which mechanism your runtime uses.
Dispatch all 6 explorer angles in one parallel batch. Wait for all before Phase 4.
tracing.NewDefaultRedactor() (or NewRedactor(rules, mask)) plumbed through TelemetryConfig.Redactor
6
Untraced HTTP/DB/Kafka boundaries
HIGH
Outbound HTTP clients, DB drivers, or queue publishers with no span around the call; missing HandleSpanError/HandleSpanBusinessErrorEvent on the error path
Wrap call with tracer.Start(ctx, "op") + defer span.End(); record errors via tracing.HandleSpanError(span, msg, err)
Severity calibration
CRITICAL: hides production failures or leaks PII (angles 1, 5)
Read /tmp/tracing-version-report.json, /tmp/tracing-delta-report.json,
and /tmp/tracing-sweep-*.json (6 files).
Emit:
1. /tmp/tracing-sweep-report.md — findings grouped by severity, cross-referenced to angle table
2. /tmp/tracing-sweep-tasks.json — one task per DIY pattern cluster (same file/package = one task)
MUST NOT invent findings. MUST NOT omit explorer findings. MUST NOT reclassify severity without justification.
Phase 5: Handoff
Surface report path + task count to the caller. Offer handoff to ring:running-dev-cycle for execution.
EnableTelemetry=true with empty CollectorExporterEndpoint; noop providers are installed but the call still returns this error so callers can decide whether to abort
ErrNilTelemetry
method called on nil *Telemetry
ErrNilShutdown
shutdown invoked but no shutdown function configured (corrupted state)
ErrNilProvider
ApplyGlobals called when TracerProvider/MeterProvider/Propagator is nil
Endpoint and security rules
http://host:4317 → scheme stripped, InsecureExporter forced to true
host:4317 (no scheme) → treated as insecure (common in cluster-internal traffic)
InsecureExporter=true in production/prod env aborts with an error unless ALLOW_INSECURE_OTEL is set with a justification — do not bypass this lightly
Disabled / empty-endpoint fallback
When EnableTelemetry=false or the endpoint is empty, NewTelemetry installs no-op providers and ApplyGlobals ensures downstream libraries (e.g. otelfiber) do not spawn real gRPC exporters that leak goroutines. Code paths above the API stay unchanged.
2. Propagation Helpers
All helpers are nil-safe and use the globally configured TextMapPropagator.
The gRPC helpers normalize Traceparent/Tracestate header casing — gRPC metadata is lowercase by spec, but some interceptors emit Pascal case. The helpers translate both ways. Do not reinvent this.
traceID := tracing.GetTraceIDFromContext(ctx) // "" if no valid span
state := tracing.GetTraceStateFromContext(ctx)
Use these for log correlation. Never parse traceparent headers by hand to recover the trace ID.
3. Span Helpers
funcHandleSpanError(span trace.Span, message string, err error)funcHandleSpanBusinessErrorEvent(span trace.Span, eventName string, err error)funcHandleSpanEvent(span trace.Span, eventName string, attributes ...attribute.KeyValue)funcSetSpanAttributesFromValue(span trace.Span, prefix string, value any, r *Redactor)errorfuncBuildAttributesFromValue(prefix string, value any, r *Redactor) ([]attribute.KeyValue, error)
funcSetSpanAttributeForParam(c *fiber.Ctx, param, value, entityName string)
All helpers are nil-safe on the span argument (untyped nil and interface-wrapped typed nil both handled). Error messages are sanitized: bearer/basic tokens stripped and the message is truncated to 1024 bytes with valid-UTF-8 enforcement.
Helper
Use when
HandleSpanError
Operation failed; mark span as failed (codes.Error) and record the error
HandleSpanBusinessErrorEvent
Domain rule rejected the request but the operation itself succeeded technically (e.g. balance insufficient) — adds an event without flipping the span to error
HandleSpanEvent
Generic milestone event with attributes (e.g. cache.hit, retry.attempt)
SetSpanAttributesFromValue
Flatten a struct/map into span attributes with redaction applied; bounded by 128 attributes and depth 32
BuildAttributesFromValue
Same flattening but returns the attribute slice instead of writing to a span
SetSpanAttributeForParam
Fiber-specific: attach a request parameter to the context-scoped attribute bag, masking sensitive names
type RedactionAction string// "mask" | "hash" | "drop"type RedactionRule struct {
FieldPattern string// regex matched against field name
PathPattern string// regex matched against dotted path
Action RedactionAction
}
type Redactor struct{ /* unexported */ }
funcNewDefaultRedactor() *Redactor // default sensitive-field list, action = maskfuncNewAlwaysMaskRedactor() *Redactor // fail-safe; masks every fieldfuncNewRedactor(rules []RedactionRule, mask string) (*Redactor, error)
funcObfuscateStruct(value any, r *Redactor) (any, error)
Pipeline
NewTelemetry defaults cfg.Redactor to NewDefaultRedactor() if nil
The tracer provider is built with RedactingAttrBagSpanProcessor{Redactor: cfg.Redactor} — every span gets request-scoped attributes from observability.AttributesFromContext filtered through redaction
SetSpanAttributesFromValue invokes ObfuscateStruct before flattening, so struct-derived attributes inherit the same rules
mask replaces the value with the configured mask string
hash produces sha256:<hex> using a per-instance HMAC key (so identical inputs in different processes produce different hashes — anti-rainbow-table)
drop removes the field entirely
RedactingAttrBagSpanProcessor
Custom sdktrace.SpanProcessor wired automatically inside NewTelemetry. It copies observability.AttributesFromContext(ctx) onto every started span and applies redaction by attribute key. Do not register it manually unless you are bypassing NewTelemetry.
5. Common Anti-Patterns
Anti-pattern
Fix
Calling otel.SetTracerProvider directly during init
Use tl.ApplyGlobals() — it also wires the meter, logger provider, and propagator atomically
Building a propagation.TraceContext{} propagator per-call
Configure once on TelemetryConfig.Propagator; helpers read otel.GetTextMapPropagator()
Logging traceparent headers verbatim
Use GetTraceIDFromContext(ctx) and log the trace ID, not the header
Shutting down providers with tp.Shutdown(ctx) directly
Use ShutdownTelemetryWithContext — it shuts down exporters and providers in the right order and joins errors
Adding a custom SpanProcessor for redaction
RedactingAttrBagSpanProcessor already runs; add rules to the Redactor instead
Setting InsecureExporter=true in production
Either fix the collector to expose TLS, or set ALLOW_INSECURE_OTEL="<justification>" with a sunset date — never silently bypass