sentry-and-otel-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Sentry and OpenTelemetry Setup

Sentry和OpenTelemetry设置

Overview

概述

Configure comprehensive error tracking and performance monitoring using Sentry with OpenTelemetry (OTel) instrumentation for Next.js applications, including automatic error capture, distributed tracing, and custom logging.
为Next.js应用配置基于Sentry与OpenTelemetry(OTel)工具的全面错误追踪和性能监控,包括自动错误捕获、分布式追踪和自定义日志功能。

Installation and Configuration

安装与配置

1. Install Sentry

1. 安装Sentry

Install Sentry Next.js SDK:
bash
npm install @sentry/nextjs
Run Sentry wizard for automatic configuration:
bash
npx @sentry/wizard@latest -i nextjs
This creates:
  • sentry.client.config.ts
    - Client-side configuration
  • sentry.server.config.ts
    - Server-side configuration
  • sentry.edge.config.ts
    - Edge runtime configuration
  • instrumentation.ts
    - OpenTelemetry setup
  • Updates
    next.config.js
    with Sentry webpack plugin
安装Sentry Next.js SDK:
bash
npm install @sentry/nextjs
运行Sentry向导进行自动配置:
bash
npx @sentry/wizard@latest -i nextjs
此操作会生成:
  • sentry.client.config.ts
    - 客户端配置文件
  • sentry.server.config.ts
    - 服务端配置文件
  • sentry.edge.config.ts
    - Edge运行时配置文件
  • instrumentation.ts
    - OpenTelemetry设置文件
  • 更新
    next.config.js
    ,添加Sentry webpack插件

2. Configure Environment Variables

2. 配置环境变量

Add Sentry credentials to
.env.local
:
env
SENTRY_DSN=https://your-dsn@sentry.io/project-id
SENTRY_ORG=your-org
SENTRY_PROJECT=your-project
NEXT_PUBLIC_SENTRY_DSN=https://your-dsn@sentry.io/project-id
Get DSN from Sentry dashboard: Settings > Projects > [Your Project] > Client Keys (DSN)
For production, add these to deployment environment variables.
.env.local
中添加Sentry凭证:
env
SENTRY_DSN=https://your-dsn@sentry.io/project-id
SENTRY_ORG=your-org
SENTRY_PROJECT=your-project
NEXT_PUBLIC_SENTRY_DSN=https://your-dsn@sentry.io/project-id
从Sentry控制台获取DSN:设置 > 项目 > [你的项目] > 客户端密钥(DSN)
生产环境中,请将这些变量添加到部署环境变量中。

3. Update Sentry Configurations

3. 更新Sentry配置

Customize
sentry.server.config.ts
using the template from
assets/sentry-server-config.ts
:
  • Set environment (development, staging, production)
  • Configure sample rates for performance monitoring
  • Enable tracing for Server Actions and API routes
  • Set up error filtering and breadcrumbs
Customize
sentry.client.config.ts
using the template from
assets/sentry-client-config.ts
:
  • Configure replay sessions for debugging
  • Set error boundaries
  • Enable performance monitoring for user interactions
使用
assets/sentry-server-config.ts
中的模板自定义
sentry.server.config.ts
  • 设置环境(开发、预发布、生产)
  • 配置性能监控的采样率
  • 启用Server Actions和API路由的追踪
  • 设置错误过滤和面包屑追踪
使用
assets/sentry-client-config.ts
中的模板自定义
sentry.client.config.ts
  • 配置用于调试的会话重放
  • 设置错误边界
  • 启用用户交互的性能监控

4. Add Instrumentation Hook

4. 添加工具初始化钩子

Create or update
instrumentation.ts
in project root using the template from
assets/instrumentation.ts
. This:
  • Initializes OpenTelemetry before app starts
  • Registers Sentry as trace provider
  • Enables distributed tracing across services
  • Runs only once on server startup
Note: Requires
experimental.instrumentationHook
in
next.config.js
(added by Sentry wizard).
使用
assets/instrumentation.ts
中的模板在项目根目录创建或更新
instrumentation.ts
。该文件会:
  • 在应用启动前初始化OpenTelemetry
  • 注册Sentry作为追踪提供者
  • 启用跨服务的分布式追踪
  • 仅在服务端启动时运行一次
注意:需要在
next.config.js
中开启
experimental.instrumentationHook
(Sentry向导会自动添加)。

5. Create Logging Wrapper

5. 创建日志包装器

Create
lib/logger.ts
using the template from
assets/logger.ts
. This provides:
  • Structured logging with context
  • Automatic Sentry integration
  • Different log levels (debug, info, warn, error)
  • Request context capture
Use instead of
console.log
for better debugging:
typescript
import { logger } from '@/lib/logger';

