distributed-tracing
Distributed tracing with OpenTelemetry — spans, context propagation, sampling. Use when instrumenting a distributed system, debugging requests that span services, setting up OpenTelemetry, choosing a sampling strategy, or understanding latency across service boundaries.
- License 许可
- MIT
- 最近更新
- 2026-11-11
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- distributed-tracing
- metadata
- { "processkit": { "id": "SKILL-distributed-tracing", "created": 1775433600000, "version": "1.1.0", "category": "devops", "apiVersion": "processkit.projectious.work/v1" } }
- description
- Distributed tracing with OpenTelemetry — spans, context propagation, sampling. Use when instrumenting a distributed system, debugging requests that span services, setting up OpenTelemetry, choosing a sampling strategy, or understanding latency across service boundaries.
03 SKILL.md 正文
Distributed Tracing
Intro
Distributed tracing follows a single request through every service it touches, exposing latency and error contributions per hop. OpenTelemetry is the vendor-neutral standard. Start with auto-instrumentation, propagate W3C Trace Context, and sample to control cost.
Overview
Core concepts
A trace is the entire journey of a request, identified by a 128-bit
trace_id. A span is one unit of work inside a trace with a name,
start time, duration, status, and attributes; spans form a tree where
every non-root span has a parent. Context carries trace_id,
span_id, and trace_flags across process boundaries via HTTP
headers, message metadata, or gRPC metadata. Baggage is small
key-value data propagated alongside context for cross-cutting concerns
like tenant ID — keep it tiny because every outgoing request carries it.
OpenTelemetry architecture
OpenTelemetry (OTel) is the standard. The API is the vendor-neutral interface your code instruments against. The SDK is the in-process library that creates and exports spans. Exporters ship spans to backends (Jaeger, Zipkin, Tempo, Datadog). The Collector is an optional proxy that decouples apps from backends and is recommended for production. Auto-instrumentation libraries create spans for common HTTP, gRPC, database, and messaging frameworks with zero code changes.
Instrumentation strategy
- Start with auto-instrumentation — it covers infrastructure for free
- Add manual spans for business operations (process order, validate payment, generate report)
- Use
<component>.<operation>span names:OrderService.createOrder - Add attributes for debugging context — HTTP method/url/status, DB
system/statement/operation, and business fields like
order.id - Record errors by setting span status to ERROR and attaching the exception as a span event
- Keep spans focused on one logical operation; break compound work into child spans
Context propagation
Context propagation is what stitches spans across service boundaries.
Use W3C Trace Context (the OTel default) with traceparent and
tracestate headers — example:
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01.
B3 propagation (Zipkin's X-B3-* headers) is still supported. For
message queues, propagate context in message headers or metadata, not
in the body. For async work, pass context explicitly when spawning
background tasks — it does not flow automatically across thread or
goroutine boundaries in most languages.
Sampling
In high-traffic systems, tracing every request is expensive. Pick a strategy:
- Head-based probabilistic — sample X% at trace root. Simple, can miss rare errors. Good starting point at 10-20%.
- Head-based rate-limiting — sample N traces per second. Prevents overload but biases toward high-traffic endpoints.
- Tail-based (requires the Collector) — decide after the trace completes. Always keep traces with errors or above a latency threshold; sample a small percentage of successes.
- Always-on (100%) — only for low-traffic or critical paths.
Recommended path: head-based probabilistic in apps, tail-based error/latency policies in the Collector as traffic grows.
Gotchas
Agent-specific failure modes — provider-neutral pause-and-self-check items:
- Missing context propagation at async boundaries. Trace context does not flow automatically through message queues, goroutines, thread pools, or task schedulers. If a service publishes a message without embedding the
traceparentheader, the consumer starts a new disconnected trace — the cross-service journey is invisible. Always pass context explicitly when crossing async boundaries, and inject it into message headers or job metadata. - Over-instrumentation — a span per function call. Adding a span to every helper function generates enormous trace data, makes waterfalls unreadable, and increases cost with no debugging value. Spans should represent meaningful operations: an HTTP call, a database query, a cache lookup, a business action. Instrument at operation boundaries, not code boundaries.
- Sensitive data in span attributes. Span attributes are stored in the tracing backend and may be visible to anyone with access to traces. Embedding PII (email addresses, user IDs mapped to identities), credentials, or full SQL query parameters in attributes creates a data exposure risk. Log only safe structural identifiers — numeric IDs, status codes, operation names.
- 100% sampling in production without a plan. Emitting a span for every request in a service handling thousands of RPS will rapidly overwhelm the tracing backend and budget. Set a sampling rate before going to production — head-based probabilistic at 10-20% is a reasonable starting point; add tail-based error/latency retention in the Collector as traffic grows.
- Treating trace_id and request_id as interchangeable. A
trace_idis created by the tracing SDK and follows the OpenTelemetry propagation standard. Arequest_idis typically generated at the API boundary for customer-facing correlation. They serve different purposes:trace_idlinks to the tracing backend;request_idappears in API responses and error messages. Propagate both and includetrace_idin log lines so you can pivot from logs to traces. - Ignoring the gaps between spans. A gap between a parent span's start and its first child's start often represents scheduler delay, queue wait time, or serialization overhead — not actual work. Reading only span durations and missing gaps will misattribute latency. Look at the full waterfall including gaps when diagnosing slowness.
- No Collector in production. Sending spans directly from applications to a tracing backend couples apps to the backend's endpoint, authentication, and retry behavior. A Collector decouples instrumentation from backend, enables tail-based sampling, allows backend migration without redeployment, and buffers spans during backend outages.
Full reference
Trace analysis for debugging
- Start from the symptom — find traces matching the error or latency
- Identify the critical path: the longest chain of sequential spans determines total latency
- Look for gaps between a parent span and its children — they indicate queueing or scheduling delay, not work
- Check span attributes for error messages, SQL queries, cache hit/miss markers
- Compare a fast trace with a slow one to spot divergence
- Read the waterfall to see parallel vs sequential execution and spot serial calls that could be parallelized
Common pitfalls
- Missing context propagation — disconnected traces almost always
mean a service is not forwarding
traceparent - Over-instrumentation — a span per function call generates noise and overhead; spans should be meaningful operations
- Sensitive data in attributes — never put PII, credentials, or full SQL parameters in spans
- No sampling in production — 100% sampling at scale will overwhelm your tracing backend and budget
- Ignoring async boundaries — traces break when context is not passed to background jobs, message consumers, or thread pools
- Confusing trace_id with request_id — propagate both; logs should carry trace_id so you can pivot from logs into traces
Cost-control tactics
When tracing volume gets expensive, look at the source mix first. Health checks are usually 30-50% of all spans and contribute zero debugging value — exclude them via the sampler. Audit middleware that emits multiple spans per request and collapse to one. Deploy a Collector with tail-based sampling that keeps 100% of errors, 100% above a latency threshold, and 5% of successful requests. This pattern typically cuts span volume 70-80% while preserving every interesting trace.
04 同仓库更多 Skills
skill-management
Manage Skill package manifests as v1 ontology entities.
schema-management
Manage generated processkit schema contracts through deterministic MCP rebuild and inspection workflows.
proposition-management
Record claims, risks, beliefs, world facts, WSJF estimates, and assumptions through the Proposition interface.
ontology-management
Manage generated v1 ontology entities that do not require a dedicated domain server.
okf-compatibility
Import, export, and validate conformant Open Knowledge Format bundles.
capability-management
Manage versioned Capability entities and their governed lifecycle.