From backend
OpenTelemetry tracing discipline: correct spans, propagation, and semantic conventions produce useful traces. Invoke whenever task involves any interaction with distributed tracing — span creation, context propagation, instrumentation, sampling configuration, or OpenTelemetry SDK setup.
npx claudepluginhub xobotyi/cc-foundry --plugin backendThis skill uses the workspace's default tool permissions.
Create spans for logical operations, propagate context across every boundary, use semantic conventions for attribute
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Create spans for logical operations, propagate context across every boundary, use semantic conventions for attribute names. Every tracing decision — span granularity, attribute selection, sampling strategy — trades off cost against visibility.
${CLAUDE_SKILL_DIR}/references/spans.md]: Span anatomy, root spans, lifetime code patterns${CLAUDE_SKILL_DIR}/references/span-data.md]: Events format, links format, SDK limits table${CLAUDE_SKILL_DIR}/references/context-propagation.md]: W3C header format, propagator
selection, baggage details, security${CLAUDE_SKILL_DIR}/references/instrumentation.md]: Server/client/async code patterns,
library rules, testing guidance${CLAUDE_SKILL_DIR}/references/sampling.md]: Head/tail/combined strategies, decision guide, sampler
types${CLAUDE_SKILL_DIR}/references/semantic-conventions.md]: HTTP/DB/messaging attribute
lists, status mapping, general conventions${CLAUDE_SKILL_DIR}/references/sdk-components.md]: Resource config, env vars, Collector
deployment, exporter typesA span represents a single unit of work in a trace — an HTTP request handler, a database query, a message publish. Not every function call.
Name spans for the class of operation, not the instance. Low-cardinality names enable aggregation; high-cardinality names destroy it.
{METHOD} {route} — server: GET /users/:id; client: GET{operation} {table} — SELECT users, INSERT orders| Name | Verdict |
|---|---|
get | Too general |
get_account/42 | Too specific — ID in name |
get_account | Good |
GET /users/{userId} | Good — route template |
POST /api/v2/orders/abc123 | Bad — order ID in name |
SpanKind tells backends how to assemble the trace tree. Set it correctly.
SERVER (Incoming) — HTTP handler, gRPC server method
CLIENT (Outgoing) — HTTP client call, DB query, gRPC call
PRODUCER (Outgoing) — Enqueue message, schedule job
CONSUMER (Incoming) — Dequeue message, process job
INTERNAL (Neither) — In-process business logic, computation
A single span MUST NOT serve more than one purpose
Create a new span before injecting context for outgoing calls
CLIENT -> SERVER for synchronous calls; PRODUCER -> CONSUMER for async
Using INTERNAL for HTTP handlers or DB calls is wrong — use SERVER or CLIENT
Unset — No error. Default — do not change on success.
Error — Operation failed. When an error occurs; include description.
Ok — Explicitly successful. Only to override a previous Error; rarely needed.
Leave status Unset on success — it already means "no error"
Ok is a "final call" — once set, subsequent Error attempts are ignored
Instrumentation libraries SHOULD NOT set Ok — leave to application code
end(), the span becomes non-recording; further mutations are ignoreddefer (Go), try/finally (Java/JS), context manager (Python)Key-value pairs annotating a span. Value types: string, boolean, integer, float, or arrays of these.
http.request.method, db.system, not custom names. Consistent
naming enables cross-service analysis.IsRecording before expensive attribute computation — sampled-out spans discard all data.AttributeCountLimit (default 128). Excess attributes are silently
dropped.Timestamped annotations — structured log entries attached to a span.
RecordException with setStatus(ERROR) — RecordException alone does not change span statusAssociate a span with spans from other traces without parent-child hierarchy.
See ${CLAUDE_SKILL_DIR}/references/span-data.md for events format, links format, and SDK limits table.
Context propagation correlates spans across service boundaries. Without it, each service produces isolated spans — no distributed trace.
Propagates arbitrary key-value pairs across service boundaries alongside trace context.
See ${CLAUDE_SKILL_DIR}/references/context-propagation.md for W3C header format, propagator selection table, baggage
details, and security considerations.
| Approach | When | Trade-off |
|---|---|---|
| Automatic | Supported libraries (HTTP, DB, messaging) | Zero code, no business attrs |
| Manual | Business logic, unsupported libraries | Full control, more code |
| Hybrid (recommended) | Production | Auto for infra + manual for business logic |
TracerProvider via dependency injection or use the global oneTracerProviderGood candidates: public API methods with I/O or significant computation, request/message handlers, outbound calls (HTTP, DB, RPC), background jobs.
Poor candidates: every function call (noise), thin wrapper libraries (already instrumented underneath), pure computation with no I/O and sub-ms duration.
Decision: Is it a network call or significant I/O? -> Create span (CLIENT/SERVER). Is it a meaningful business operation? -> Create span (INTERNAL). Would a span event on parent suffice? -> Add event. Otherwise -> don't instrument.
schema_url to record which semantic convention version you useTracerProvider injection for testabilitySee ${CLAUDE_SKILL_DIR}/references/instrumentation.md for server-side, client-side, and async producer/consumer
patterns, plus testing guidance.
Sampling controls which traces are recorded and exported — the primary mechanism for managing tracing costs.
Decision at trace creation time, before any spans complete.
AlwaysOn — Record and sample everythingAlwaysOff — Drop everythingTraceIdRatioBased(ratio) — Sample based on trace ID hashParentBased(root) — Delegate based on parent sampling decisionParentBased is the most common production configuration — respects parent decisions, applies custom root sampling.
Default SDK sampler: ParentBased(root=AlwaysOn).
Decision after all spans in a trace complete. Requires collector infrastructure.
ParentBased — children follow parent decisions for complete tracesSee ${CLAUDE_SKILL_DIR}/references/sampling.md for combined head+tail strategies, decision guide, and per-scenario
recommendations.
Use semantic conventions for span names and attributes. Consistent naming enables cross-service analysis without learning custom attribute names.
SERVER, name {METHOD} {http.route}, never full URI pathCLIENT, name {METHOD}CLIENT, name {operation} {target}, always sanitize queriesPRODUCER, name {destination} publishCONSUMER, name {destination} processSee ${CLAUDE_SKILL_DIR}/references/semantic-conventions.md for required/recommended attributes per domain, status
mapping rules, and general conventions.
shutdown() on exit — flushes remaining spansResource with service.name — identifies your service in backendsBatchSpanProcessor in production — SimpleSpanProcessor is for dev/testing onlySee ${CLAUDE_SKILL_DIR}/references/sdk-components.md for Resource attributes, BatchSpanProcessor tuning, exporter
types, environment variable configuration, and Collector deployment patterns.
When writing tracing code:
When reviewing tracing code:
span.end().The coding skill governs workflow; this skill governs tracing implementation choices. Language-specific skills handle SDK API differences.