logger.info('User logged in', { userId: user.id });
logger.error('Failed to save data', { error, userId });
使用
assets/logger.ts
中的模板创建
lib/logger.ts
。该文件提供:
  • 带上下文的结构化日志
  • 自动集成Sentry
  • 不同日志级别(debug、info、warn、error)
  • 请求上下文捕获
替代
console.log
以获得更好的调试体验:
typescript
import { logger } from '@/lib/logger';

logger.info('用户已登录', { userId: user.id });
logger.error('数据保存失败', { error, userId });

6. Add Error Boundary (Client Components)

6. 添加错误边界(客户端组件)

Create
components/error-boundary.tsx
using the template from
assets/error-boundary.tsx
. This:
  • Catches React errors in client components
  • Sends errors to Sentry
  • Shows fallback UI
  • Provides error recovery
Use in layouts or pages:
typescript
import { ErrorBoundary } from '@/components/error-boundary';

export default function Layout({ children }) {
  return (
    <ErrorBoundary>
      {children}
    </ErrorBoundary>
  );
}
使用
assets/error-boundary.tsx
中的模板创建
components/error-boundary.tsx
。该组件会:
  • 捕获客户端组件中的React错误
  • 将错误发送至Sentry
  • 显示降级UI
  • 提供错误恢复功能
在布局或页面中使用:
typescript
import { ErrorBoundary } from '@/components/error-boundary';

export default function Layout({ children }) {
  return (
    <ErrorBoundary>
      {children}
    </ErrorBoundary>
  );
}

7. Create Custom Error Page

7. 创建自定义错误页面

Update
app/error.tsx
using the template from
assets/error-page.tsx
. This:
  • Shows user-friendly error messages
  • Captures errors in Server Components
  • Provides retry functionality
  • Sends errors to Sentry
使用
assets/error-page.tsx
中的模板更新
app/error.tsx
。该页面会:
  • 显示用户友好的错误信息
  • 捕获服务端组件中的错误
  • 提供重试功能
  • 将错误发送至Sentry

8. Add Global Error Handler

8. 添加全局错误处理器

Update
app/global-error.tsx
using the template from
assets/global-error.tsx
. This:
  • Catches errors in root layout
  • Last resort error boundary
  • Required for catching layout errors
使用
assets/global-error.tsx
中的模板更新
app/global-error.tsx
。该处理器会:
  • 捕获根布局中的错误
  • 作为最后的错误边界
  • 是捕获布局错误的必需配置

Tracing Server Actions

追踪Server Actions

Manual Instrumentation

手动工具集成

Wrap Server Actions with Sentry tracing:
typescript
'use server';

import { logger } from '@/lib/logger';
import * as Sentry from '@sentry/nextjs';

export async function createPost(formData: FormData) {
  return await Sentry.startSpan(
    { name: 'createPost', op: 'server.action' },
    async () => {
      try {
        const title = formData.get('title') as string;

        logger.info('Creating post', { title });

        // Your logic here
        const post = await prisma.post.create({
          data: { title, content: '...' },
        });

        logger.info('Post created', { postId: post.id });
        return { success: true, post };

      } catch (error) {
        logger.error('Failed to create post', { error });
        Sentry.captureException(error);
        throw error;
      }
    }
  );
}
使用Sentry追踪包装Server Actions:
typescript
'use server';

import { logger } from '@/lib/logger';
import * as Sentry from '@sentry/nextjs';

export async function createPost(formData: FormData) {
  return await Sentry.startSpan(
    { name: 'createPost', op: 'server.action' },
    async () => {
      try {
        const title = formData.get('title') as string;

        logger.info('正在创建文章', { title });

        // 你的业务逻辑
        const post = await prisma.post.create({
          data: { title, content: '...' },
        });

        logger.info('文章创建完成', { postId: post.id });
        return { success: true, post };

      } catch (error) {
        logger.error('文章创建失败', { error });
        Sentry.captureException(error);
        throw error;
      }
    }
  );
}

Automatic Instrumentation

自动工具集成

Sentry automatically instruments:
  • Next.js API routes
  • Server Components (partial)
  • Fetch requests
  • Database queries (with OTel)
Sentry会自动集成以下内容:
  • Next.js API路由
  • 服务端组件(部分支持)
  • Fetch请求
  • 数据库查询(需配合OTel)

Monitoring Patterns

监控模式

1. Capture User Context

1. 捕获用户上下文

Associate errors with users:
typescript
import * as Sentry from '@sentry/nextjs';
import { getCurrentUser } from '@/lib/auth/utils';

export async function setUserContext() {
  const user = await getCurrentUser();

  if (user) {
    Sentry.setUser({
      id: user.id,
      email: user.email,
    });
  }
}
Call in layouts or middleware to track user context globally.
将错误与用户关联:
typescript
import * as Sentry from '@sentry/nextjs';
import { getCurrentUser } from '@/lib/auth/utils';

