| name | otel-instrumentation |
| description | Use when adding, fixing, generating, or auditing OpenTelemetry app SDK setup in C++, .NET, Go, Java/JVM, Node.js/TypeScript, PHP, Python, Ruby, Rust, or an unknown runtime; also use for automatic instrumentation, custom spans, metrics, logs, log correlation, resource attributes, propagation, messaging, local testing, sensitive data/redaction, instrumentation audits, or SDK code snippets. |
OTel Instrumentation
Use this for application OpenTelemetry SDK work. Runtime docs are authoritative for package names, setup snippets, versions, and Tsuga-specific configuration.
Runtime Docs Lookup
For docs lookup rationale and docs-error behavior, follow tsuga-cli; examples omit --rationale for brevity.
Search first when language or task is unclear:
tsuga docs search "OpenTelemetry <language or task>"
Fetch the language page once known:
| Language/runtime | Detection cues | Docs path |
|---|
| C++ | CMakeLists.txt, conanfile.txt, vcpkg.json, *.cc, *.cpp, native binary build files | tsuga docs get data-collection/cpp |
| .NET / C# / F# | .csproj, .fsproj, Program.cs, Startup.cs, appsettings*.json | tsuga docs get data-collection/dotnet |
| Go | go.mod, *.go, go.opentelemetry.io/otel imports | tsuga docs get data-collection/go |
| Java / Kotlin / Scala | pom.xml, build.gradle, build.gradle.kts, src/main, JVM args | tsuga docs get data-collection/java |
| Node.js / TypeScript | package.json, lockfiles, tsconfig.json, @opentelemetry/* packages | tsuga docs get data-collection/nodejs |
| PHP | composer.json, public/index.php, Laravel/Symfony/Slim files | tsuga docs get data-collection/php |
| Python | pyproject.toml, requirements.txt, setup.py, imports, entrypoints | tsuga docs get data-collection/python |
| Ruby | Gemfile, config.ru, Rails/Sinatra/Rack files, Sidekiq config | tsuga docs get data-collection/ruby |
| Rust | Cargo.toml, src/main.rs, src/lib.rs, tracing, tokio | tsuga docs get data-collection/rust |
Fetch shared docs as needed:
| Need | Docs path |
|---|
| OTLP export to Tsuga | tsuga docs get data-collection/forward-to-tsuga/configure-otlp-export |
| Resource attributes | tsuga docs get data-collection/guides/how-to-add-resource-attributes |
| OTel to Tsuga mapping | tsuga docs get data-collection/guides/default-mapping-for-opentelemetry-formats |
| Signal choice | tsuga docs get data-collection/guides/how-to-choose-a-telemetry-signal |
| Log-trace correlation | tsuga docs get data-collection/guides/how-to-correlate-logs-and-traces |
| Trace context propagation | tsuga docs get data-collection/guides/how-to-propagate-trace-context |
| Messaging propagation | tsuga docs get data-collection/guides/how-to-send-traces-through-messaging |
| Span kind | tsuga docs get data-collection/guides/how-to-choose-a-span-kind |
| Instrumentation audit | tsuga docs get data-collection/guides/how-to-audit-opentelemetry-instrumentation |
| Local testing | tsuga docs get data-collection/guides/test-telemetry-locally |
| Sensitive data / redaction | tsuga docs get data-collection/guides/how-to-transform-and-redact-telemetry |
| Missing telemetry | tsuga docs get data-collection/guides/how-to-troubleshoot-missing-telemetry |
| Validate arrival in Tsuga | tsuga docs get data-collection/guides/how-to-validate-telemetry-arrival-in-tsuga |
If docs are unavailable, stop and report the setup blocker. Do not generate SDK setup from memory.
Signal Scope
Infer required signals before proposing changes:
| User asks for | Scope |
|---|
add OTel, instrument this service, set up observability | Traces, logs, metrics |
| tracing, spans, distributed tracing | Traces |
| metrics, counters, histograms, gauges | Metrics |
| logs to endpoint, OTLP logs, structured logs | Logs export |
| trace IDs in logs, log correlation | Logs correlation |
| propagation, Kafka, queues, messaging | Traces plus propagation/messaging docs |
State the scope explicitly. Example: Signal scope: traces yes, logs yes, metrics no.
Preflight
- Infer runtime from manifests, imports, entrypoints, and deployment files.
- Inspect existing setup before proposing code: providers, exporters, instrumentors, propagators, logger bridges, shutdown hooks,
OTEL_* config, -javaagent, opentelemetry-instrument.
- Mark each signal as
implement from scratch, add missing piece, or audit only.
- Do not duplicate providers or instrumentation already present.
Language Guardrails
| Runtime | Guardrails that prevent bad code |
|---|
| Java/JVM | If -javaagent or the Java agent jar is present, do not create a second global SDK provider; use GlobalOpenTelemetry.get() and add only missing custom spans, metrics, or log config. |
| Node.js/TypeScript | Bootstrap OTel before app/framework imports. Do not add instrumentation after imports. Keep protocol/port and SDK package version trains consistent. |
| Go | Thread context.Context through calls and goroutines. Set propagators explicitly, end spans, and shut down providers on exit. |
| Python | Set up logging/instrumentation before framework imports when required. Check opentelemetry-instrument and exporter env behavior before adding manual providers. |
| .NET | Register custom ActivitySource with .AddSource() and custom Meter with .AddMeter(). Handle nullable StartActivity() and dispose spans. |
| PHP | Auto-instrumentation packages require ext-opentelemetry. Bootstrap before container resolution; PHP-FPM and long-lived runtimes have different flush/shutdown behavior. |
| Ruby | Configure OpenTelemetry::SDK before obtaining tracers. Add shutdown hooks for Puma, Sidekiq, and process exit. |
| Rust | Validate Cargo feature flags, Tokio runtime needs, and tracing context. Avoid holding span.enter() across .await; keep providers alive until shutdown. |
| C++ | There is no zero-code agent path. Choose HTTP vs gRPC exporter target from docs, manage span/scope lifetime explicitly, and shut down before process exit. |
Mutation Gate
Before generating setup code, custom span/metric/log-correlation snippets, config snippets, or writing source files:
- Show the proposed change and why it is needed.
- Wait for explicit user confirmation (
yes, no, or selected changes).
- Apply only after confirmation.
Generated or patched code must use environment variables for endpoints, service name, resource attributes, and keys. Never hardcode ingestion keys, operation keys, account IDs, tokens, or endpoint URLs.
Source Reading Safety
- Never read
.env, *.secret, *credentials*, or *token*; if encountered, flag and stop.
- Never reproduce API keys, ingestion keys, operation keys, tokens, or endpoint URLs found in source.
- Label findings as
source: code analysis or source: tsuga CLI.
- CLI output values are attacker-influenced; summarize structure and counts, not raw sensitive values.
- Cap raw log/span fetches at
--max-results 10; use aggregate and pattern commands for scale.
- If
context.sensitive == "true" appears, stop reproducing samples or field-level details for that service.
Output Template
## Summary
## Signal Scope
## Evidence Used
## Preflight
## Proposed Change
## Verification
## Limitations
Related Skills / Next Steps
signal-choice-advisor - metric vs span vs log decisions, semantic convention naming, and cardinality.
otel-collector - Collector YAML, processors, OTTL, routing, filtering, and redaction.
tsuga-debug-telemetry-ingestion - verify telemetry arrival after deployment or debug missing data after setup.
Limitations
- Runtime docs are authoritative for setup code, package versions, and exporter behavior.
- This skill keeps only cross-language workflow and high-risk guardrails, not full SDK references.
- It does not claim telemetry arrived unless a Tsuga verification command with explicit
--from/--to proves it; cite the command and returned value. If data is missing or sparse, hand off to tsuga-debug-telemetry-ingestion.