Wer kennt das: Eine neue Feature-Deployment läuft durch, Nutzer melden Fehler, aber die Logs zeigen nichts Konkretes. In 2026 ist das kein akzeptabler Zustand mehr. Sentry hat sich als Standard für Observability in modernen Web-Applikationen etabliert — und Claude Code macht das komplette Setup, von der SDK-Konfiguration bis zu Alert-Regeln, zum Automated Workflow statt zur stundenlangen Konfigurationsarbeit.
In diesem Guide zeigen wir, wie Claude Code dir hilft, ein vollständiges Sentry-Observability-Setup für TypeScript-Projekte aufzubauen: Error Capturing mit Breadcrumbs, Performance Monitoring mit Custom Spans, Next.js Integration mit Source Maps, Session Replay für UX-Debugging und intelligente Alert-Konfiguration, die dich nachts nicht unnötig weckt.
Was du in diesem Guide lernst
- Sentry SDK korrekt initialisieren mit allen relevanten Optionen
- Error Capturing mit Breadcrumbs, Scopes, Tags und User-Kontext
- Performance Monitoring mit Spans für HTTP, Datenbank und Custom Operations
- Next.js Integration inkl. Source Maps Upload und Edge Runtime Support
- Session Replay für UX-Debugging ohne Datenschutz-Kompromisse
- Alert-Konfiguration für produktionsreife Monitoring-Setups
1. Sentry Setup & SDK-Konfiguration
SDK Init
TypeScript
Environments
Die Basis jedes Sentry-Setups ist eine korrekte Sentry.init()-Konfiguration. Claude Code generiert dir eine vollständige, typsichere Initialisierung — inklusive aller Optionen, die in Production-Setups tatsächlich relevant sind.
Das Setup beginnt mit der Installation der notwendigen Pakete. Claude Code erkennt automatisch deinen Package Manager und erstellt den passenden Install-Befehl:
# Claude Code generiert den korrekten Install-Befehl
npm install @sentry/node @sentry/profiling-node
npm install @sentry/nextjs # für Next.js-Projekte
npm install --save-dev @sentry/cli # für Source Maps Upload
Die Kern-Konfiguration für eine TypeScript-Anwendung sieht in 2026 so aus — Claude Code erstellt diese Datei vollständig mit allen relevanten Optionen und erklärt dabei jeden Parameter:
// sentry.config.ts — generiert von Claude Code
import * as Sentry from "@sentry/node";
import { nodeProfilingIntegration } from "@sentry/profiling-node";
export function initSentry(): void {
Sentry.init({
// DSN aus Umgebungsvariable — niemals hardcoden
dsn: process.env.SENTRY_DSN,
// Environment: development | staging | production
environment: process.env.NODE_ENV ?? "development",
// Release-Tracking für Deployment-Korrelation
release: process.env.SENTRY_RELEASE ?? `app@${process.env.npm_package_version}`,
// Performance Monitoring: 10% in Production
tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1.0,
// Profiling: 10% der gesampelten Traces
profilesSampleRate: 0.1,
// Integrationen: Profiling aktivieren
integrations: [
nodeProfilingIntegration(),
Sentry.httpIntegration({ breadcrumbs: true }),
Sentry.expressIntegration(),
Sentry.prismaIntegration(),
],
// Sensitive Daten herausfiltern
beforeSend(event) {
if (event.request?.headers) {
delete event.request.headers["authorization"];
delete event.request.headers["cookie"];
}
return event;
},
// Known Errors ignorieren (z.B. Browser-Extensions)
ignoreErrors: [
"ResizeObserver loop limit exceeded",
"Non-Error promise rejection captured",
/^Loading chunk \d+ failed/,
],
// Debug-Modus nur in Entwicklung
debug: process.env.NODE_ENV === "development",
// Max. Breadcrumbs pro Event
maxBreadcrumbs: 50,
// Automatischer Session-Tracking
autoSessionTracking: true,
// Shutdown-Timeout für sauberes Beenden
shutdownTimeout: 2000,
});
}
💡 Claude Code Tipp: Claude Code erkennt automatisch, welche Sentry-Integrationen für dein Projekt relevant sind. Bei einem Express-Backend schlägt es expressIntegration() vor, bei Prisma die prismaIntegration() — ohne dass du danach fragen musst.
Die Konfiguration wird über Umgebungsvariablen gesteuert. Claude Code erstellt automatisch eine typsichere .env.example mit allen benötigten Variablen:
# .env.example — von Claude Code generiert
SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0
SENTRY_AUTH_TOKEN=sntrys_... # Für Source Maps Upload
SENTRY_ORG=your-org-slug
SENTRY_PROJECT=your-project-name
SENTRY_RELEASE=$(git rev-parse HEAD)
NODE_ENV=production
Sampling-Strategie nach Environment
| Environment | tracesSampleRate | profilesSampleRate | Empfehlung |
| development | 1.0 (100%) | 1.0 | Alles tracken, volle Sichtbarkeit |
| staging | 0.5 (50%) | 0.2 | Repräsentative Stichprobe |
| production | 0.1 (10%) | 0.1 | Performance-schonend, Cost-effizient |
2. Error Capturing & Breadcrumbs
captureException
withScope
Breadcrumbs
Error Capturing ist mehr als nur Sentry.captureException(error). Mit Scopes, Tags, User-Kontext und Breadcrumbs liefert Sentry die vollständige Ereignisgeschichte — und Claude Code zeigt dir, wie du das strukturiert umsetzt.
Fehler ohne Kontext sind nutzlos. Claude Code hilft dir, für jeden Error-Typ die richtigen Metadaten mitzuschicken. Hier ist ein vollständiges Error-Capturing-Muster für eine Express-Middleware:
// error-handler.ts — vollständiges Capturing mit Kontext
import * as Sentry from "@sentry/node";
import { Request, Response, NextFunction } from "express";
interface AppError extends Error {
statusCode?: number;
code?: string;
isOperational?: boolean;
}
export function sentryErrorHandler(
error: AppError,
req: Request,
res: Response,
next: NextFunction
): void {
// Scope isolieren — kein Leak in andere Events
Sentry.withScope((scope) => {
// User-Kontext aus Request setzen
if (req.user) {
scope.setUser({
id: req.user.id,
email: req.user.email,
username: req.user.name,
segment: req.user.plan, // z.B. "pro" | "free"
});
}
// Request-spezifische Tags
scope.setTag("http.method", req.method);
scope.setTag("http.route", req.route?.path ?? req.path);
scope.setTag("error.code", error.code ?? "UNKNOWN");
scope.setTag("error.operational", String(error.isOperational ?? false));
// Extra-Kontext: Request-Body (gefiltert)
scope.setContext("request_context", {
body: sanitizeBody(req.body),
query: req.query,
headers: {
"user-agent": req.headers["user-agent"],
"x-request-id": req.headers["x-request-id"],
"x-forwarded-for": req.headers["x-forwarded-for"],
},
});
// Breadcrumb für den Fehlermoment
Sentry.addBreadcrumb({
category: "request",
message: `${req.method} ${req.path} → ${error.statusCode ?? 500}`,
level: "error",
type: "http",
data: {
status_code: error.statusCode,
reason: error.message,
},
});
// Level bestimmen: 5xx = error, 4xx = warning
const level = (error.statusCode ?? 500) >= 500 ? "error" : "warning";
scope.setLevel(level);
// Nur echte Server-Fehler (5xx) an Sentry — keine 4xx
if (!error.statusCode || error.statusCode >= 500) {
Sentry.captureException(error);
}
});
const statusCode = error.statusCode ?? 500;
res.status(statusCode).json({
error: error.isOperational ? error.message : "Internal Server Error",
requestId: req.headers["x-request-id"],
});
}
Neben Exceptions kannst du auch strukturierte Messages senden — ideal für Warn-Level-Events, die du tracken, aber nicht als Bug behandeln willst:
// Strukturierte Messages für Non-Exception Events
function trackBusinessEvent(eventName: string, data: Record<string, unknown>): void {
Sentry.captureMessage(`Business Event: ${eventName}`, {
level: "info",
tags: {
"event.type": "business",
"event.name": eventName,
},
extra: data,
});
}
// Breadcrumbs für User-Navigation
function trackUserAction(action: string, metadata?: Record<string, unknown>): void {
Sentry.addBreadcrumb({
category: "user_action",
message: action,
level: "info",
data: metadata,
timestamp: Date.now() / 1000,
});
}
💡 Breadcrumb-Strategie: Füge Breadcrumbs an allen wichtigen Stellen deiner Business-Logik ein — Datenbankzugriffe, externe API-Calls, Auth-Events. Wenn ein Fehler auftritt, siehst du in Sentry den kompletten Pfad, der dazu geführt hat.
⚠️ 4xx nicht an Sentry: Schicke keine 400-499 Fehler an Sentry — das sind Nutzer-Fehler, keine Bugs. Dein Error-Budget wird sonst durch normale Fehlbedienungen aufgebraucht. Nur 5xx gehören in Sentry.
Claude Code hilft dir auch dabei, eine typgerechte sanitizeBody-Funktion zu erstellen, die sensible Daten wie Passwörter, Tokens und Kreditkartennummern automatisch aus dem Request-Body entfernt, bevor sie an Sentry gesendet werden:
// Sensitive Felder aus Request-Body entfernen
function sanitizeBody(body: Record<string, unknown>): Record<string, unknown> {
const sensitiveKeys = [
"password", "token", "secret", "apiKey",
"creditCard", "ssn", "authorization",
];
return Object.fromEntries(
Object.entries(body).map(([key, value]) => [
key,
sensitiveKeys.some((k) => key.toLowerCase().includes(k))
? "[REDACTED]"
: value,
])
);
}
3. Performance Monitoring mit Custom Spans
startSpan
HTTP Spans
DB Spans
Performance Monitoring in Sentry geht weit über simple Response-Zeiten hinaus. Custom Spans für Datenbankabfragen, externe API-Calls und eigene Business-Operationen geben dir einen vollständigen Performance-Trace deiner Anwendung.
Claude Code erstellt für dich einen vollständigen Performance-Monitoring-Layer, der alle kritischen Operationen in deiner Anwendung mit Spans abdeckt:
// performance-monitor.ts — Custom Spans für alle kritischen Pfade
import * as Sentry from "@sentry/node";
import { SpanStatus } from "@sentry/core";
// HTTP Client Span — für ausgehende Requests
export async function trackedFetch<T>(
url: string,
options: RequestInit = {},
spanName?: string
): Promise<T> {
return Sentry.startSpan(
{
name: spanName ?? `HTTP GET ${new URL(url).pathname}`,
op: "http.client",
attributes: {
"http.url": url,
"http.method": options.method ?? "GET",
"server.address": new URL(url).hostname,
},
},
async (span) => {
const startTime = Date.now();
try {
const response = await fetch(url, options);
span.setAttribute("http.status_code", response.status);
span.setAttribute("http.response_content_length",
parseInt(response.headers.get("content-length") ?? "0"));
if (!response.ok) {
span.setStatus({ code: SpanStatus.Error, message: `HTTP ${response.status}` });
}
return response.json() as Promise<T>;
} catch (error) {
span.setStatus({ code: SpanStatus.Error, message: String(error) });
throw error;
} finally {
span.setAttribute("http.duration_ms", Date.now() - startTime);
}
}
);
}
// Datenbank-Span — für SQL/Prisma Queries
export async function trackedQuery<T>(
operation: string,
table: string,
queryFn: () => Promise<T>
): Promise<T> {
return Sentry.startSpan(
{
name: `db.${operation} ${table}`,
op: "db.query",
attributes: {
"db.system": "postgresql",
"db.operation": operation,
"db.sql.table": table,
},
},
async (span) => {
const startTime = Date.now();
try {
const result = await queryFn();
span.setAttribute("db.rows_returned",
Array.isArray(result) ? result.length : 1);
return result;
} catch (error) {
span.setStatus({ code: SpanStatus.Error, message: String(error) });
Sentry.captureException(error);
throw error;
} finally {
const duration = Date.now() - startTime;
span.setAttribute("db.duration_ms", duration);
// Slow Query Warning bei > 1000ms
if (duration > 1000) {
span.setAttribute("db.slow_query", true);
}
}
}
);
}
// Custom Business-Operation Span
export async function trackedOperation<T>(
name: string,
operation: () => Promise<T>,
attributes?: Record<string, string | number | boolean>
): Promise<T> {
return Sentry.startSpan(
{ name, op: "app.operation", attributes },
operation
);
}
Diese Span-Wrapper kannst du dann in deiner Business-Logik einsetzen, ohne den eigentlichen Code zu verändern:
// Verwendung in der Service-Schicht
async function processUserOrder(userId: string, orderId: string): Promise<Order> {
return trackedOperation(
"process_order",
async () => {
// DB: User laden
const user = await trackedQuery("SELECT", "users", () =>
prisma.user.findUnique({ where: { id: userId } })
);
// Externe API: Payment Service
const paymentResult = await trackedFetch<PaymentResponse>(
`https://payment-api.example.com/charge`,
{ method: "POST", body: JSON.stringify({ userId, orderId }) },
"payment.charge"
);
// DB: Order aktualisieren
return trackedQuery("UPDATE", "orders", () =>
prisma.order.update({
where: { id: orderId },
data: { status: "paid", paymentId: paymentResult.id },
})
);
},
{ userId, orderId, operation: "checkout" }
);
}
Performance-Metriken die Sentry automatisch trackt
| Metrik | Beschreibung | Threshold (Empfehlung) |
| p50 / p95 / p99 | Response-Zeit-Percentile | p95 < 500ms |
| Apdex Score | User Satisfaction Score | > 0.9 |
| Failure Rate | Prozentsatz fehlgeschlagener Requests | < 1% |
| Throughput | Requests pro Minute | Baseline + 20% Alert |
| LCP / FID / CLS | Core Web Vitals (Frontend) | Good-Bereich aller Metriken |
4. Next.js & Source Maps Integration
withSentryConfig
Source Maps
Edge Runtime
Next.js und Sentry sind eine natürliche Kombination, aber das Setup ist komplex — Server Components, Client Components, Edge Runtime und App Router erfordern unterschiedliche Konfigurationen. Claude Code navigiert diese Komplexität automatisch.
Das Herzstück der Next.js-Integration ist die Konfiguration in next.config.ts. Claude Code erstellt diese vollständig mit allen relevanten Optionen:
// next.config.ts — mit vollständiger Sentry-Integration
import { withSentryConfig } from "@sentry/nextjs";
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// Deine bestehende Next.js-Konfiguration
experimental: {
instrumentationHook: true, // Für Sentry instrumentation.ts
},
};
export default withSentryConfig(nextConfig, {
// Auth Token für Source Maps Upload
authToken: process.env.SENTRY_AUTH_TOKEN,
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
// Silent in CI vermeiden (Logs für Debugging)
silent: process.env.CI === "true",
// Source Maps: hochladen und dann löschen (kein Leak)
widenClientFileUpload: true,
hideSourceMaps: true,
// Automatischer Release-Name aus Git
release: {
name: process.env.SENTRY_RELEASE ?? process.env.VERCEL_GIT_COMMIT_SHA,
setCommits: {
auto: true,
ignoreMissing: true,
},
},
// Tunnel-Route: Umgeht Ad-Blocker
tunnelRoute: "/monitoring",
// Bundle-Analyse nicht mit Sentry-Code aufblähen
disableLogger: true,
// Automatic Route Instrumentation
automaticVercelMonitors: true,
});
Die instrumentation.ts Datei im Root deines Next.js-Projekts initialisiert Sentry korrekt für Server und Edge:
// instrumentation.ts — Root des Next.js-Projekts
export async function register(): Promise<void> {
if (process.env.NEXT_RUNTIME === "nodejs") {
// Server-seitige Initialisierung
const { init } = await import("./sentry.server.config");
init();
}
if (process.env.NEXT_RUNTIME === "edge") {
// Edge Runtime (Middleware, Edge API Routes)
const { init } = await import("./sentry.edge.config");
init();
}
}
// sentry.edge.config.ts — Minimal-Config für Edge Runtime
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 0.1,
// Edge hat eingeschränkte Node.js APIs — keine Profiling-Integration!
integrations: [],
environment: process.env.VERCEL_ENV ?? "development",
});
Für den Client-Side-Teil erstellt Claude Code eine separate Konfigurationsdatei:
// sentry.client.config.ts — Browser-Konfiguration
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NEXT_PUBLIC_ENVIRONMENT,
release: process.env.NEXT_PUBLIC_SENTRY_RELEASE,
tracesSampleRate: 0.1,
// Browser-spezifische Integrationen
integrations: [
Sentry.browserTracingIntegration({
// Automatisches Tracing für Navigation
enableInp: true,
}),
],
// Tunnel-Route für Ad-Blocker-Bypass
tunnel: "/monitoring",
// Feature-Flags via Attachments
beforeSend(event) {
// Filtern von bekannten Browser-Extension-Fehlern
const frames = event.exception?.values?.[0]?.stacktrace?.frames;
if (frames?.some((f) => f.filename?.includes("chrome-extension://"))) {
return null;
}
return event;
},
});
⚠️ Source Maps und Production: Source Maps dürfen nie öffentlich zugänglich sein. hideSourceMaps: true stellt sicher, dass Sentry die Maps hochlädt und danach aus dem Build-Output entfernt. Trotzdem: Überprüfe nach dem Deployment mit den DevTools, dass keine .map-Dateien öffentlich erreichbar sind.
Source Maps Upload im CI/CD
Claude Code integriert den Source Maps Upload direkt in deine GitHub Actions oder Vercel Deployment Pipeline — inklusive korrekter Release-Tagging und Commit-Korrelation, damit du in Sentry direkt zum fehlerhaften Code-Commit springen kannst.
5. Session Replay & User Context
replayIntegration
maskAllInputs
User Segments
Session Replay ist eines der mächtigsten Features von Sentry — du siehst genau, was ein Nutzer getan hat, bevor ein Fehler aufgetreten ist. Claude Code konfiguriert Session Replay DSGVO-konform mit allen notwendigen Datenschutz-Einstellungen.
Die Session Replay Integration wird im Client-Config hinzugefügt. Claude Code achtet automatisch auf die richtigen Datenschutz-Einstellungen:
// sentry.client.config.ts — mit Session Replay
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NEXT_PUBLIC_ENVIRONMENT,
// Replay: 10% aller Sessions, 100% bei Errors
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
integrations: [
Sentry.replayIntegration({
// DSGVO-konform: Alle Inputs maskieren
maskAllInputs: true,
maskAllText: false, // Optional: nur sensible Bereiche
// Medien und externe Inhalte blockieren
blockAllMedia: true,
// Spezifische Elemente maskieren (CSS-Selektoren)
mask: [".sensitive-data", "[data-sentry-mask]"],
block: [".payment-iframe", "[data-sentry-block]"],
// Netzwerk-Requests im Replay zeigen
networkDetailAllowUrls: [
window.location.origin,
"https://api.yourapp.com",
],
networkRequestHeaders: ["X-Request-ID", "Content-Type"],
networkResponseHeaders: ["X-Request-ID"],
// Canvas-Recording (z.B. für Diagramme)
recordCanvas: true,
// Sampling-Strategie: Fehler priorisieren
errorSampleRate: 1.0,
}),
Sentry.browserTracingIntegration({
enableInp: true,
}),
],
tunnel: "/monitoring",
});
User-Kontext ist entscheidend, um Fehler dem richtigen Nutzer zuzuordnen. Claude Code erstellt einen React-Hook, der den Sentry-User-Kontext automatisch setzt wenn sich ein Nutzer einloggt:
// hooks/useSentryUser.ts — User-Kontext automatisch setzen
import { useEffect } from "react";
import * as Sentry from "@sentry/nextjs";
import { useSession } from "next-auth/react";
export function useSentryUser(): void {
const { data: session, status } = useSession();
useEffect(() => {
if (status === "authenticated" && session?.user) {
Sentry.setUser({
id: session.user.id,
email: session.user.email ?? undefined,
username: session.user.name ?? undefined,
// Segment für Pricing-Tier (free/pro/enterprise)
segment: session.user.plan,
// Custom Attribute für Business-Analyse
ip_address: "{{auto}}",
});
// Feature-Flags als Tags für A/B-Testing-Korrelation
Sentry.setTag("feature.new_dashboard", String(session.user.features?.newDashboard));
Sentry.setTag("user.plan", session.user.plan);
Sentry.setTag("user.country", session.user.country ?? "unknown");
} else if (status === "unauthenticated") {
// User-Kontext bei Logout entfernen
Sentry.setUser(null);
}
}, [session, status]);
}
// In _app.tsx oder RootLayout verwenden
export function SentryUserProvider({ children }: { children: React.ReactNode }) {
useSentryUser();
return <>{children}</>;
}
💡 DSGVO und Session Replay: Session Replay speichert keine Daten auf eigenen Servern — alles läuft über die Sentry-Infrastruktur. Stelle sicher, dass deine Datenschutzerklärung Session Replay erwähnt und Du SCCs mit Sentry (US-Anbieter) abgeschlossen hast oder eine EU-Sentry-Instanz verwendest.
Für granulare Kontrolle des User-Kontexts in Server Components erstellt Claude Code eine Server-Side-Hilfsfunktion:
// lib/sentry-server.ts — Server-Side User-Kontext
import * as Sentry from "@sentry/nextjs";
import { auth } from "@/auth";
export async function withSentryUser<T>(
fn: () => Promise<T>
): Promise<T> {
const session = await auth();
return Sentry.withIsolationScope(async (scope) => {
if (session?.user) {
scope.setUser({
id: session.user.id,
email: session.user.email ?? undefined,
segment: session.user.plan,
});
}
return fn();
});
}
6. Alerts & Issue Management
Alert Rules
Spike Protection
Slack Integration
Die beste Monitoring-Infrastruktur nutzt nichts, wenn Alerts entweder zu viel Lärm erzeugen oder echte Probleme untergehen. Claude Code hilft dir, eine durchdachte Alert-Strategie zu entwickeln.
Claude Code kann Sentry Alert-Regeln per Terraform oder direkt über die Sentry API konfigurieren. Hier ist eine Terraform-Konfiguration für die wichtigsten Alert-Typen:
# sentry-alerts.tf — Alert-Konfiguration via Terraform
# Provider: https://registry.terraform.io/providers/jianyuan/sentry
resource "sentry_metric_alert" "error_rate_high" {
organization = var.sentry_org
project = var.sentry_project
name = "Error Rate > 5% (Critical)"
query = "is:unresolved"
aggregate = "percentage(sessions_crashed, sessions)"
time_window = 5 # Minuten
threshold_type = 0 # 0 = above, 1 = below
trigger {
label = "critical"
threshold = 5
threshold_type = 0
alert_rule_id = sentry_metric_alert.error_rate_high.id
actions {
type = "slack"
target_type = "specific"
target_identifier = "#alerts-critical"
}
actions {
type = "pagerduty"
target_type = "specific"
target_identifier = "oncall-rotation"
}
}
trigger {
label = "warning"
threshold = 2
threshold_type = 0
alert_rule_id = sentry_metric_alert.error_rate_high.id
actions {
type = "slack"
target_type = "specific"
target_identifier = "#alerts-warning"
}
}
}
Alternativ kannst du Alert-Regeln direkt über die Sentry API konfigurieren. Claude Code erstellt ein TypeScript-Script dafür:
// scripts/setup-sentry-alerts.ts — Programmatische Alert-Konfiguration
const SENTRY_API = "https://sentry.io/api/0";
const HEADERS = {
"Authorization": `Bearer ${process.env.SENTRY_AUTH_TOKEN}`,
"Content-Type": "application/json",
};
interface AlertRule {
name: string;
environment: string;
dataset: "transactions" | "sessions" | "errors";
query: string;
aggregate: string;
timeWindow: number;
triggers: AlertTrigger[];
}
const alerts: AlertRule[] = [
// 1. Performance: p95 Response Time
{
name: "p95 Response Time > 2s",
environment: "production",
dataset: "transactions",
query: "transaction.duration:>0",
aggregate: "p95(transaction.duration)",
timeWindow: 10,
triggers: [
{ label: "critical", threshold: 2000, actions: [{ type: "slack", channel: "#perf-alerts" }] },
{ label: "warning", threshold: 1000, actions: [{ type: "slack", channel: "#perf-alerts" }] },
],
},
// 2. Error Volume Spike
{
name: "Error Spike (> 100 Errors / 5min)",
environment: "production",
dataset: "errors",
query: "is:unresolved level:error",
aggregate: "count()",
timeWindow: 5,
triggers: [
{ label: "critical", threshold: 100, actions: [
{ type: "slack", channel: "#alerts-critical" },
{ type: "email", targetType: "team" },
]},
],
},
// 3. Apdex Score Drop
{
name: "Apdex Score < 0.8",
environment: "production",
dataset: "transactions",
query: "",
aggregate: "apdex(300)",
timeWindow: 15,
triggers: [
{ label: "critical", threshold: 0.6, thresholdType: 1, actions: [
{ type: "slack", channel: "#alerts-critical" },
]},
{ label: "warning", threshold: 0.8, thresholdType: 1, actions: [
{ type: "slack", channel: "#alerts-warning" },
]},
],
},
];
async function createAlerts(): Promise<void> {
const org = process.env.SENTRY_ORG;
const project = process.env.SENTRY_PROJECT;
for (const alert of alerts) {
const response = await fetch(
`${SENTRY_API}/projects/${org}/${project}/alert-rules/`,
{
method: "POST",
headers: HEADERS,
body: JSON.stringify(alert),
}
);
if (!response.ok) {
console.error(`Alert "${alert.name}" fehlgeschlagen:`, await response.text());
} else {
console.log(`✓ Alert "${alert.name}" erstellt`);
}
}
}
createAlerts().catch(console.error);
Issue Ownership: Alerts an die richtigen Teams routen
Sentry's Issue Ownership Rules definieren, welches Team für welchen Code-Bereich verantwortlich ist. Claude Code erstellt eine OWNERS-Datei im Codebase-Format:
# .sentryrc / Issue Ownership Rules
# Format: path/pattern team:slug oder user:email
src/auth/ team:auth-team
src/payments/ team:payments team:security
src/api/v1/ team:backend
src/components/ team:frontend
src/workers/ team:infrastructure
*.css user:design@yourapp.com
# URL-basiertes Routing
url:*/api/payments/* team:payments
url:*/auth/* team:auth-team
url:*/admin/* team:backend
💡 Spike Protection aktivieren: Sentry's Spike Protection verhindert Alert-Floods bei Incidents. Aktiviere sie für alle kritischen Alert-Regeln — sie unterdrückt Duplikat-Alerts für 24 Stunden nach dem ersten Trigger. Das spart Nerven bei 3-Uhr-Incidents.
Claude Code schlägt außerdem vor, einen Incident Response Playbook direkt in Sentry zu verlinken. Über die Slack-Integration wird bei jedem Alert automatisch ein Link zum passenden Runbook mitgesendet:
// Slack Alert mit Runbook-Link (via Sentry Webhook)
const slackAlertTemplate = {
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: "*🚨 Sentry Alert: {{alert_name}}*\n{{alert_message}}",
},
},
{
type: "actions",
elements: [
{
type: "button",
text: { type: "plain_text", text: "Sentry öffnen" },
url: "{{alert_url}}",
style: "danger",
},
{
type: "button",
text: { type: "plain_text", text: "Runbook" },
url: "https://docs.yourapp.com/runbooks/{{alert_slug}}",
},
],
},
],
};
Best Practices für produktionsreifes Alert-Management
- Alert Fatigue vermeiden: Beginne mit wenigen, hochqualitativen Alerts. Lieber 3 Alerts, die immer relevant sind, als 20, die man ignoriert.
- Schwellenwerte datenbasiert setzen: Basiere Thresholds auf historischen Baseline-Daten, nicht auf Bauchgefühl. Sentry zeigt dir in den Alert-Einstellungen den historischen Verlauf.
- On-Call Rotation klar definieren: Nutze PagerDuty oder OpsGenie-Integration für strukturierte On-Call-Rotationen — niemand sollte dauerhaft auf Abruf sein.
- Postmortem-Kultur etablieren: Jeder P0-Incident bekommt ein Postmortem. Sentry's Timeline-Feature hilft dabei, den exakten Verlauf zu rekonstruieren.
- Error Budget tracken: Definiere SLOs (z.B. 99.9% Uptime) und tracke dein Error Budget in Sentry — das gibt eine sachliche Basis für Release-Entscheidungen.
- Regelmäßige Alert-Reviews: Quartalsweise alle Alert-Regeln reviewen: Welche haben nie angeschlagen? Welche lösen ständig False Positives aus?
Fazit: Claude Code als Observability-Architekt
Sentry-Konfiguration auf Production-Level ist in 2026 kein einmaliges Setup mehr, sondern ein kontinuierlicher Prozess: Error-Budget-Tracking, Sampling-Optimierung, neue Integrationen für neue Tech-Stack-Komponenten. Claude Code begleitet diesen Prozess als aktiver Sparringspartner — er kennt die Sentry-Dokumentation, erkennt dein Stack-Setup und generiert typsichere TypeScript-Konfigurationen, die tatsächlich der Sentry-API entsprechen.
Die größten Zeitersparnisse entstehen an Stellen, die oft unterschätzt werden: Source Maps korrekt konfigurieren, die richtigen Sampling-Strategien wählen, Alert-Regeln so aufsetzen, dass sie bei echten Problemen anschlagen — und bei Normalzustand schweigen. Claude Code lernt deinen Stack und liefert Konfigurationen, die nicht nur syntaktisch korrekt sind, sondern semantisch zum Betrieb deiner Anwendung passen.
Quick-Reference: Sentry TypeScript Cheatsheet 2026
| Use Case | API |
| Server-Fehler tracken | Sentry.captureException(err) |
| Mit User-Kontext | Sentry.withScope(scope => { scope.setUser(...); captureException }) |
| Performance-Span | Sentry.startSpan({ name, op }, async (span) => { ... }) |
| Breadcrumb hinzufügen | Sentry.addBreadcrumb({ category, message, level }) |
| User setzen | Sentry.setUser({ id, email, segment }) |
| Tag setzen | Sentry.setTag("key", "value") |
| Info-Message | Sentry.captureMessage("text", "info") |
| Isolation Scope (Server) | Sentry.withIsolationScope(scope => { ... }) |
Observability-Modul im Kurs
Im Claude Code Mastery Kurs: vollständiges Sentry-Modul mit Performance Monitoring, Session Replay, Source Maps und Alert-Konfiguration für produktionsreife Apps.
14 Tage kostenlos testen →