| name | sentry |
| description | [Applies to: **/*] Definitive guidelines for integrating and using Sentry for error tracking and performance monitoring, ensuring optimal setup, performance, and debuggability across all applications. |
| source | cursor_mdc |
Sentry Best Practices
Sentry is our definitive platform for error tracking and performance monitoring. Proper integration ensures we debug faster, ship more reliably, and maintain high application health. This guide outlines the mandatory best practices for all projects.
1. Code Organization and Initialization
Always initialize the Sentry SDK early in your application's bootstrap process. This ensures maximum coverage for errors and performance tracing.
1.1. Early and Centralized Initialization
Initialize Sentry once, as close to your application's entry point as possible. Use environment variables for sensitive data like DSN and for configuration that varies by environment.
❌ BAD: Late or Scattered Initialization
import sentry_sdk
def my_function():
if not sentry_sdk.is_initialized():
sentry_sdk.init(dsn="YOUR_DSN")
✅ GOOD: Application Bootstrap (Python Example)
import os
import sentry_sdk
from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration
SENTRY_DSN = os.getenv("SENTRY_DSN")
SENTRY_ENVIRONMENT = os.getenv("SENTRY_ENVIRONMENT", "development")
SENTRY_RELEASE = os.getenv("SENTRY_RELEASE", "unknown")
SENTRY_TRACES_SAMPLE_RATE = float(os.getenv("SENTRY_TRACES_SAMPLE_RATE", "0.0"))
if SENTRY_DSN:
sentry_sdk.init(
dsn=SENTRY_DSN,
environment=SENTRY_ENVIRONMENT,
release=SENTRY_RELEASE,
enable_tracing=True,
traces_sample_rate=SENTRY_TRACES_SAMPLE_RATE,
)
✅ GOOD: Application Bootstrap (JavaScript/TypeScript Example)
import * as Sentry from "@sentry/node";
const SENTRY_DSN = process.env.SENTRY_DSN;
const SENTRY_ENVIRONMENT = process.env.SENTRY_ENVIRONMENT || "development";
const SENTRY_RELEASE = process.env.SENTRY_RELEASE || "unknown";
const SENTRY_TRACES_SAMPLE_RATE = parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE || "0.0");
if (SENTRY_DSN) {
Sentry.init({
dsn: SENTRY_DSN,
environment: SENTRY_ENVIRONMENT,
release: SENTRY_RELEASE,
integrations: [
],
tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE,
enableTracing: true,
});
}
1.2. Environment, Release, and User Context
Always set environment and release during initialization. Enrich events with user and other relevant context for faster debugging.
✅ GOOD: Setting Context
import sentry_sdk
def process_order(user_id: str, order_details: dict):
with sentry_sdk.push_scope() as scope:
scope.set_user({"id": user_id, "email": "user@example.com"})
scope.set_tag("order_type", "premium")
scope.set_context("order_details", order_details)
try:
raise ValueError("Failed to process payment")
except Exception as e:
sentry_sdk.capture_exception(e)
2. Common Patterns and Anti-patterns
2.1. Performance Tracing with OpenTelemetry
Leverage OpenTelemetry for distributed tracing. Sentry SDKs integrate seamlessly, allowing end-to-end visibility without rewriting existing instrumentation.
✅ GOOD: OpenTelemetry Integration (Python Example)
import sentry_sdk
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from sentry_sdk.integrations.opentelemetry import SentrySpanProcessor
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
provider.add_span_processor(SentrySpanProcessor())
trace.set_tracer_provider(provider)
sentry_sdk.init(
dsn="YOUR_DSN",
enable_tracing=True,
traces_sample_rate=1.0,
)
tracer = trace.get_tracer(__name__)
def my_traced_function():
with tracer.start_as_current_span("my-custom-operation"):
print("Executing traced operation...")
2.2. Isolated Clients for Shared Environments (JavaScript/TypeScript)
NEVER use Sentry.init() in shared environments (e.g., browser extensions, VS Code extensions, third-party widgets). This pollutes global state and leads to data leakage. Create a dedicated client instance manually.
❌ BAD: Global Init in Shared Environment
import * as Sentry from "@sentry/browser";
Sentry.init({
dsn: "YOUR_DSN",
});
✅ GOOD: Manual Client Setup for Shared Environments
import {
BrowserClient,
defaultStackParser,
getDefaultIntegrations,
makeFetchTransport,
Scope,
} from "@sentry/browser";
const integrations = getDefaultIntegrations({}).filter(
(defaultIntegration) =>
!["BrowserApiErrors", "Breadcrumbs", "GlobalHandlers"].includes(defaultIntegration.name)
);
const client = new BrowserClient({
dsn: "YOUR_DSN",
transport: makeFetchTransport,
stackParser: defaultStackParser,
integrations: integrations,
tracesSampleRate: 1.0,
enableTracing: true,
});
const scope = new Scope();
scope.setClient(client);
client.init();
try {
throw new Error("Example error in extension");
} catch (error) {
scope.captureException(error);
}
2.3. AWS Lambda Integration
For serverless functions, use the platform-specific integration.
✅ GOOD: AWS Lambda (Python Example)
import os
import sentry_sdk
from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration
SENTRY_DSN = os.getenv("SENTRY_DSN")
SENTRY_TRACES_SAMPLE_RATE = float(os.getenv("SENTRY_TRACES_SAMPLE_RATE", "0.0"))
if SENTRY_DSN:
sentry_sdk.init(
dsn=SENTRY_DSN,
integrations=[AwsLambdaIntegration()],
traces_sample_rate=SENTRY_TRACES_SAMPLE_RATE,
environment=os.getenv("SENTRY_ENVIRONMENT", "production"),
release=os.getenv("SENTRY_RELEASE", "unknown"),
)
def lambda_handler(event, context):
print("Processing event...")
raise ValueError("Something went wrong in Lambda!")
return {"statusCode": 200, "body": "Success"}
3. Performance Considerations
3.1. Configure traces_sample_rate Judiciously
traces_sample_rate directly impacts performance overhead and Sentry quota usage.
- Development: Set to
1.0 to capture all transactions for full visibility.
- Production: Set to a lower value (e.g.,
0.01 to 0.1) to sample a representative subset of transactions. Adjust based on traffic volume and monitoring needs.
❌ BAD: traces_sample_rate=1.0 in Production
sentry_sdk.init(
dsn="YOUR_PROD_DSN",
traces_sample_rate=1.0,
enable_tracing=True,
)
✅ GOOD: Controlled Sampling in Production
sentry_sdk.init(
dsn="YOUR_PROD_DSN",
traces_sample_rate=0.05,
enable_tracing=True,
)
4. Common Pitfalls and Gotchas
4.1. Missing or Invalid DSN
Without a valid DSN, Sentry cannot send events. Always verify your DSN is correctly configured, ideally via environment variables.
❌ BAD: Hardcoded or Missing DSN
sentry_sdk.init(
dsn="",
)
✅ GOOD: DSN from Environment Variables
import os
sentry_sdk.init(
dsn=os.getenv("SENTRY_DSN"),
)
4.2. Unset environment and release
Events without environment or release are significantly harder to triage and correlate. Always set these values.
❌ BAD: Omitting Environment/Release
sentry_sdk.init(
dsn="YOUR_DSN",
)
✅ GOOD: Explicit Environment/Release
sentry_sdk.init(
dsn="YOUR_DSN",
environment=os.getenv("SENTRY_ENVIRONMENT", "development"),
release=os.getenv("SENTRY_RELEASE", "my-app@1.0.0"),
)
4.3. Ignoring Inbound Filters
If Sentry events aren't appearing, check your Sentry project's Project Settings > Inbound Filters. Ensure you haven't accidentally enabled filters that block events (e.g., "Filter out errors known to be caused by browser extensions" if you're in a shared environment).
5. Testing Approaches
5.1. Disabling Sentry in Test Environments
Prevent test noise and unnecessary Sentry events by disabling the SDK during automated tests.
✅ GOOD: Conditional Sentry Initialization
import os
import sentry_sdk
if os.getenv("SENTRY_DSN") and os.getenv("APP_ENV") != "test":
sentry_sdk.init(
dsn=os.getenv("SENTRY_DSN"),
environment=os.getenv("SENTRY_ENVIRONMENT", "development"),
release=os.getenv("SENTRY_RELEASE", "unknown"),
traces_sample_rate=float(os.getenv("SENTRY_TRACES_SAMPLE_RATE", "0.0")),
enable_tracing=True,
)
5.2. Manual Error Capture
For specific, non-critical errors that you want to report without crashing the application, use sentry_sdk.capture_message() or sentry_sdk.capture_exception().
✅ GOOD: Manual Capture
import sentry_sdk
def process_data(data: list):
if not data:
sentry_sdk.capture_message("Received empty data for processing.", level="warning")
return False
try:
raise ConnectionError("Database unreachable")
except ConnectionError as e:
sentry_sdk.capture_exception(e)
return False