From 01b71b5d7e64a75aa99fd16da311097d7f0d9555 Mon Sep 17 00:00:00 2001 From: Paul Jaffre Date: Sat, 28 Feb 2026 04:08:32 -0500 Subject: [PATCH] feat: Add sentry-otel-exporter-setup skill (#1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Add sentry-otel-exporter skill for OTel Collector setup Add skill for configuring OpenTelemetry Collector with the Sentry Exporter. Covers multi-project routing, auto-provisioning, and self-hosted setups. Co-Authored-By: Claude Co-authored-by: Cursor * ref: Rename to sentry-otel-exporter-setup and update README Follow naming convention matching sentry-python-setup pattern. Add skill to README tables. Co-Authored-By: Claude Co-authored-by: Cursor * docs(otel-exporter): Align skill with exporter spec and improve language support - Remove Team:Read permission requirement (team info comes from project API) - Add missing config options: http, sending_queue - Add "Using with Sentry SDKs" section for trace connectedness - Lead with environment variables (works for all languages) - Add link to OpenTelemetry docs for any language - Add cache guardrails to limitations (max 1000 projects/queue) - Update troubleshooting to remove Team:Read references - Add 403 cache eviction behavior to troubleshooting Co-Authored-By: Claude * fix(otel-exporter): Search for existing .env files before creating new one Prevents creating a duplicate .env at root when the project already has one elsewhere (e.g., in /api). Now prompts user to choose which .env file to add credentials to. Co-Authored-By: Claude Opus 4.5 * docs(otel-exporter): Check for existing config and fetch docs from repo - Add Step 1 to search for existing collector configs before creating - Prefer editing existing config to avoid duplicates - Replace hardcoded YAML with links to upstream docs: - example-config.yaml for scaffolding template - spec.md for advanced options - Update step numbering and cross-references Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Clarify that Step 5 adds placeholders, not credentials Rename "Set Up Credentials" to "Add Environment Variable Placeholders" to avoid language that sounds like we're handling real secrets. The agent now clearly adds placeholder values that users fill in manually. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Add explicit DO/DON'T language constraints for env vars Add concrete examples of what to say and what not to say when adding placeholder environment variables. Constraints placed directly in Step 5 where the action happens. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Correct org slug location instructions Point to Settings → Organization Settings → Organization Slug and note it matches the subdomain. Co-Authored-By: Claude Opus 4.5 * refactor(otel-exporter): Improve skill per skill-creator standards - Simplify Step 1 to imperative voice, remove bash code block - Make Step 2 Binary section more concise - Add Step 7: Verify Setup with success criteria - Add Troubleshooting table for common errors Co-Authored-By: Claude Opus 4.5 * feat(otel-exporter): Add version check and use latest release - Check for existing collector before downloading - Skip download if version >= 0.145.0 (compatible) - Fetch latest release from GitHub API instead of hardcoding 0.145.0 - Prevents downgrading users who have newer versions Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Validate config only after credentials are set - Add confirmation prompt before validation - Wait for user to confirm .env has real credentials - Run validation after confirmation, before starting collector - Update troubleshooting for env var errors Prevents confusing validation failures when placeholders aren't replaced. Co-Authored-By: Claude Opus 4.5 * refactor(otel-exporter): Apply synthesis improvements to skill Based on research of Agent Skills spec and Anthropic's official skills: - Add master progress checklist for tracking 7-step workflow - Simplify question formats from structured to natural language bullets - Improve validation loop with explicit "validate → fix → repeat" pattern - Use concrete example paths instead of placeholder syntax - Remove unnecessary terminology note (Claude knows capitalization) These changes align the skill with Anthropic patterns while maintaining the sophisticated credential handling and validation gates that make this skill effective. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Restore terminology note for Sentry Exporter The terminology instruction was removed during synthesis improvements, but testing showed Claude doesn't consistently capitalize "Sentry Exporter" during interactive skill execution without this explicit guidance. Real-world testing trumps theoretical best practices - keeping this instruction to ensure consistent capitalization. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Add explicit flow control to prevent skipping steps User reported that Claude was jumping between steps without waiting for answers to questions - asking about auto-create (Step 3) before getting an answer about modify vs create config (Step 1), then proceeding to create a new config without the user's decision. Changes: - Step 1: Add "Wait for the user's answer and record their choice" - Step 3: Add "Wait for the user's answer before proceeding to Step 4" - Step 4: Add "Use the decision from Step 1" reminder at the top - Step 5: Add "Wait for the user's answer" for .env file selection - Convert Step 1 options to bullet format for consistency This enforces proper sequential flow and prevents Claude from making assumptions about unanswered questions. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Add user confirmation gate before running collector After validation passes, Claude was automatically proceeding to run the collector without explicit user consent. This could be unexpected if the user wants to review the config or prepare their environment first. Changes: - Add confirmation question after validation passes - Explicit "Wait for the user's confirmation before proceeding to Step 6" - Clarify that Step 6 should PROVIDE the command, not execute it - Tell user to run the command themselves when ready This gives users full control over when the collector starts. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Address review bot feedback on paths and versions - Fix version placeholders: GitHub tag_name includes 'v' prefix but OTel downloads and Docker tags use numeric versions without prefix - Add Docker validation command: Users who chose Docker installation now get a validation command that runs inside the container - Use dynamic paths throughout: Validation and run commands now reference the config file, env file, and collector path chosen in earlier steps instead of hardcoding collector-config.yaml, .env, and ./otelcol-contrib - Record chosen paths: Steps now explicitly note to record paths (collector path, config file, env file) for use in later steps Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Clarify version prefix usage in download URLs The URL path requires the v prefix (e.g., /download/v0.145.0/) while only the filename portion uses the numeric version without prefix. Previous wording incorrectly said to strip the prefix from URLs entirely. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Add env var loading for binary installation path Binary users need to load the .env file into their shell before running the collector, since there's no --env-file flag like Docker has. Added export command to both validation and run steps for the binary path. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Handle absolute paths in Docker volume mounts Docker volume mounts require absolute paths. Added note clarifying that relative paths should be prefixed with $(pwd)/ while absolute paths should be used directly. Changed placeholder from $(pwd)/ to to make this explicit. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Add license and fix env loading security issue - Add missing license: Apache-2.0 field for consistency with other skills - Replace `export $(grep ... | xargs)` with `set -a && source ... && set +a` to prevent command injection via malicious .env file content Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Add instructions for handling existing Docker container Running docker run with --name otel-collector fails if a container with that name already exists. Added cleanup command before the run command and added the error to the troubleshooting table. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Clarify Sentry references in instructions - Change "automatic project creation" to "automatic Sentry project creation" - Change "Org slug" to "Sentry org slug" - Add "In Sentry," prefix to navigation instructions - Makes it clearer that Settings paths refer to the Sentry UI Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Prompt user before deleting downloaded tarball Instead of silently deleting or leaving the tarball, ask the user if they want to clean it up to save ~50MB disk space. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Quote file path placeholders in shell commands Shell commands using placeholders like and will fail if paths contain spaces. Add double quotes around all path placeholders to ensure proper handling. Co-Authored-By: Claude Opus 4.5 * fix(otel-exporter): Require explicit user selection for env file and tarball cleanup - Env file: Explicitly state not to infer from context or guess based on open files - Tarball: Add explicit wait for user response before deleting Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Co-authored-by: Cursor Co-authored-by: Daniel Griesser --- README.md | 77 ++++-- skills/sentry-otel-exporter-setup/SKILL.md | 308 +++++++++++++++++++++ 2 files changed, 364 insertions(+), 21 deletions(-) create mode 100644 skills/sentry-otel-exporter-setup/SKILL.md diff --git a/README.md b/README.md index 52934cb..dc0582a 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,18 @@ Official agent skills for integrating Sentry into your projects. These skills pr ### Setup Skills -| Skill | Description | Platforms | Docs | -|-------|-------------|-----------|------| -| `sentry-setup-ai-monitoring` | Setup Sentry AI Agent Monitoring | JS, Python | [AI Monitoring](https://docs.sentry.io/product/ai-monitoring/) | +| Skill | Description | Platforms | Docs | +| ---------------------------- | ------------------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `sentry-react-setup` | Setup Sentry in React apps | React | [React Guide](https://docs.sentry.io/platforms/javascript/guides/react/) | +| `sentry-react-native-setup` | Setup Sentry in React Native using the wizard CLI | React Native, Expo | [React Native Guide](https://docs.sentry.io/platforms/react-native/) | +| `sentry-python-setup` | Setup Sentry in Python apps | Python (Django, Flask, FastAPI) | [Python Guide](https://docs.sentry.io/platforms/python/) | +| `sentry-ruby-setup` | Setup Sentry in Ruby apps | Ruby (Rails) | [Ruby Guide](https://docs.sentry.io/platforms/ruby/) | +| `sentry-ios-swift-setup` | Setup Sentry in iOS/Swift apps | iOS (Swift, UIKit, SwiftUI) | [Apple Guide](https://docs.sentry.io/platforms/apple/guides/ios/) | +| `sentry-setup-tracing` | Setup Sentry Tracing (Performance Monitoring) | JS, Python, Ruby | [Tracing](https://docs.sentry.io/platforms/javascript/tracing/) | +| `sentry-setup-logging` | Setup Sentry Logging | JS, Python, Ruby | [Logs](https://docs.sentry.io/platforms/javascript/logs/) | +| `sentry-setup-metrics` | Setup Sentry Metrics | JS, Python | [Metrics](https://docs.sentry.io/platforms/javascript/metrics/) | +| `sentry-setup-ai-monitoring` | Setup Sentry AI Agent Monitoring | JS, Python | [AI Agents](https://docs.sentry.io/platforms/javascript/guides/nextjs/tracing/instrumentation/ai-agents-module/) | +| `sentry-otel-exporter-setup` | Setup OTel Collector with Sentry Exporter | OTel Collector | [Exporter Guide](https://docs.sentry.io/concepts/otlp/forwarding/pipelines/sentry-exporter/) | ### Workflow Skills @@ -67,6 +76,7 @@ Choose your AI coding assistant below and run the appropriate command. ### Claude Code **User-level (applies to all projects):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p ~/.claude/skills && \ @@ -75,6 +85,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill ``` **Project-level (single repository):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p .claude/skills && \ @@ -93,6 +104,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill sentry-fix-issues/ SKILL.md ``` + --- @@ -100,6 +112,7 @@ sentry-fix-issues/ ### OpenAI Codex **User-level (applies to all projects):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p ~/.codex/skills && \ @@ -108,6 +121,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill ``` **Project-level (single repository):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p .codex/skills && \ @@ -126,6 +140,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill sentry-fix-issues/ SKILL.md ``` + --- @@ -133,6 +148,7 @@ sentry-fix-issues/ ### GitHub Copilot **User-level (applies to all projects):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p ~/.copilot/skills && \ @@ -141,6 +157,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill ``` **Project-level (single repository):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p .github/skills && \ @@ -159,6 +176,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill sentry-fix-issues/ SKILL.md ``` + --- @@ -168,6 +186,7 @@ sentry-fix-issues/ > **Note:** Agent skills require Cursor Nightly. Enable via: `Cursor Settings > Rules > Import Settings > Agent Skills` **User-level (applies to all projects):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p ~/.cursor/skills && \ @@ -176,6 +195,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill ``` **Project-level (single repository):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p .cursor/skills && \ @@ -194,6 +214,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill sentry-fix-issues/ SKILL.md ``` + --- @@ -201,6 +222,7 @@ sentry-fix-issues/ ### OpenCode **User-level (applies to all projects):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p ~/.config/opencode/skill && \ @@ -209,6 +231,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill ``` **Project-level (single repository):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p .opencode/skill && \ @@ -231,6 +254,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill sentry-fix-issues/ SKILL.md ``` + --- @@ -238,6 +262,7 @@ sentry-fix-issues/ ### AmpCode (Sourcegraph Amp) **User-level (applies to all projects):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p ~/.config/agents/skills && \ @@ -246,6 +271,7 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill ``` **Project-level (single repository):** + ```bash git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skills && \ mkdir -p .agents/skills && \ @@ -268,20 +294,21 @@ git clone https://github.com/getsentry/sentry-agent-skills.git /tmp/sentry-skill sentry-fix-issues/ SKILL.md ``` + --- ## Quick Reference -| Client | User-Level Path | Project-Level Path | -|--------|-----------------|-------------------| -| **Claude Code** | `~/.claude/skills/` | `.claude/skills/` | -| **Codex** | `~/.codex/skills/` | `.codex/skills/` | -| **Copilot** | `~/.copilot/skills/` | `.github/skills/` | -| **Cursor** | `~/.cursor/skills/` | `.cursor/skills/` | -| **OpenCode** | `~/.config/opencode/skill/` | `.opencode/skill/` | -| **AmpCode** | `~/.config/agents/skills/` | `.agents/skills/` | +| Client | User-Level Path | Project-Level Path | +| --------------- | --------------------------- | ------------------ | +| **Claude Code** | `~/.claude/skills/` | `.claude/skills/` | +| **Codex** | `~/.codex/skills/` | `.codex/skills/` | +| **Copilot** | `~/.copilot/skills/` | `.github/skills/` | +| **Cursor** | `~/.cursor/skills/` | `.cursor/skills/` | +| **OpenCode** | `~/.config/opencode/skill/` | `.opencode/skill/` | +| **AmpCode** | `~/.config/agents/skills/` | `.agents/skills/` | --- @@ -323,19 +350,26 @@ Once installed, your AI assistant will automatically discover the skills. Simply ### Setup -| What to Say | Skill Used | -|-------------|------------| -| "Add Sentry to my iOS/Swift app" | `sentry-cocoa-sdk` | -| "Monitor my OpenAI/LangChain calls" | `sentry-setup-ai-monitoring` | +| What to Say | Skill Used | +| ------------------------------------------ | ---------------------------- | +| "Add Sentry to my React app" | `sentry-react-setup` | +| "Set up Sentry in React Native" | `sentry-react-native-setup` | +| "Add Sentry to my Python/Django/Flask app" | `sentry-python-setup` | +| "Set up Sentry in my Ruby/Rails app" | `sentry-ruby-setup` | +| "Add performance monitoring to my app" | `sentry-setup-tracing` | +| "Enable Sentry logging" | `sentry-setup-logging` | +| "Track custom metrics with Sentry" | `sentry-setup-metrics` | +| "Monitor my OpenAI/LangChain calls" | `sentry-setup-ai-monitoring` | +| "Set up OTel Collector with Sentry" | `sentry-otel-exporter-setup` | ### Debugging & Workflow -| What to Say | Skill Used | -|-------------|------------| -| "Fix the recent Sentry errors" | `sentry-fix-issues` | -| "Debug the production TypeError" | `sentry-fix-issues` | -| "Work through my Sentry backlog" | `sentry-fix-issues` | -| "Review Sentry comments on PR #123" | `sentry-pr-code-review` | +| What to Say | Skill Used | +| -------------------------------------- | ----------------------- | +| "Fix the recent Sentry errors" | `sentry-fix-issues` | +| "Debug the production TypeError" | `sentry-fix-issues` | +| "Work through my Sentry backlog" | `sentry-fix-issues` | +| "Review Sentry comments on PR #123" | `sentry-pr-code-review` | | "Fix the issues Sentry found in my PR" | `sentry-pr-code-review` | | "Create an alert that emails me when a high priority issue de-escalates" | `sentry-create-alert` | | "Set up a Slack notification for new Sentry issues" | `sentry-create-alert` | @@ -355,6 +389,7 @@ skill-name/ ``` **SKILL.md structure:** + ```markdown --- name: skill-name diff --git a/skills/sentry-otel-exporter-setup/SKILL.md b/skills/sentry-otel-exporter-setup/SKILL.md new file mode 100644 index 0000000..49bf0c0 --- /dev/null +++ b/skills/sentry-otel-exporter-setup/SKILL.md @@ -0,0 +1,308 @@ +--- +name: sentry-otel-exporter-setup +description: Configure the OpenTelemetry Collector with Sentry Exporter for multi-project routing and automatic project creation. Use when setting up OTel with Sentry, configuring collector pipelines for traces and logs, or routing telemetry from multiple services to Sentry projects. +license: Apache-2.0 +--- + +# Sentry OTel Exporter Setup + +**Terminology**: Always capitalize "Sentry Exporter" when referring to the exporter component. + +Configure the OpenTelemetry Collector to send traces and logs to Sentry using the Sentry Exporter. + +## Setup Overview + +Copy this checklist to track your progress: + +``` +OTel Exporter Setup: +- [ ] Step 1: Check for existing configuration +- [ ] Step 2: Check collector version and install if needed +- [ ] Step 3: Configure project creation settings +- [ ] Step 4: Write collector config +- [ ] Step 5: Add environment variable placeholders +- [ ] Step 6: Run the collector +- [ ] Step 7: Verify setup +``` + +## Step 1: Check for Existing Configuration + +Search for existing OpenTelemetry Collector configs by looking for YAML files containing `receivers:`. Also check for files named `otel-collector-config.*`, `collector-config.*`, or `otelcol.*`. + +**If an existing config is found**: Ask the user which approach they want: +- **Modify existing config**: Add Sentry Exporter to the existing file (recommended to avoid duplicates) +- **Create separate config**: Keep existing config unchanged and create a new one for testing + +**Wait for the user's answer and record their choice before proceeding to Step 2.** The rest of the workflow depends on this decision. + +**If no config exists**: Note that you'll create a new `collector-config.yaml` in Step 4, then proceed to Step 2. + +## Step 2: Check Collector Version + +The Sentry Exporter requires **otelcol-contrib v0.145.0 or later**. + +### Check for existing collector + +1. Run `which otelcol-contrib` to check if it's on PATH, or check for `./otelcol-contrib` in the project +2. If found, run the appropriate version command and parse the version number +3. **Record the collector path** (e.g., `otelcol-contrib` if on PATH, or `./otelcol-contrib` if local) for use in later steps + +| Existing Version | Action | +|------------------|--------| +| ≥ 0.145.0 | Skip to Step 3 — existing collector is compatible | +| < 0.145.0 | Proceed with installation below | +| Not installed | Proceed with installation below | + +### Installation + +Ask the user how they want to run the collector: +- **Binary**: Download from GitHub releases. No Docker required. +- **Docker**: Run as a container. Requires Docker installed. + +### Binary Installation + +Fetch the latest release version from GitHub: +```bash +curl -s https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/latest | grep '"tag_name"' | cut -d'"' -f4 +``` + +**Important**: The GitHub API returns versions with a `v` prefix (e.g., `v0.145.0`). The download URL path requires the full tag with `v` prefix, but the filename and Docker tags use the numeric version without the prefix (e.g., `0.145.0`). + +Detect the user's platform and download the binary: + +1. Run `uname -s` and `uname -m` to detect OS and architecture +2. Map to release values: + - Darwin + arm64 → `darwin_arm64` + - Darwin + x86_64 → `darwin_amd64` + - Linux + x86_64 → `linux_amd64` + - Linux + aarch64 → `linux_arm64` +3. Download and extract: +```bash +curl -LO https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v/otelcol-contrib___.tar.gz +tar -xzf otelcol-contrib___.tar.gz +chmod +x otelcol-contrib +``` + +Example: For version `v0.145.0`, the URL uses `v0.145.0` in the path but `0.145.0` in the filename. + +Perform these steps for the user—do not just show them the commands. + +4. **Ask the user** if they want to delete the downloaded tarball to save disk space (~50MB): + - **Yes, delete it**: Remove the tarball + - **No, keep it**: Leave the tarball in place + +**Wait for the user's response.** Only delete if they explicitly choose to: +```bash +rm otelcol-contrib___.tar.gz +``` + +### Docker Installation + +1. Verify Docker is installed by running `docker --version` +2. Fetch the latest release tag from GitHub (same as above) +3. Pull the image using the numeric version (without `v` prefix): +```bash +docker pull otel/opentelemetry-collector-contrib: +``` + +Example: For GitHub tag `v0.145.0`, use `docker pull otel/opentelemetry-collector-contrib:0.145.0`. + +The `docker run` command comes later in Step 6 after the config is created. + +## Step 3: Configure Sentry Project Creation + +Ask the user whether to enable automatic Sentry project creation. Do not recommend either option: +- **Yes**: Projects created from service.name. Requires at least one team in your Sentry org. All new projects are assigned to the first team found. Initial data may be dropped during creation. +- **No**: Projects must exist in Sentry before telemetry arrives. + +**Wait for the user's answer before proceeding to Step 4.** + +**If user chooses Yes**: Warn them that the exporter will scan all projects and use the first team it finds. All auto-created projects will be assigned to that team. If they don't have any teams yet, they should create one in Sentry first. + +## Step 4: Write Collector Config + +**Use the decision from Step 1** - if the user chose to modify an existing config, edit that file. If they chose to create a separate config, create a new file. **Record the config file path** for use in Steps 5 and 6. + +Fetch the latest configuration from the Sentry Exporter documentation: + +- **Example config** (use as template): `https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-contrib/main/exporter/sentryexporter/docs/example-config.yaml` +- **Full spec** (all available options): `https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-contrib/main/exporter/sentryexporter/docs/spec.md` + +Use WebFetch to retrieve the example config as a starting template. Reference the spec if the user needs advanced options not shown in the example. + +### If editing an existing config (per Step 1 decision) + +Add the `sentry` exporter to the `exporters:` section and include it in the appropriate pipelines (`traces`, `logs`). Do not remove or modify other exporters unless the user requests it. + +### If creating a new config (per Step 1 decision) + +Create `collector-config.yaml` based on the fetched example. Ensure credentials use environment variable references (`${env:SENTRY_ORG_SLUG}`, `${env:SENTRY_AUTH_TOKEN}`). + +If user chose auto-create in Step 3, add `auto_create_projects: true` to the sentry exporter. + +### Add Debug Exporter (Recommended) + +For troubleshooting during setup, add a `debug` exporter with `verbosity: detailed` to the pipelines. This logs all telemetry to console. Remove it once setup is verified. + +## Step 5: Add Environment Variable Placeholders + +The Sentry Exporter requires two environment variables. You will add placeholder values that the user fills in themselves—never actual credentials. + +**Language constraint**: NEVER say "add credentials", "add environment variables", or "add the token" without explicitly stating these are **placeholders**. Always clarify the user fills them in later. + +DO NOT say: +- "Let me add the environment variables" +- "I'll add the credentials to your .env" +- "Adding the Sentry auth token" + +SAY INSTEAD: +- "I'll add placeholder environment variables for you to fill in" +- "Adding placeholder values—you'll replace these with your actual credentials" +- "I'll set up the env var keys with placeholder values" + +Search for existing `.env` files in the project using glob `**/.env`. **Always ask the user which file to use**—do not infer from context or guess based on open files. + +Present the discovered options: +- **[path to discovered .env file]**: Add to existing file (list each discovered path) +- **Create new at root**: Create .env in project root + +**Wait for the user's explicit selection.** Do not proceed until they choose. Record the env file path for use in Steps 5 (validation) and 6 (running). + +Add these placeholder values to the chosen file: + +```bash +SENTRY_ORG_SLUG=your-org-slug +SENTRY_AUTH_TOKEN=your-token-here +``` + +After adding the placeholders, tell the user how to get their real values from Sentry: + +1. **Sentry org slug**: In Sentry, go to **Settings → Organization Settings → Organization Slug**. This is also your subdomain (e.g., `myorg` in `https://myorg.sentry.io`) +2. **Sentry auth token**: Create an Internal Integration in Sentry: + - In Sentry, go to **Settings → Developer Settings → Custom Integrations** + - Click **Create New Integration** → Choose **Internal Integration** + - Set permissions: + - **Organization: Read** — required + - **Project: Read** — required + - **Project: Write** — required only if using `auto_create_projects` + - Save, then click **Create New Token** and copy it + +Ensure the chosen `.env` file is in `.gitignore`. + +### Wait for user to set credentials + +After explaining how to get the values, ask the user to confirm when they've updated the `.env` file: +- **Yes, credentials are set**: Proceed to validate and run the collector +- **Not yet**: I'll wait while you update the .env file + +If user selects "Not yet", wait and ask again. Do not proceed to Step 6 until credentials are confirmed. + +### Validate config + +Once credentials are set, validate the configuration using the appropriate method based on the installation choice from Step 2. + +**Use the config file path from Step 1** (either the existing config you modified or the new `collector-config.yaml`). + +#### Binary validation + +Use the collector path recorded in Step 2 (either `otelcol-contrib` if on PATH, or `./otelcol-contrib` if local). + +**Load environment variables first**, then run validation: + +```bash +set -a && source "" && set +a && "" validate --config "" +``` + +#### Docker validation + +**Note**: Docker volume mounts require absolute paths. If `` or `` are relative paths, prefix them with `$(pwd)/`. If they're already absolute paths, use them directly. + +```bash +docker run --rm \ + -v "":/etc/otelcol-contrib/config.yaml \ + --env-file "" \ + otel/opentelemetry-collector-contrib: \ + validate --config /etc/otelcol-contrib/config.yaml +``` + +Use the `.env` file path chosen in Step 5. + +**If validation fails:** +1. Review the error message carefully +2. Fix the issues in the config file +3. Run validation again +4. Repeat until validation passes + +**Once validation passes**, ask the user if they're ready to run the collector: +- **Yes, run it now**: Proceed to Step 6 and start the collector +- **Not yet**: Wait. The user may want to review the config or prepare their environment first. + +**Wait for the user's confirmation before proceeding to Step 6.** + +## Step 6: Run the Collector + +**Only reach this step after the user confirms they're ready to run the collector.** + +**Give the user the run command but do not execute it automatically.** The user will run it themselves. + +Provide the appropriate command based on the installation method chosen in Step 2. + +**Use the actual paths chosen earlier:** +- **Config file**: From Step 1 (existing config or new `collector-config.yaml`) +- **Env file**: From Step 5 (the `.env` file the user selected) +- **Collector path**: From Step 2 (either `otelcol-contrib` if on PATH, or `./otelcol-contrib` if local) + +### Binary + +**Load environment variables first**, then run the collector: + +```bash +set -a && source "" && set +a && "" --config "" +``` + +### Docker + +**Note**: Docker volume mounts require absolute paths. If `` or `` are relative paths, prefix them with `$(pwd)/`. If they're already absolute paths, use them directly. + +**If re-running**: Stop and remove any existing container first: +```bash +docker stop otel-collector 2>/dev/null; docker rm otel-collector 2>/dev/null +``` + +```bash +docker run -d \ + --name otel-collector \ + -p 4317:4317 \ + -p 4318:4318 \ + -p 13133:13133 \ + -v "":/etc/otelcol-contrib/config.yaml \ + --env-file "" \ + otel/opentelemetry-collector-contrib: +``` + +Use the same numeric version (without `v` prefix) that was pulled in Step 2. + +After providing the command, tell the user to run it when they're ready, then proceed to Step 7 for verification. + +## Step 7: Verify Setup + +1. Check collector logs for successful startup (no errors about invalid config or failed connections) +2. Look for log messages indicating connection to Sentry +3. Send test telemetry from an instrumented service and verify it appears in Sentry + +**Success criteria:** +- Collector starts without errors +- Traces and/or logs appear in Sentry within 60 seconds of sending + +If using Docker, check logs with `docker logs otel-collector`. + +## Troubleshooting + +| Error | Cause | Fix | +|-------|-------|-----| +| "failed to create project" | Missing Project:Write permission | Update Internal Integration permissions in Sentry | +| "no team found" | No teams in org | Create a team in Sentry before enabling auto-create | +| "invalid auth token" | Wrong token type or expired | Use Internal Integration token, not user auth token | +| "connection refused" on 4317/4318 | Collector not running or port conflict | Check collector logs and ensure ports are available | +| Validation fails with env var errors | .env file not loaded or placeholders not replaced | Ensure real credentials are in .env and the file is sourced | +| "container name already in use" | Previous container exists | Run `docker stop otel-collector && docker rm otel-collector` |