Claude
Skills
Sign in
Back

sentry-multi-env-setup

Included with Lifetime
$97 forever

Configure Sentry across development, staging, and production environments with separate DSNs, environment-specific sample rates, per-environment alert rules, and dashboard filtering. Use when setting up Sentry for dev/staging/production, managing environment-specific configurations, isolating data between environments, or configuring .env files for per-environment DSNs. Trigger: "sentry environments", "sentry staging setup", "multi-environment sentry", "sentry dev vs prod", "sentry DSN per env".

Data & Analyticssaassentryenvironmentsconfigurationmulti-envdsnalerts

What this skill does

# Sentry Multi-Environment Setup

## Overview

Configure Sentry to run across development, staging, and production with isolated DSNs, tuned sample rates, environment-aware alert routing, and dashboard filtering. Covers `@sentry/node` v8+ (TypeScript) and `sentry-sdk` v2+ (Python), targeting `sentry.io` or self-hosted Sentry 24.1+. The goal is to capture everything in dev, validate in staging, and protect production with tight sampling and PII scrubbing.

## Prerequisites

- Sentry organization at [sentry.io](https://sentry.io) with at least one project created
- `@sentry/node` v8+ installed (`npm install @sentry/node`) or `sentry-sdk` v2+ (`pip install sentry-sdk`)
- Environment naming convention agreed upon (this guide uses `development`, `staging`, `production`)
- DSN strategy decided: single project with environment tags or separate projects per environment (see [project-structure-options.md](references/project-structure-options.md))
- `.env` file management tooling (dotenv, direnv, or platform-native env config)

## Instructions

### Step 1 — Create Environment-Aware SDK Configuration with Separate DSNs

Each environment gets its own DSN pointing to a dedicated Sentry project. This prevents dev noise from inflating production quotas and allows independent rate limits per environment.

**Set up `.env` files per environment:**

```bash
# .env.development
SENTRY_DSN=https://[email protected]/111
SENTRY_ENVIRONMENT=development
SENTRY_RELEASE=local-dev

# .env.staging
SENTRY_DSN=https://[email protected]/222
SENTRY_ENVIRONMENT=staging

# .env.production
SENTRY_DSN=https://[email protected]/333
SENTRY_ENVIRONMENT=production
```

**TypeScript — environment-aware init with typed config:**

```typescript
// config/sentry.ts
import * as Sentry from '@sentry/node';

type Environment = 'development' | 'staging' | 'production';

interface EnvSentryConfig {
  tracesSampleRate: number;
  sampleRate: number;
  debug: boolean;
  sendDefaultPii: boolean;
  maxBreadcrumbs: number;
  enabled: boolean;
}

const ENV_CONFIG: Record<Environment, EnvSentryConfig> = {
  development: {
    tracesSampleRate: 1.0,   // Capture every transaction for local debugging
    sampleRate: 1.0,         // Every error
    debug: true,             // Verbose console output for SDK troubleshooting
    sendDefaultPii: true,    // Include PII for local debugging only
    maxBreadcrumbs: 100,     // Full breadcrumb trail
    enabled: true,           // Set to false to fully disable in dev
  },
  staging: {
    tracesSampleRate: 0.5,   // 50% of transactions — enough to catch regressions
    sampleRate: 1.0,         // All errors — staging validates error handling
    debug: false,
    sendDefaultPii: false,   // Staging mirrors prod PII policy
    maxBreadcrumbs: 50,
    enabled: true,
  },
  production: {
    tracesSampleRate: 0.1,   // 10% — balances visibility with quota budget
    sampleRate: 1.0,         // All errors — never drop production errors
    debug: false,
    sendDefaultPii: false,   // Never send PII in production
    maxBreadcrumbs: 50,
    enabled: true,
  },
};

export function initSentry(env?: Environment): void {
  const environment = env
    || (process.env.SENTRY_ENVIRONMENT as Environment)
    || (process.env.NODE_ENV as Environment)
    || 'development';

  const config = ENV_CONFIG[environment] || ENV_CONFIG.development;

  Sentry.init({
    dsn: process.env.SENTRY_DSN,
    environment,
    release: process.env.SENTRY_RELEASE || `app@${process.env.npm_package_version || 'unknown'}`,
    ...config,

    // Environment-specific event filtering
    beforeSend(event) {
      // Dev: capture everything for debugging
      if (environment === 'development') return event;

      // Staging: drop debug-level events to reduce noise
      if (environment === 'staging' && event.level === 'debug') return null;

      // Production: aggressive filtering
      if (environment === 'production') {
        // Drop known non-actionable browser errors
        if (event.exception?.values?.some(e =>
          e.value?.match(/ResizeObserver|Loading chunk|AbortError/)
        )) return null;

        // Scrub sensitive headers
        if (event.request?.headers) {
          delete event.request.headers['Authorization'];
          delete event.request.headers['Cookie'];
          delete event.request.headers['X-API-Key'];
        }
      }

      return event;
    },
  });
}
```

**Python — equivalent multi-environment init:**

```python
# config/sentry_config.py
import os
import sentry_sdk

ENV_CONFIG = {
    "development": {
        "traces_sample_rate": 1.0,
        "sample_rate": 1.0,
        "debug": True,
        "send_default_pii": True,
        "max_breadcrumbs": 100,
    },
    "staging": {
        "traces_sample_rate": 0.5,
        "sample_rate": 1.0,
        "debug": False,
        "send_default_pii": False,
        "max_breadcrumbs": 50,
    },
    "production": {
        "traces_sample_rate": 0.1,
        "sample_rate": 1.0,
        "debug": False,
        "send_default_pii": False,
        "max_breadcrumbs": 50,
    },
}


def init_sentry() -> None:
    environment = os.environ.get(
        "SENTRY_ENVIRONMENT",
        os.environ.get("PYTHON_ENV", "development"),
    )
    config = ENV_CONFIG.get(environment, ENV_CONFIG["development"])

    def before_send(event, hint):
        if environment == "production":
            exc_info = hint.get("exc_info")
            if exc_info:
                exc_type = exc_info[0]
                # Drop expected exceptions in production
                if exc_type in (KeyboardInterrupt, SystemExit):
                    return None
            # Scrub PII from headers
            request = event.get("request", {})
            headers = request.get("headers", {})
            for key in ("Authorization", "Cookie", "X-API-Key"):
                headers.pop(key, None)
        return event

    sentry_sdk.init(
        dsn=os.environ.get("SENTRY_DSN", ""),
        environment=environment,
        release=os.environ.get("SENTRY_RELEASE", "unknown"),
        before_send=before_send,
        **config,
    )
```

### Step 2 — Configure Per-Environment Alert Rules and Dashboard Filtering

Alert routing prevents dev noise from waking on-call engineers. Each environment gets alert rules matching its severity tier.

**Production alert rules (Sentry dashboard > Alerts > Create Rule):**

| Alert Type | Condition | Filter | Action |
|-----------|-----------|--------|--------|
| Issue alert | New issue | `environment:production` | PagerDuty on-call |
| Metric alert | Error rate > 50/min for 5 min | `environment:production` | Slack `#alerts-critical` |
| Metric alert | P95 latency > 2s for 10 min | `environment:production` | Slack `#alerts-performance` |

**Staging alert rules:**

| Alert Type | Condition | Filter | Action |
|-----------|-----------|--------|--------|
| Issue alert | New issue (first seen) | `environment:staging` | Slack `#alerts-staging` |
| Metric alert | Error rate > 100/min for 5 min | `environment:staging` | Slack `#alerts-staging` |

**Development:** No alerts configured. Developers check the dashboard manually or use `debug: true` for console output.

**Add environment context tags for richer filtering:**

```typescript
// Add to Sentry.init() for dashboard filtering
Sentry.init({
  // ...base config from Step 1
  initialScope: {
    tags: {
      environment: process.env.SENTRY_ENVIRONMENT || process.env.NODE_ENV,
      region: process.env.AWS_REGION || process.env.GCP_REGION || 'us-east-1',
      service: process.env.SERVICE_NAME || 'app',
      deployment: process.env.DEPLOYMENT_ID || 'unknown',
    },
  },
});

// Dashboard filter queries:
//   Issues > environment:production is:unresolved
//   Performance > environment:staging service:api-gateway
//   Discover > environment:production region:us-east-1
```

**Disable Sentry in test and CI environments:**

```typescript
// test/setup.ts — prev

Related in Data & Analytics