From ebs-claude-code
Configure Claude Code telemetry on the current developer machine. Detects the platform (macOS / Ubuntu / Windows), writes the required environment variables to the right shell rc (zsh/bash) or PowerShell profile + User-scope env vars, and verifies end-to-end reachability to the OTLP collector. Includes an auto-heal loop that maps common failures to concrete fixes, and an `--uninstall` flag that cleanly removes everything. Trigger when the user asks to set up Claude Code telemetry, enable metrics, or invokes `/ebs-claude-code:setup-telemetry`.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ebs-claude-code:setup-telemetryThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Configure Claude Code telemetry so the local CLI pushes OpenTelemetry
Configure Claude Code telemetry so the local CLI pushes OpenTelemetry metrics to the ebs-cc-monitoring collector. Cross-platform: macOS (zsh), Ubuntu (bash), Windows (PowerShell 5.1 + pwsh 7). Idempotent, diagnostic, reversible.
Activate this skill when the user:
/ebs-claude-code:setup-telemetry (possibly with flags)--uninstall flow)https://cc-otlp.aspatari.dev
Override by passing --endpoint <URL>. For local testing against the
in-repo stack (make up), use http://localhost:4318.
Follow this flow in order. Each stage uses platform-specific scripts shipped with the skill; pick the right one based on host OS.
Invoke the detection script to learn about the host:
./scripts/detect-platform.shpowershell -ExecutionPolicy Bypass -File ./scripts/detect-platform.ps1
(from the Bash tool, prefix with powershell.exe or pwsh.exe as available)The script emits JSON on stdout with os, arch, shell, shell_rc_path,
claude_bin, claude_version, telemetry_env, keyring_available.
Surface a one-line summary to the user, e.g.:
Detected: macOS arm64, zsh (/Users/alice/.zshrc), Claude Code 1.0.17, telemetry not yet configured.
If claude_bin is null → Claude Code is not installed. STOP and point the
user at https://docs.claude.com/en/docs/claude-code/setup. Do not proceed.
If os is null → unsupported platform. STOP and tell the user this skill
covers macOS / Ubuntu / Windows only.
Priority order:
--endpoint <URL> flag from $ARGUMENTS$EBS_CC_TELEMETRY_ENDPOINT env var (non-interactive override for CI / scripts)AskUserQuestion:
https://cc-otlp.aspatari.devhttp://localhost:4318 (for developers testing with make up)Validate the URL parses (scheme + host + port). Reject obvious mistakes
(missing ://, non-numeric port) with a short message and re-ask.
Show the diff first. Read the current shell rc, mentally apply the write, and display a compact diff to the user:
Proposed change to /Users/alice/.zshrc:
+ # BEGIN ebs-cc-telemetry (managed by /ebs-claude-code:setup-telemetry — do not edit)
+ export CLAUDE_CODE_ENABLE_TELEMETRY=1
+ export OTEL_METRICS_EXPORTER=otlp
+ export OTEL_LOGS_EXPORTER=otlp
+ export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
+ export OTEL_EXPORTER_OTLP_ENDPOINT=https://cc-otlp.aspatari.dev
+ export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative
+ export OTEL_METRICS_INCLUDE_VERSION=true
+ # END ebs-cc-telemetry
If --dry-run is set, stop here and do NOT write.
Otherwise, invoke the writer (team/role are optional resource-attr tags for multi-team dashboard slicing — ask before invoking when unset, see below):
./scripts/write-shell-block.sh --rc "<shell_rc_path>" --endpoint "<URL>" [--team "<name>"] [--role "<name>"]pwsh -File ./scripts/write-shell-block.ps1 -ProfilePath "<path>" -Endpoint "<URL>" [-Team "<name>"] [-Role "<name>"]Team / role prompt. Before invoking the writer, if --team and --role
were NOT passed as flags, ask the user:
AskUserQuestion: Tag your telemetry for per-team / per-role dashboard slicing?
(Stored as OTEL_RESOURCE_ATTRIBUTES=team=X,role=Y,installer=ebs-claude-code)
Options:
1. Yes — I'll enter team and role
2. Skip — don't add resource attributes
If "Yes", prompt for team and role as free-form strings. Only
[A-Za-z0-9_.-] allowed (spaces and commas break OTEL attribute format;
the writer will drop invalid values with a WARN and continue).
Check the exit code. On 3 (unwritable), fall through to Heal with
cause: rc_unwritable.
Run the verifier to confirm the endpoint answers TCP probes:
./scripts/verify-endpoint.sh --endpoint "<URL>"pwsh -File ./scripts/verify-endpoint.ps1 -Endpoint "<URL>"For a full end-to-end check (optional; user must opt in): pass
--run-claude --prom-url <URL> (POSIX) or -RunClaude -PromUrl <URL>
(Windows). This actually calls claude -p with the new env and polls
the provided Prometheus for metric growth. Default mode is TCP-only.
On exit:
0 → verified, proceed to Report2 → pre-flight failure (e.g., claude missing) → Heal with cause: preflight4 → unreachable or metric timeout → Heal with cause: unreachablecause: otherMap the failure cause to a fix, referencing
references/TROUBLESHOOTING.md for depth:
| Cause | Likely reason | Action |
|---|---|---|
unreachable | DNS not routing, firewall blocking, TLS cert not ready | Verify DNS resolves; try nc -vz host port; for fresh deploys check Let's Encrypt issued the cert |
preflight | claude not on PATH, jq missing, PowerShell execution policy | Point at the tool's install; for PS, suggest Set-ExecutionPolicy RemoteSigned -Scope CurrentUser |
rc_unwritable | rc owned by root, locked file, symlink chain | ls -la the rc, walk symlinks, suggest chown or --dry-run to hand-paste the block |
other | unknown | Print stderr from the failing script verbatim and link to TROUBLESHOOTING.md |
After applying a heal, re-run Verify once. Do NOT loop — if the second verify still fails, stop and print the final error for the user to act on.
Summarize what changed and what to do next:
✅ Telemetry configured on this machine.
Platform: macOS arm64 (zsh)
Endpoint: https://cc-otlp.aspatari.dev
Shell rc: /Users/alice/.zshrc [block added]
Verification: endpoint reachable (TCP probe)
To pick up the new env vars:
source /Users/alice/.zshrc # zsh/bash
# or open a new terminal
To verify end-to-end (after using Claude Code for a bit), visit the
overview dashboard and confirm your user appears:
https://grafana.aspatari.dev/d/cc-adoption
On Windows, append the mandatory note:
Windows: env vars set via
setxtake effect in new processes only. Close and reopen your terminal / VS Code for the change to apply.
Parse $ARGUMENTS for these, in order; later flags override earlier ones.
| Flag | Effect |
|---|---|
| (none) | Full flow: Detect → Decide → Configure → Verify → Heal → Report |
--endpoint <URL> | Skip the endpoint-picker dialog; use this URL |
--team <name> | Skip the team prompt; use this value. Only [A-Za-z0-9_.-]. |
--role <name> | Skip the role prompt; use this value. Same char rules. |
--uninstall | Skip Configure/Verify; invoke remove-shell-block.{sh,ps1}; report |
--dry-run | Detect + build the proposed block + display the diff; do NOT write |
--verify-only | Skip Configure; run Detect + Verify + Heal |
Examples:
/ebs-claude-code:setup-telemetry
/ebs-claude-code:setup-telemetry --endpoint http://localhost:4318
/ebs-claude-code:setup-telemetry --team platform --role senior-engineer
/ebs-claude-code:setup-telemetry --dry-run
/ebs-claude-code:setup-telemetry --verify-only
/ebs-claude-code:setup-telemetry --uninstall
./scripts/remove-shell-block.sh --rc "<shell_rc_path>"pwsh -File ./scripts/remove-shell-block.ps1 -ProfilePath "<path>"security on macOS, secret-tool on Linux, Credential Manager on
Windows) via helpers that are already wired (but no-op) in the detect
script's keyring_available field.docs/client-setup.md — user-facing guide
docs/infrastructure.md — stack operations
.ai-factory/references/claude-code-monitoring.md — metric schema referenceCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub aspatari/claude-code-telemetry-plugin --plugin ebs-claude-code