Sentry Monitoring
beginner*Error tracking and performance monitoring with Sentry. Includes source maps and custom context.
monitoringerror-trackingperformancesentry
Tested on⬢20▲16⚛19TS5.9
$ bunx sinew add monitoring/sentry-monitoringInteractive demo coming soon
1The Problem
Production debugging is difficult without:
- Automatic error capture with stack traces
- Performance monitoring and bottleneck detection
- User context for reproducing issues
- Release tracking and regression detection
2The Solution
Sentry provides comprehensive observability with minimal setup.
3Files
sentry.client.config.ts
sentry.client.config.tsTypeScript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Performance monitoring
tracesSampleRate: 1.0,
// Session replay
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
// Environment
environment: process.env.NODE_ENV,
// Filter out known non-issues
ignoreErrors: ["ResizeObserver loop limit exceeded", "Network request failed"],
// Add integrations
integrations: [Sentry.replayIntegration(), Sentry.browserTracingIntegration()],
});sentry.server.config.ts
sentry.server.config.tsTypeScript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Performance monitoring
tracesSampleRate: 1.0,
// Environment
environment: process.env.NODE_ENV,
// Enable profiling
profilesSampleRate: 1.0,
});sentry.edge.config.ts
sentry.edge.config.tsTypeScript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 1.0,
environment: process.env.NODE_ENV,
});next.config.js
next.config.jsJavaScript
import { withSentryConfig } from "@sentry/nextjs";
const nextConfig = {
// Your existing config
};
export default withSentryConfig(nextConfig, {
// Upload source maps for better stack traces
org: "your-org",
project: "your-project",
// Suppress logs during build
silent: true,
// Hide source maps from client
hideSourceMaps: true,
// Automatically instrument
autoInstrumentServerFunctions: true,
autoInstrumentMiddleware: true,
});lib/sentry.ts
lib/sentry.tsTypeScript
import * as Sentry from "@sentry/nextjs";
// Set user context for error tracking
export function setUser(user: { id: string; email: string }) {
Sentry.setUser({
id: user.id,
email: user.email,
});
}
// Clear user on logout
export function clearUser() {
Sentry.setUser(null);
}
// Capture error with context
export function captureError(error: Error, context?: Record<string, unknown>) {
Sentry.captureException(error, {
extra: context,
});
}
// Track custom events
export function trackEvent(name: string, data?: Record<string, unknown>) {
Sentry.captureMessage(name, {
level: "info",
extra: data,
});
}
// Create a transaction for performance monitoring
export function startTransaction(name: string, op: string) {
return Sentry.startSpan({ name, op }, () => {});
}app/global-error.tsx
app/global-error.tsxTypeScript
"use client";
import * as Sentry from "@sentry/nextjs";
import { useEffect } from "react";
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
Sentry.captureException(error);
}, [error]);
return (
<html>
<body>
<div className="flex min-h-screen items-center justify-center">
<div className="text-center">
<h2 className="text-2xl font-bold">Something went wrong!</h2>
<button
onClick={reset}
className="mt-4 rounded bg-blue-500 px-4 py-2 text-white"
>
Try again
</button>
</div>
</div>
</body>
</html>
);
}.env.example
.env.exampleBash
NEXT_PUBLIC_SENTRY_DSN="https://xxx@xxx.ingest.sentry.io/xxx"
SENTRY_AUTH_TOKEN="sntrys_..."
SENTRY_ORG="your-org"
SENTRY_PROJECT="your-project"4Dependencies
$ bun add @sentry/nextjs5Configuration
Sample Rates
// Development: capture everything
tracesSampleRate: 1.0,
// Production: sample for cost efficiency
tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1.0,TypeScript
Filtering Errors
Sentry.init({
beforeSend(event, hint) {
const error = hint.originalException;
// Don't send expected errors
if (error?.message?.includes("Expected error")) {
return null;
}
return event;
},
});TypeScript
6Usage
Manual Error Capture
import { captureError } from "@/lib/sentry";
try {
await riskyOperation();
} catch (error) {
captureError(error as Error, {
operation: "riskyOperation",
userId: user.id,
});
}TypeScript
Performance Monitoring
import * as Sentry from "@sentry/nextjs";
async function processOrder(orderId: string) {
return Sentry.startSpan({ name: "processOrder", op: "task" }, async () => {
// Your code here
await chargePayment(orderId);
await sendConfirmation(orderId);
});
}TypeScript
Set User Context
// On login
import { setUser } from "@/lib/sentry";
async function onLogin(user: User) {
setUser({ id: user.id, email: user.email });
}TypeScript
7Troubleshooting
Source maps not working
- Check that
SENTRY_AUTH_TOKENis set during build - Verify org and project names are correct
- Ensure
hideSourceMaps: trueis set for security
Too many events
- Reduce
tracesSampleRatefor production - Add error filters in
beforeSend - Use
ignoreErrorsfor known non-issues