Sentry mit Claude Code: Error Monitoring und Performance 2026
Sentry ist das führende Open-Source-Error-Monitoring-Tool — und Claude Code kennt das gesamte SDK in- und auswendig. Von SDK-Setup über Error Capturing und Performance Tracing bis zu Source Maps, User Context und Alert-Konfiguration: Claude Code richtet vollständiges Sentry-Monitoring für Next.js und Node.js in Minuten ein.
Warum Sentry + Claude Code?
| Feature | Ohne Monitoring | Mit Sentry + Claude Code |
|---|---|---|
| Fehler-Discovery | Nutzer-Beschwerden | Sofortiger Alert mit Stack Trace |
| Performance-Probleme | Erst nach Beschwerden sichtbar | Transaction Tracing in Echtzeit |
| Release-Qualität | Unbekannt bis Prod-Feedback | Error-Rate pro Release vergleichen |
| Debugging-Zeit | Stunden (keine Kontext-Daten) | Minuten (Breadcrumbs + User-Context) |
| Source Map Support | Minifizierte Stack Traces unlesbar | Original-Sourcecode im Stack Trace |
| Setup-Aufwand | — | ~15 Minuten mit Claude Code |
1. Setup für Next.js
SetupSDK installieren und konfigurieren
# Prompt: "Richte Sentry für unser Next.js 14 Projekt ein, mit DSN, Tunnel und Source Maps"
# Installation:
npx @sentry/wizard@latest -i nextjs
# Alternativ manuell:
npm install @sentry/nextjs
# Wizard erstellt automatisch:
# sentry.client.config.ts → Browser-Errors
# sentry.server.config.ts → Server-Errors (SSR, API Routes)
# sentry.edge.config.ts → Edge Runtime (Middleware)
# next.config.js → withSentryConfig Wrapper
// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Tunnel verhindert Ad-Blocker-Blockierung:
tunnel: '/api/sentry-tunnel',
// Performance Tracing:
tracesSampleRate: 0.1, // 10% aller Requests tracen
tracePropagationTargets: [
'localhost',
/^https:\/\/api\.myapp\.com/,
],
// Session Replay (optional):
replaysSessionSampleRate: 0.05, // 5% aller Sessions
replaysOnErrorSampleRate: 1.0, // 100% bei Errors
integrations: [
Sentry.replayIntegration({
maskAllText: true, // DSGVO: Texte maskieren
blockAllMedia: false,
}),
],
// Environment-Tag:
environment: process.env.NODE_ENV,
// Release-Tracking (von CI gesetzt):
release: process.env.NEXT_PUBLIC_SENTRY_RELEASE,
});
// sentry.server.config.ts
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.SENTRY_DSN, // Server-seitig: kein NEXT_PUBLIC_ Prefix
tracesSampleRate: 0.2, // Server-Traces: 20%
// Node.js spezifische Integrationen:
integrations: [
Sentry.prismaIntegration(), // Prisma Query Tracing
Sentry.httpIntegration({
tracing: true,
}),
],
// PII-Schutz:
sendDefaultPii: false,
environment: process.env.NODE_ENV,
});
// next.config.ts — withSentryConfig Wrapper
import { withSentryConfig } from '@sentry/nextjs';
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
// ... deine bestehende Next.js Config
};
export default withSentryConfig(nextConfig, {
org: 'my-org',
project: 'my-nextjs-app',
// Source Maps automatisch hochladen:
silent: true,
widenClientFileUpload: true,
// Tree-shaking für kleineres Bundle:
disableLogger: true,
// Tunnel-Route automatisch erstellen:
tunnelRoute: '/api/sentry-tunnel',
// Source Maps nach Upload löschen (kein Leak in Deploy-Artefakten):
sourcemaps: {
deleteSourcemapsAfterUpload: true,
},
});
DSN-Sicherheit: Für den Browser ist der DSN öffentlich (NEXT_PUBLIC_SENTRY_DSN) — das ist by Design, Sentry-DSNs sind keine Secrets. Der Tunnel unter
/api/sentry-tunnel leitet Browser-Events serverseitig weiter und umgeht Ad-Blocker zuverlässig.2. Error Capturing
ErrorcaptureException, captureMessage und withScope
// Prompt: "Zeig mir alle Sentry Error-Capturing Methoden mit Best Practices"
import * as Sentry from '@sentry/nextjs';
// 1. Exception fangen (Standard — am häufigsten verwendet):
try {
await processPayment(orderId);
} catch (error) {
Sentry.captureException(error);
throw error; // Error weiterwerfen für UI-Handling
}
// 2. Manuell eine Nachricht senden (kein Exception-Objekt):
Sentry.captureMessage('Checkout ohne Produkt aufgerufen', 'warning');
// Severity-Levels: 'fatal' | 'error' | 'warning' | 'info' | 'debug'
// 3. withScope — temporärer Kontext für einen einzelnen Event:
Sentry.withScope((scope) => {
scope.setTag('payment.provider', 'stripe');
scope.setExtra('orderId', orderId);
scope.setExtra('amount', amount);
scope.setLevel('fatal');
Sentry.captureException(error);
});
// 4. Breadcrumbs — Spur vor dem Fehler hinterlassen:
Sentry.addBreadcrumb({
message: 'User hat Checkout-Seite aufgerufen',
category: 'navigation',
level: 'info',
data: {
cartItems: cart.length,
totalValue: cart.reduce((s, i) => s + i.price, 0),
},
});
Sentry.addBreadcrumb({
message: 'Payment API aufgerufen',
category: 'http',
level: 'info',
data: { endpoint: '/api/stripe/charge', method: 'POST' },
});
// Next.js API Route — vollständiges Error Handling Pattern:
// app/api/orders/route.ts
import { NextRequest, NextResponse } from 'next/server';
import * as Sentry from '@sentry/nextjs';
export async function POST(req: NextRequest) {
return await Sentry.withServerActionInstrumentation(
'createOrder',
{ recordResponse: true },
async () => {
try {
const body = await req.json();
const order = await createOrder(body);
return NextResponse.json(order);
} catch (error) {
Sentry.captureException(error, {
tags: { api: 'orders', method: 'POST' },
});
return NextResponse.json(
{ error: 'Order creation failed' },
{ status: 500 }
);
}
}
);
}
// React Error Boundary (Client Component):
// app/error.tsx — wird automatisch von Sentry instrumentiert
'use client';
import * as Sentry from '@sentry/nextjs';
import { useEffect } from 'react';
export default function Error({
error, reset,
}: { error: Error & { digest?: string }; reset: () => void }) {
useEffect(() => {
Sentry.captureException(error);
}, [error]);
return (
<div>
<h2>Etwas ist schiefgelaufen!</h2>
<button onClick={() => reset()}>Nochmal versuchen</button>
</div>
);
}
Global Error Handler für Next.js:
app/global-error.tsx ist der Root Error Boundary — dieser fängt auch Layout-Errors. Sentry instrumentiert ihn automatisch wenn der Wizard genutzt wird. Claude Code fügt den Sentry-Import und captureException korrekt ein.3. Performance Tracing
PerfstartSpan, Custom Transactions und tracesSampleRate
// Prompt: "Implementiere Performance Tracing für unsere kritischen Business-Prozesse"
import * as Sentry from '@sentry/nextjs';
// 1. startSpan — misst die Dauer einer Operation:
const result = await Sentry.startSpan(
{
name: 'checkout.processPayment',
op: 'payment',
attributes: {
'payment.provider': 'stripe',
'order.items_count': cart.length,
},
},
async (span) => {
span.setAttribute('order.id', orderId);
const charge = await stripe.charges.create({ ... });
span.setAttribute('payment.status', charge.status);
return charge;
}
);
// 2. Verschachtelte Spans (Tracing-Tree):
await Sentry.startSpan({ name: 'user.register', op: 'function' }, async () => {
// Jeder DB-Call wird als Child-Span getrackt:
await Sentry.startSpan({ name: 'db.createUser', op: 'db.query' }, async () => {
return prisma.user.create({ data: userData });
});
await Sentry.startSpan({ name: 'email.sendWelcome', op: 'http.client' }, async () => {
return sendWelcomeEmail(userData.email);
});
});
// 3. Sampling-Strategie — nach Route differenzieren:
Sentry.init({
tracesSampler: (samplingContext) => {
const { name } = samplingContext;
// Health Checks NIE tracen:
if (name.includes('GET /api/health')) return 0;
// Checkout-Flow IMMER tracen (business-kritisch):
if (name.includes('/checkout')) return 1.0;
// Admin-Bereich: 50%
if (name.includes('/admin')) return 0.5;
// Standard: 10%
return 0.1;
},
});
// 4. Web Vitals automatisch tracen (Next.js Integration):
// app/layout.tsx — Sentry trackt CLS, LCP, FID, TTFB automatisch
// 5. Manuelle Web Vitals für Custom Metrics:
import { onCLS, onFID, onLCP, onFCP, onTTFB } from 'web-vitals';
function reportWebVital({ name, value, id }: WebVitalsMetric) {
Sentry.getCurrentScope().getTransaction()?.setMeasurement(
name.toLowerCase(),
value,
name === 'CLS' ? '' : 'millisecond'
);
}
onCLS(reportWebVital);
onFID(reportWebVital);
onLCP(reportWebVital);
// 6. Performance Dashboard — welche Seiten sind langsam?
// Sentry → Performance → Slow DB Queries zeigt automatisch:
// - P50, P75, P95, P99 Latenz pro Route
// - Slowest DB Queries (mit Prisma Integration)
// - Throughput (req/min) pro Endpoint
Sampling-Kosten: tracesSampleRate: 1.0 in Production kann schnell teuer werden. Sentry berechnet Performance-Events separat. Claude Code berechnet auf Anfrage die optimale Sample-Rate anhand deines Traffic-Volumens und Sentry-Plan-Limits.
4. Source Maps
ReleaseuploadSourcemaps, Releases und getReleaseName
// Prompt: "Konfiguriere Source Map Upload für lesbare Stack Traces in Production"
// next.config.ts — Source Maps via withSentryConfig (empfohlen):
export default withSentryConfig(nextConfig, {
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN, // NUR serverseitig, nie im Browser!
sourcemaps: {
// Source Maps hochladen und dann aus dem Deploy entfernen:
deleteSourcemapsAfterUpload: true, // Kein Leak in public/_next/static
disable: process.env.NODE_ENV !== 'production',
},
release: {
// Release-Name: automatisch aus Git-SHA generieren:
create: true,
finalize: true,
deploy: {
env: process.env.SENTRY_ENVIRONMENT || 'production',
},
},
});
# Manueller Source Map Upload (ohne Next.js Wizard):
# Für Node.js oder andere Frameworks:
# 1. Build mit Source Maps:
npm run build
# 2. Release-Name aus Git-SHA:
RELEASE=$(sentry-cli releases propose-version)
echo "Release: $RELEASE"
# 3. Release erstellen:
sentry-cli releases new "$RELEASE"
sentry-cli releases set-commits --auto "$RELEASE"
# 4. Source Maps hochladen:
sentry-cli sourcemaps inject ./dist
sentry-cli sourcemaps upload ./dist \
--release="$RELEASE" \
--url-prefix="~/"
# 5. Deploy taggen:
sentry-cli releases finalize "$RELEASE"
sentry-cli releases deploys "$RELEASE" new \
--env production
// getReleaseName() für konsistente Release-Benennung:
// release-utils.ts
import { execSync } from 'child_process';
export function getReleaseName(): string {
const gitSha = process.env.GIT_SHA ||
execSync('git rev-parse --short HEAD')
.toString().trim();
const version = process.env.npm_package_version || '0.0.0';
const env = process.env.NODE_ENV || 'development';
return `my-app@${version}+${gitSha}-${env}`;
// Beispiel: "my-app@2.1.0+a3f8d21-production"
}
// In sentry.*.config.ts verwenden:
import { getReleaseName } from './release-utils';
Sentry.init({
release: getReleaseName(),
// ...
});
# GitHub Actions — Source Maps im CI/CD:
# .github/workflows/deploy.yml
jobs:
deploy:
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Wichtig: volle Git History für Commits
- name: Build
run: npm run build
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ vars.SENTRY_ORG }}
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }}
GIT_SHA: ${{ github.sha }}
# Source Maps werden automatisch von withSentryConfig hochgeladen
SENTRY_AUTH_TOKEN Sicherheit: Der Auth Token darf NIEMALS im Client-Bundle landen. Er wird nur beim Build-Prozess gebraucht (für den Upload) und kommt aus CI-Secrets oder .env.local. Claude Code prüft das automatisch und warnt wenn der Token versehentlich als NEXT_PUBLIC_ Variable gesetzt wird.
5. User Context und Enrichment
ContextsetUser, setTag, setExtra und addBreadcrumb
// Prompt: "Reichere Sentry Events mit User-Kontext an — DSGVO-konform"
import * as Sentry from '@sentry/nextjs';
// 1. User setzen (nach Login):
Sentry.setUser({
id: user.id, // PFLICHT: eindeutige ID
email: user.email, // Optional — prüfe DSGVO
username: user.displayName,
// Eigene Felder möglich:
plan: user.subscriptionTier, // 'free' | 'pro' | 'enterprise'
companyId: user.companyId,
});
// 2. User leeren (nach Logout):
Sentry.setUser(null);
// 3. Tags — indexiert, filterbar, für Alerting nutzbar:
Sentry.setTag('feature.flag', 'checkout-v2');
Sentry.setTag('api.version', 'v3');
Sentry.setTag('db.region', 'eu-west-1');
// 4. Extra-Daten — nicht indexiert, nur für Debugging:
Sentry.setExtra('requestPayload', JSON.stringify(payload));
Sentry.setExtra('redisKeyCount', redisKeys.length);
// 5. Context-Objekte — strukturierter als setExtra:
Sentry.setContext('order', {
id: order.id,
status: order.status,
itemCount: order.items.length,
total: order.total,
currency: order.currency,
});
Sentry.setContext('infrastructure', {
region: process.env.AWS_REGION,
instanceType: process.env.INSTANCE_TYPE,
deployedAt: process.env.DEPLOY_TIMESTAMP,
});
// 6. Breadcrumbs — automatische + manuelle Spur:
// Automatisch getrackt von Sentry (ohne Code):
// ✅ fetch/XMLHttpRequest Calls
// ✅ console.log/warn/error Aufrufe
// ✅ Navigation Events (next/router)
// ✅ User Interaktionen (Clicks, Inputs)
// Manuell hinzufügen:
Sentry.addBreadcrumb({
category: 'auth',
message: 'User hat 2FA aktiviert',
level: 'info',
timestamp: Date.now() / 1000,
data: { method: 'totp' },
});
Sentry.addBreadcrumb({
category: 'db',
message: 'Migration gestartet',
level: 'warning',
data: { migrationId: '20260505_add_index' },
});
// 7. beforeSend — Events filtern oder anreichern bevor sie Sentry erreichen:
Sentry.init({
beforeSend(event, hint) {
// Bekannte harmlose Errors ignorieren:
const error = hint.originalException as Error;
if (error?.message?.includes('ResizeObserver loop')) {
return null; // Nicht senden
}
// Sensible Daten aus Stack Trace entfernen:
if (event.request?.data) {
delete event.request.data.password;
delete event.request.data.creditCard;
}
return event;
},
});
DSGVO und Sentry: Wenn User-E-Mails als PII gelten, kann
sendDefaultPii: false in der Init-Config die automatische IP-Erfassung und Cookie-Tracking deaktivieren. Claude Code erstellt auf Anfrage eine DSGVO-konforme Sentry-Konfiguration mit Data Scrubbing und Datenlokalierung (EU-Region).6. Alerts und Dashboards
AlertIssue Alerts, Performance Alerts und Custom Metrics
// Prompt: "Erkläre mir wie ich Sentry Alerts für unsere KPIs konfiguriere"
// ALERT-TYPEN in Sentry:
// ─────────────────────────────────────────────────────────────────
// Issue Alerts → basierend auf Error-Events (neue/regressive Issues)
// Metric Alerts → basierend auf Zahlen (error rate, latenz, custom)
// Uptime Alerts → HTTP Health Check Monitoring
// Cron Alerts → Scheduled Jobs überwachen
// ─────────────────────────────────────────────────────────────────
// Issue Alert — per sentry-cli oder API konfigurieren:
# sentry-cli / Sentry API: Alert-Regel erstellen
# Wichtige Issue Alert-Trigger:
# - "A new issue is created" → sofort Slack
# - "The issue is seen more than 100 times/hour" → P0 PagerDuty
# - "A previously resolved issue re-appears" → regression Alert
# - "The issue affects more than 50 users" → VIP Alert
// Custom Metrics — eigene Business-Metriken tracken:
import * as Sentry from '@sentry/nextjs';
// Counter — einfache Ereigniszählung:
Sentry.metrics.increment('checkout.started', 1, {
tags: { plan: user.plan, country: user.country },
});
Sentry.metrics.increment('checkout.completed');
Sentry.metrics.increment('checkout.abandoned');
// Distribution — Werte mit Verteilung (Latenzen, Beträge):
Sentry.metrics.distribution('payment.amount_eur', orderTotal, {
unit: 'euro',
tags: { currency: 'EUR', plan: user.plan },
});
Sentry.metrics.distribution('db.query_time', queryDurationMs, {
unit: 'millisecond',
tags: { table: 'orders', operation: 'SELECT' },
});
// Gauge — aktueller Zustand (Queue-Länge, aktive Sessions):
Sentry.metrics.gauge('queue.depth', jobQueue.length, {
tags: { worker: 'email-processor' },
});
// Set — einzigartige Werte zählen (Unique Users):
Sentry.metrics.set('feature.users', userId, {
tags: { feature: 'dark-mode' },
});
// Cron Monitoring — Scheduled Jobs überwachen:
// Wenn ein Job nicht läuft → sofort Alert
import * as Sentry from '@sentry/nextjs';
async function nightlyEmailDigest() {
const checkInId = Sentry.captureCheckIn(
{
monitorSlug: 'nightly-email-digest',
status: 'in_progress',
},
{
schedule: {
type: 'crontab',
value: '0 3 * * *', // Täglich 3:00 Uhr
},
checkinMargin: 5, // 5 Min Toleranz
maxRuntime: 30, // Max 30 Min
timezone: 'Europe/Berlin',
}
);
try {
await sendEmailsToAllUsers();
Sentry.captureCheckIn({ monitorSlug: 'nightly-email-digest', checkInId, status: 'ok' });
} catch (err) {
Sentry.captureCheckIn({ monitorSlug: 'nightly-email-digest', checkInId, status: 'error' });
throw err;
}
}
// Uptime Monitor — HTTP Endpoint Health Check:
// Sentry → Alerts → Uptime → Monitor erstellen
// URL: https://myapp.com/api/health
// Intervall: 1 Minute
// Timeout: 5 Sekunden
// Alert wenn: 2 von 3 Checks schlagen fehl
// Slack Integration — Alerts in den richtigen Channel:
// Sentry → Settings → Integrations → Slack
// Empfohlene Alert-Routing-Strategie:
// #alerts-critical → error_rate > 5%, neue P0-Issues
// #alerts-performance → P95 Latenz > 2s, Apdex < 0.8
// #alerts-weekly → Wöchentliches Summary Digest
// Sentry Dashboards — wichtige Widgets:
// 1. Error Rate über Zeit (Issue Volume Chart)
// 2. Top 10 Errors nach Häufigkeit
// 3. P50/P95 Latenz pro API Route
// 4. Apdex Score (User Satisfaction Index)
// 5. Checkout Conversion Rate (Custom Metric)
// 6. Cron Job Status Overview
Sentry Workflow mit Claude Code: Beschreibe Claude Code deinen Alert-Bedarf auf Deutsch: "Wir brauchen einen Alert wenn die Checkout-Error-Rate über 2% steigt, einen weiteren wenn der Nightly Job nicht läuft, und ein Dashboard mit unseren Business-KPIs." Claude Code liefert die komplette Konfiguration — Slack-Integration, Metric Alerts, Cron Monitor und Dashboard-Widgets.
Sentry in Node.js ohne Next.js
Node.jsExpress / Fastify / Standalone Setup
// Prompt: "Richte Sentry für unsere Express API ein"
// instrument.ts — MUSS als ERSTES importiert werden (vor allem anderen)!
// Node.js --require Flag nutzen, kein normaler Import
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 0.1,
environment: process.env.NODE_ENV,
integrations: [
Sentry.httpIntegration({ tracing: true }),
Sentry.expressIntegration(), // Express spezifisch
Sentry.prismaIntegration(), // Prisma Query Tracing
Sentry.redisIntegration(), // Redis Command Tracing
],
});
// package.json start script:
// "start": "node --require ./instrument.js dist/server.js"
// server.ts — NACH instrument.ts laden:
import './instrument';
import express from 'express';
import * as Sentry from '@sentry/node';
const app = express();
// Sentry Request Handler (GANZ OBEN in Middleware-Stack):
app.use(Sentry.expressErrorHandler());
// ... deine Routes ...
// Sentry Error Handler (GANZ UNTEN — nach allen Routes):
app.use(Sentry.expressErrorHandler());
Claude Code Prompts für Sentry
PromptsDie effektivsten Sentry-Prompts für Claude Code
# Setup-Prompts:
"Richte Sentry für unser Next.js 14 App Router Projekt ein: DSN aus .env,
Tunnel gegen Ad-Blocker, Source Map Upload in CI, DSGVO-konformes User Context"
"Zeig mir den Unterschied zwischen sentry.client.config.ts und
sentry.server.config.ts — was gehört wohin?"
# Error Handling-Prompts:
"Füge Sentry Error Capturing zu allen unseren API Routes hinzu —
mit Tags, Extra-Daten und Breadcrumbs"
"Erstelle einen beforeSend Handler der DSGVO-sensible Felder filtert:
password, email, creditCard, iban"
# Performance-Prompts:
"Implementiere Performance Tracing für unseren Checkout-Flow —
jeden Step als eigenen Span mit Business-Attributen"
"Konfiguriere tracesSampler der Checkout-Flows mit 100% und
Health-Checks mit 0% samplet"
# Alert-Prompts:
"Erkläre mir wie ich einen Metric Alert für error_rate > 2%
in Sentry konfiguriere und in Slack #alerts-critical poste"
"Richte Cron Monitoring für alle unsere scheduled Jobs ein —
Daily Digest, Weekly Report, DB Backup"
# Debugging-Prompts:
"Dieser Sentry Stack Trace ist minifiziert — was muss ich am
Source Map Upload ändern damit ich Original-Code sehe?"
"Analysiere diesen Sentry Event: [Event einfügen] — was ist
die wahrscheinliche Root Cause?"
Monitoring-Modul im Kurs
Im Claude Code Mastery Kurs: vollständiges Monitoring-Modul mit Sentry Setup für Next.js und Node.js, Error Capturing Patterns, Performance Tracing, Source Maps CI/CD Integration, DSGVO-konformes User Context, Alert-Konfiguration und Custom Metrics — inkl. Slack und PagerDuty Anbindung.
14 Tage kostenlos testen →