export async function setUserContext() {
  const user = await getCurrentUser();

  if (user) {
    Sentry.setUser({
      id: user.id,
      email: user.email,
    });
  }
}
在布局或中间件中调用,以全局追踪用户上下文。

2. Add Custom Tags

2. 添加自定义标签

Tag errors for filtering:
typescript
Sentry.setTag('feature', 'worldbuilding');
Sentry.setTag('entity_type', 'character');

// Now errors are tagged and filterable in Sentry dashboard
为错误添加标签以便过滤:
typescript
Sentry.setTag('feature', 'worldbuilding');
Sentry.setTag('entity_type', 'character');

// 现在可以在Sentry控制台中通过标签过滤错误

3. Add Breadcrumbs

3. 添加面包屑

Track user actions leading to errors:
typescript
Sentry.addBreadcrumb({
  category: 'user_action',
  message: 'User clicked create entity',
  level: 'info',
  data: {
    entityType: 'character',
    worldId: 'world-123',
  },
});
追踪错误发生前的用户操作:
typescript
Sentry.addBreadcrumb({
  category: 'user_action',
  message: '用户点击创建实体',
  level: 'info',
  data: {
    entityType: 'character',
    worldId: 'world-123',
  },
});

4. Performance Monitoring

4. 性能监控

Track custom operations:
typescript
import * as Sentry from '@sentry/nextjs';

export async function complexOperation() {
  const transaction = Sentry.startTransaction({
    name: 'Complex World Generation',
    op: 'task',
  });

  // Step 1
  const span1 = transaction.startChild({
    op: 'generate.terrain',
    description: 'Generate terrain data',
  });
  await generateTerrain();
  span1.finish();

  // Step 2
  const span2 = transaction.startChild({
    op: 'generate.biomes',
    description: 'Generate biome data',
  });
  await generateBiomes();
  span2.finish();

  transaction.finish();
}
追踪自定义操作:
typescript
import * as Sentry from '@sentry/nextjs';

export async function complexOperation() {
  const transaction = Sentry.startTransaction({
    name: '复杂世界生成',
    op: 'task',
  });

  // 步骤1
  const span1 = transaction.startChild({
    op: 'generate.terrain',
    description: '生成地形数据',
  });
  await generateTerrain();
  span1.finish();

  // 步骤2
  const span2 = transaction.startChild({
    op: 'generate.biomes',
    description: '生成生物群系数据',
  });
  await generateBiomes();
  span2.finish();

  transaction.finish();
}

5. Database Query Tracing

5. 数据库查询追踪

Prisma automatically integrates with OTel:
typescript
// Queries are automatically traced if OTel is configured
const users = await prisma.user.findMany();
// Shows up in Sentry as a database span
Prisma会自动与OTel集成:
typescript
// 若已配置OTel,查询会被自动追踪
const users = await prisma.user.findMany();
// 会在Sentry中显示为数据库追踪 span

Configuration Options

配置选项

Sample Rates

采样率

Control how many events are sent to Sentry (avoid quota limits):
typescript
// sentry.server.config.ts
Sentry.init({
  dsn: process.env.SENTRY_DSN,

  // Percentage of errors to capture (1.0 = 100%)
  sampleRate: 1.0,

  // Percentage of transactions to trace
  tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,

  // Percentage of sessions to replay
  replaysSessionSampleRate: 0.1,

  // Percentage of error sessions to replay
  replaysOnErrorSampleRate: 1.0,
});
控制发送到Sentry的事件数量(避免配额超限):
typescript
// sentry.server.config.ts
Sentry.init({
  dsn: process.env.SENTRY_DSN,

  // 错误捕获比例(1.0 = 100%)
  sampleRate: 1.0,

  // 事务追踪比例
  tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,

  // 会话重放比例
  replaysSessionSampleRate: 0.1,

  // 错误会话的重放比例
  replaysOnErrorSampleRate: 1.0,
});

Environment Detection

环境检测

Configure different settings per environment:
typescript
Sentry.init({
  environment: process.env.NODE_ENV,
  enabled: process.env.NODE_ENV !== 'development', // Disable in dev

  beforeSend(event, hint) {
    // Filter out specific errors
    if (event.exception?.values?.[0]?.value?.includes('ResizeObserver')) {
      return null; // Don't send to Sentry
    }
    return event;
  },
});
为不同环境配置不同设置:
typescript
Sentry.init({
  environment: process.env.NODE_ENV,
  enabled: process.env.NODE_ENV !== 'development', // 在开发环境禁用

  beforeSend(event, hint) {
    // 过滤特定错误
    if (event.exception?.values?.[0]?.value?.includes('ResizeObserver')) {
      return null; // 不发送到Sentry
    }
    return event;
  },
});

