| name | ollygarden-otel-manual-instrumentation |
| description | OpenTelemetry best practices for manual instrumentation. Use when adding, changing, or reviewing OpenTelemetry instrumentation in code. Guidance to choose runtime boundaries, choose signals, apply semantic conventions, handle propagation, control cardinality, and verify the result. |
OpenTelemetry Manual Instrumentation
Use this skill for manual instrumentation design, implementation, and review.
Usage:
- load the bundled references only when they apply
- use
otel-semantic-conventions for semantic convention naming and attributes when available; otherwise use the upstream semantic convention docs via websearch
If a companion skill is unavailable:
- do not stop
- do not rely on memory alone when the guidance can be checked from official sources
- use the corresponding official OpenTelemetry release sources, documentation, examples, or source code
- state that the companion skill was unavailable
- cite the fallback source used
- leave any unverified item unresolved rather than guessing
Non-Negotiable Rules
- Use the latest compatible OpenTelemetry SDK or package for the project language. If the latest release is not compatible, use the latest compatible version and state the reason. When SDK behavior, examples, or setup details are unclear, check official SDK docs and source code instead of relying on model memory.
- Instrument meaningful runtime boundaries only. Do not create spans for helpers, loop bodies, validation-only code, serialization glue, getters, or pure computation. See
references/boundaries.md.
- Choose the signal before writing code. Use spans for request or operation flow, metrics for aggregate recurring questions, logs or events for discrete diagnostic facts, and nothing when telemetry would be noise. See
references/signal-selection.md.
- For any known boundary type such as
http, db, messaging, or rpc, check the released semantic conventions before choosing names or attributes. Derive semconv-governed span names directly from the released naming rule. Do not add custom prose, protocol labels, hostnames, product names, or business hints to semconv-governed span names. If no released key exists, use a stable custom namespace and keep values bounded.
- Keep values bounded. Prefer method, route template, status code, operation name, destination name, region, deployment environment, or customer tier. Avoid raw user IDs, full URLs, raw SQL in metrics, free-form messages, and timestamps as dimensions.
- Never record raw SQL statement text with inlined parameter values on any signal — spans included. Bound parameters routinely carry PII (emails, names, tokens). Disable statement-value capture in the instrumentation (e.g. parameterize
db.query.text) or redact it; prefer parameterized text like INSERT INTO users (...) VALUES (?, ?, ?).
- Record failure on the span that owns the final failed outcome. Do not mark the final span as failed if retries succeed. Do not treat handled errors as terminal failures. See
references/boundaries.md.
- Preserve trace context across network, async, and internal call boundaries. Extract inbound context, inject outbound context, and thread the active context into every DB/client call so its span stays attached. Use baggage only when it is intentional and bounded. See
references/propagation.md.
Workflow
- Identify the task mode: planning, implementation, or review.
- For each instrumentation point, decide:
- the runtime boundary
- the signal
- whether to create a new span, annotate the current span, emit a metric/event, or do nothing
- the semantic convention group if one exists
- the key attributes and cardinality risks
- PII and sensitive data risks
- whether auto-instrumentation already covers the technical boundary
- the propagation requirements
- Implement or review the code.
- Re-open the changed files and verify the result with evidence.
SDK Setup
For SDK initialization, exporter, processor, propagator, and transport configuration, use the ollygarden-otel-sdk-setup companion skill when available. If it is unavailable, apply these minimal defaults:
- traces: OTLP exporter plus batch span processor
- metrics: OTLP exporter plus periodic exporting metric reader
- logs: OTLP exporter plus batching log record processor
- propagators:
tracecontext,baggage
- if no SDK exists, configure one; if one exists, reuse it; do not add extra signals
These defaults are fallback mechanics only. They do not override the instrumentation
plan. Do not use them to add signals, exporters, propagators, or services outside the
plan/task scope. Logs require an explicit redaction/export policy, and baggage requires
intentional bounded keys.
Planning Mode Output
When this skill is used during instrumentation planning, record the decisions that the
implementer must not guess:
- why the instrumentation point is a meaningful runtime boundary
- whether auto-instrumentation already covers the technical boundary
- whether the implementation should create a new span or annotate existing context
- exact signal choice: span, current-span attributes, metric, log/event, or nothing
- attributes with cardinality and PII risk
- sensitive values that must not be recorded
- error ownership and handled-error behavior
- propagation requirements, or why propagation is not applicable
References To Load On Demand
- boundary choice and error ownership:
references/boundaries.md
- signal choice:
references/signal-selection.md
- propagation and baggage:
references/propagation.md
- semantic conventions naming and attributes skill:
otel-semantic-conventions
- SDK initialization and configuration skill:
ollygarden-otel-sdk-setup
- SDK versions and docs skill:
otel-sdk-versions
Verification Contract
If you changed code or performed an instrumentation review:
- re-open the changed files before finishing
- confirm each applicable item with codebase evidence
- mark non-applicable items explicitly
- do not mark an item complete based on intent alone
Report the final check with:
[x] completed
[~] not applicable, with a reason
[ ] unresolved
Use these items:
- meaningful boundary
- latest compatible SDK or package decision
- SDK setup uses common defaults or preserves an intentional alternative
- released semantic conventions were checked for each known boundary type
- names and attributes match released semantic conventions, or a concrete compatibility limitation is stated
- signal choice is intentional
- cardinality is bounded
- error ownership matches the final failed outcome
- propagation is handled across relevant network or async boundaries, or is not applicable
- changed files were re-read
- remaining risks or gaps are stated