Source Maps

源映射

Ensure source maps are uploaded for readable stack traces:
typescript
// next.config.js (added by Sentry wizard)
const { withSentryConfig } = require('@sentry/nextjs');

module.exports = withSentryConfig(
  nextConfig,
  {
    silent: true,
    org: process.env.SENTRY_ORG,
    project: process.env.SENTRY_PROJECT,
  },
  {
    hideSourceMaps: true,
    widenClientFileUpload: true,
  }
);
确保上传源映射以获得可读的堆栈跟踪:
typescript
// next.config.js(Sentry向导会自动添加)
const { withSentryConfig } = require('@sentry/nextjs');

module.exports = withSentryConfig(
  nextConfig,
  {
    silent: true,
    org: process.env.SENTRY_ORG,
    project: process.env.SENTRY_PROJECT,
  },
  {
    hideSourceMaps: true,
    widenClientFileUpload: true,
  }
);

Best Practices

最佳实践

  1. Use logger wrapper: Centralize logging for consistency
  2. Set user context: Associate errors with users for debugging
  3. Add breadcrumbs: Track user journey before errors
  4. Monitor performance: Use tracing for slow operations
  5. Filter noise: Exclude known non-critical errors
  6. Configure sample rates: Balance visibility with quota
  7. Test in staging: Verify Sentry integration before production
  8. Review regularly: Check Sentry dashboard for patterns
  1. 使用日志包装器:集中日志管理以保证一致性
  2. 设置用户上下文:将错误与用户关联以方便调试
  3. 添加面包屑:追踪错误发生前的用户操作路径
  4. 监控性能:使用追踪功能定位慢操作
  5. 过滤无效信息:排除已知的非关键错误
  6. 配置采样率:在可见性和配额之间取得平衡
  7. 在预发布环境测试:上线前验证Sentry集成效果
  8. 定期复查:查看Sentry控制台以发现错误模式

Troubleshooting

故障排除

Sentry not capturing errors: Check DSN is correct and Sentry is initialized. Verify
instrumentation.ts
exports
register()
.
Source maps not working: Ensure auth token is set and source maps are uploaded during build. Check Sentry dashboard > Settings > Source Maps.
High quota usage: Reduce sample rates in production. Filter out noisy errors with
beforeSend
.
Traces not appearing: Verify
tracesSampleRate
> 0. Check OpenTelemetry is initialized in
instrumentation.ts
.
Client errors not captured: Ensure
NEXT_PUBLIC_SENTRY_DSN
is set and accessible from browser.
Sentry未捕获错误:检查DSN是否正确,Sentry是否已初始化。验证
instrumentation.ts
是否导出
register()
源映射不生效:确保已设置认证令牌,且构建过程中已上传源映射。查看Sentry控制台 > 设置 > 源映射。
配额使用过高:降低生产环境的采样率。使用
beforeSend
过滤无效错误。
追踪数据未显示:验证
tracesSampleRate
> 0。检查
instrumentation.ts
中是否已初始化OpenTelemetry。
客户端错误未捕获:确保已设置
NEXT_PUBLIC_SENTRY_DSN
,且浏览器可访问该变量。

Resources

资源

scripts/

scripts/

No executable scripts needed for this skill.
本技能无需可执行脚本。

references/

references/

  • sentry-best-practices.md
    - Error handling patterns, performance monitoring strategies, and quota management
  • otel-integration.md
    - OpenTelemetry concepts, custom instrumentation, and distributed tracing setup
  • sentry-best-practices.md
    - 错误处理模式、性能监控策略和配额管理
  • otel-integration.md
    - OpenTelemetry概念、自定义工具集成和分布式追踪设置

assets/

assets/

  • sentry-server-config.ts
    - Server-side Sentry configuration with tracing and sampling
  • sentry-client-config.ts
    - Client-side Sentry configuration with replay and error boundaries
  • instrumentation.ts
    - OpenTelemetry initialization and Sentry integration
  • logger.ts
    - Structured logging wrapper with Sentry integration
  • error-boundary.tsx
    - React error boundary component for client-side error handling
  • error-page.tsx
    - Custom error page for Server Component errors
  • global-error.tsx
    - Global error handler for root layout errors
  • sentry-server-config.ts
    - 带追踪和采样配置的服务端Sentry配置文件
  • sentry-client-config.ts
    - 带会话重放和错误边界配置的客户端Sentry配置文件
  • instrumentation.ts
    - OpenTelemetry初始化与Sentry集成文件
  • logger.ts
    - 集成Sentry的结构化日志包装器
  • error-boundary.tsx
    - 用于客户端错误处理的React错误边界组件
  • error-page.tsx
    - 服务端组件错误的自定义错误页面
  • global-error.tsx
    - 根布局的全局错误处理器