Sentry 安装与配置 #

注册 Sentry 账户 #

选择部署方式 #

Sentry 提供两种部署方式:

text
┌─────────────────────────────────────────────────────────────┐
│                    Sentry 部署方式                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. SaaS(Sentry.io)                                       │
│     ✅ 无需运维,开箱即用                                    │
│     ✅ 自动升级和扩展                                       │
│     ✅ 免费额度充足                                         │
│     ⚠️ 数据存储在云端                                       │
│                                                             │
│  2. 自托管(Self-hosted)                                   │
│     ✅ 数据完全自主控制                                     │
│     ✅ 可定制化                                             │
│     ✅ 内网部署                                             │
│     ⚠️ 需要运维能力                                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

注册 SaaS 账户 #

  1. 访问 https://sentry.io
  2. 点击 “Start for Free” 或 “Sign Up”
  3. 选择注册方式:
    • GitHub 账户
    • Google 账户
    • 邮箱注册

免费额度 #

资源 免费额度
错误事件 5,000 次/月
性能事件 10,000 次/月
项目数量 不限
团队成员 1 人

创建项目和获取 DSN #

创建项目 #

text
┌─────────────────────────────────────────────────────────────┐
│                    创建项目流程                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 登录 Sentry 控制台                                      │
│     ↓                                                       │
│  2. 点击 "Create Project"                                   │
│     ↓                                                       │
│  3. 选择平台(JavaScript, Python, Java...)                 │
│     ↓                                                       │
│  4. 设置告警频率(默认即可)                                │
│     ↓                                                       │
│  5. 命名项目                                                │
│     ↓                                                       │
│  6. 获取 DSN                                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

理解 DSN #

DSN(Data Source Name)是 Sentry 项目的唯一标识符:

text
https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@o123456.ingest.sentry.io/1234567
│       │                              │                      │
│       │                              │                      └── Project ID
│       │                              └── Organization ID
│       └── Public Key(公钥)
└── Protocol(协议)

DSN 配置位置 #

javascript
// Sentry 初始化时使用 DSN
Sentry.init({
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
});

前端 SDK 安装 #

JavaScript/TypeScript #

bash
# npm
npm install @sentry/browser

# yarn
yarn add @sentry/browser

# pnpm
pnpm add @sentry/browser

React #

bash
# npm
npm install @sentry/react

# yarn
yarn add @sentry/react

Vue #

bash
# npm
npm install @sentry/vue

# yarn
yarn add @sentry/vue

Angular #

bash
# npm
npm install @sentry/angular

# yarn
yarn add @sentry/angular

Next.js #

bash
# npm
npm install @sentry/nextjs

# yarn
yarn add @sentry/nextjs

后端 SDK 安装 #

Python #

bash
# pip
pip install sentry-sdk

# poetry
poetry add sentry-sdk

# pipenv
pipenv install sentry-sdk

Node.js #

bash
# npm
npm install @sentry/node

# yarn
yarn add @sentry/node

Java (Maven) #

xml
<dependency>
    <groupId>io.sentry</groupId>
    <artifactId>sentry</artifactId>
    <version>7.0.0</version>
</dependency>

Java (Gradle) #

groovy
implementation 'io.sentry:sentry:7.0.0'

Go #

bash
go get github.com/getsentry/sentry-go

Ruby #

ruby
# Gemfile
gem "sentry-ruby"
gem "sentry-rails"  # 如果使用 Rails

PHP #

bash
composer require sentry/sentry

.NET #

bash
dotnet add package Sentry

前端初始化配置 #

基础配置 #

javascript
// src/index.js 或 main.js
import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  
  // 设置环境
  environment: process.env.NODE_ENV,
  
  // 设置版本
  release: "my-project@1.0.0",
  
  // 采样率(1.0 = 100%)
  sampleRate: 1.0,
});

React 完整配置 #

javascript
// src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import * as Sentry from "@sentry/react";
import { BrowserTracing } from "@sentry/tracing";
import App from "./App";

Sentry.init({
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  integrations: [
    new BrowserTracing(),
    new Sentry.Replay({
      maskAllText: true,
      blockAllMedia: true,
    }),
  ],
  
  tracesSampleRate: 0.1,
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  
  environment: process.env.NODE_ENV,
  release: `my-app@${process.env.npm_package_version}`,
  
  beforeSend(event) {
    if (event.request?.url?.includes("localhost")) {
      return null;
    }
    return event;
  },
});

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Vue 完整配置 #

javascript
// src/main.js
import { createApp } from "vue";
import * as Sentry from "@sentry/vue";
import { BrowserTracing } from "@sentry/tracing";
import App from "./App.vue";

const app = createApp(App);

Sentry.init({
  app,
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  integrations: [
    new BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
    }),
  ],
  
  tracesSampleRate: 0.1,
  
  environment: import.meta.env.MODE,
  release: `my-vue-app@${import.meta.env.VITE_APP_VERSION}`,
  
  logErrors: true,
});

app.use(router);
app.mount("#app");

Next.js 配置 #

javascript
// next.config.js
const { withSentryConfig } = require("@sentry/nextjs");

const moduleExports = {
  sentry: {
    hideSourceMaps: true,
  },
};

const sentryWebpackPluginOptions = {
  silent: true,
  authToken: process.env.SENTRY_AUTH_TOKEN,
  org: "my-org",
  project: "my-project",
};

module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions);
javascript
// sentry.client.config.js
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  tracesSampleRate: 0.1,
  environment: process.env.NODE_ENV,
});
javascript
// sentry.server.config.js
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  tracesSampleRate: 0.1,
  environment: process.env.NODE_ENV,
});

后端初始化配置 #

Python Flask #

python
# app.py
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from flask import Flask

sentry_sdk.init(
    dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
    integrations=[FlaskIntegration()],
    
    traces_sample_rate=0.1,
    
    environment="production",
    release="my-app@1.0.0",
    
    before_send=lambda event, hint: event,
)

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, World!"

Python Django #

python
# settings.py
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration

sentry_sdk.init(
    dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
    integrations=[DjangoIntegration()],
    
    traces_sample_rate=0.1,
    
    environment="production",
    release="my-django-app@1.0.0",
    
    send_default_pii=True,
)

Python FastAPI #

python
# main.py
import sentry_sdk
from sentry_sdk.integrations.starlette import StarletteIntegration
from sentry_sdk.integrations.fastapi import FastApiIntegration
from fastapi import FastAPI

sentry_sdk.init(
    dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
    integrations=[
        StarletteIntegration(),
        FastApiIntegration(),
    ],
    
    traces_sample_rate=0.1,
    
    environment="production",
)

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

Node.js Express #

javascript
// app.js
const express = require("express");
const Sentry = require("@sentry/node");
const { ProfilingIntegration } = require("@sentry/profiling-node");

const app = express();

Sentry.init({
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  integrations: [
    new Sentry.Integrations.Http({ tracing: true }),
    new Sentry.Integrations.Express({ app }),
    new ProfilingIntegration(),
  ],
  
  tracesSampleRate: 0.1,
  profilesSampleRate: 0.1,
  
  environment: process.env.NODE_ENV,
  release: `my-api@${process.env.npm_package_version}`,
});

app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.tracingHandler());

app.get("/", (req, res) => {
  res.send("Hello World");
});

app.use(Sentry.Handlers.errorHandler());

app.listen(3000);

Node.js NestJS #

typescript
// main.ts
import { NestFactory } from "@nestjs/core";
import * as Sentry from "@sentry/node";
import { SentryFilter } from "./sentry.filter";
import { AppModule } from "./app.module";

Sentry.init({
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  tracesSampleRate: 0.1,
  environment: process.env.NODE_ENV,
});

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  
  app.useGlobalFilters(new SentryFilter());
  
  await app.listen(3000);
}
bootstrap();
typescript
// sentry.filter.ts
import { Catch, ArgumentsHost, HttpException, HttpStatus } from "@nestjs/common";
import { BaseExceptionFilter } from "@nestjs/core";
import * as Sentry from "@sentry/node";

@Catch()
export class SentryFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    Sentry.captureException(exception);
    
    super.catch(exception, host);
  }
}

Go #

go
// main.go
package main

import (
    "github.com/getsentry/sentry-go"
    sentryhttp "github.com/getsentry/sentry-go/http"
    "net/http"
    "time"
)

func main() {
    err := sentry.Init(sentry.ClientOptions{
        Dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
        
        TracesSampleRate: 0.1,
        
        Environment: "production",
        Release:     "my-go-app@1.0.0",
    })
    if err != nil {
        panic(err)
    }
    defer sentry.Flush(2 * time.Second)
    
    sentryHandler := sentryhttp.New(sentryhttp.Options{})
    
    http.Handle("/", sentryHandler.HandleFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, World!"))
    }))
    
    http.ListenAndServe(":8080", nil)
}

Java Spring Boot #

java
// SentryConfig.java
import io.sentry.Sentry;
import io.sentry.spring.SentryExceptionResolver;
import io.sentry.spring.SentryServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SentryConfig {
    
    @Bean
    public SentryExceptionResolver sentryExceptionResolver() {
        return new SentryExceptionResolver();
    }
    
    @Bean
    public SentryServletContextInitializer sentryServletContextInitializer() {
        return new SentryServletContextInitializer();
    }
}
properties
# application.properties
sentry.dsn=https://xxxxxxxx@o123456.ingest.sentry.io/1234567
sentry.environment=production
sentry.release=my-spring-app@1.0.0
sentry.traces-sample-rate=0.1

配置选项详解 #

基础配置 #

javascript
Sentry.init({
  // 必需:DSN
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  
  // 可选:环境
  environment: "production",
  
  // 可选:版本
  release: "my-app@1.0.0",
  
  // 可选:服务器名称
  serverName: "web-server-1",
  
  // 可选:应用名称
  appName: "my-app",
  
  // 可选:应用版本
  appVersion: "1.0.0",
});

采样配置 #

javascript
Sentry.init({
  // 错误采样率(1.0 = 100%)
  sampleRate: 1.0,
  
  // 性能追踪采样率
  tracesSampleRate: 0.1,
  
  // Session Replay 采样率
  replaysSessionSampleRate: 0.1,
  
  // 错误时 Session Replay 采样率
  replaysOnErrorSampleRate: 1.0,
  
  // 动态采样
  tracesSampler: (samplingContext) => {
    if (samplingContext.transactionContext.name === "GET /health") {
      return 0;
    }
    return 0.1;
  },
});

过滤配置 #

javascript
Sentry.init({
  // 发送前处理
  beforeSend(event, hint) {
    if (event.request?.url?.includes("localhost")) {
      return null;
    }
    return event;
  },
  
  // 发送事务前处理
  beforeSendTransaction(event) {
    if (event.transaction === "GET /health") {
      return null;
    }
    return event;
  },
  
  // 发送面包屑前处理
  beforeBreadcrumb(breadcrumb, hint) {
    if (breadcrumb.category === "console") {
      return null;
    }
    return breadcrumb;
  },
  
  // 忽略特定错误
  ignoreErrors: [
    "NetworkError",
    "TypeError: Failed to fetch",
    /ResizeObserver/i,
  ],
  
  // 忽略特定事务
  ignoreTransactions: [
    "GET /health",
    "OPTIONS *",
  ],
});

集成配置 #

javascript
Sentry.init({
  integrations: [
    // 自动集成
    new Sentry.Integrations.GlobalHandlers({
      onerror: true,
      onunhandledrejection: true,
    }),
    
    new Sentry.Integrations.Breadcrumbs({
      console: true,
      dom: true,
      fetch: true,
      history: true,
      xhr: true,
    }),
    
    // 性能监控
    new Sentry.BrowserTracing({
      traceFetch: true,
      traceXHR: true,
    }),
    
    // Session Replay
    new Sentry.Replay({
      maskAllText: true,
      blockAllMedia: true,
    }),
  ],
  
  // 禁用默认集成
  defaultIntegrations: false,
});

环境变量配置 #

使用环境变量 #

javascript
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV || "development",
  release: process.env.SENTRY_RELEASE,
});

.env 文件 #

bash
# .env
SENTRY_DSN=https://xxxxxxxx@o123456.ingest.sentry.io/1234567
SENTRY_ENVIRONMENT=production
SENTRY_RELEASE=my-app@1.0.0

CI/CD 配置 #

yaml
# GitHub Actions
env:
  SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
  SENTRY_RELEASE: ${{ github.sha }}
  SENTRY_ENVIRONMENT: production

验证配置 #

测试错误捕获 #

javascript
// 手动触发测试错误
Sentry.captureException(new Error("This is a test error"));

// 或使用未处理的错误
throw new Error("This is a test error");

检查初始化状态 #

javascript
if (Sentry.isInitialized()) {
  console.log("Sentry is initialized");
}

调试模式 #

javascript
Sentry.init({
  dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
  debug: true,
  
  // 输出详细日志
  _experiments: {
    printParsedDSN: true,
  },
});

常见问题 #

1. 错误未上报 #

javascript
// 检查是否被过滤
Sentry.init({
  beforeSend(event) {
    console.log("Event:", event);
    return event;
  },
});

// 检查采样率
Sentry.init({
  sampleRate: 1.0,  // 确保为 1.0 进行测试
});

2. Source Map 未加载 #

javascript
// 确保配置正确
Sentry.init({
  release: "my-app@1.0.0",
  
  // 确保上传了 Source Map
});

3. 性能数据缺失 #

javascript
// 确保添加了 BrowserTracing 集成
Sentry.init({
  integrations: [new Sentry.BrowserTracing()],
  tracesSampleRate: 1.0,  // 测试时设为 1.0
});

下一步 #

现在你已经完成了 Sentry 的安装和配置,接下来学习 错误捕获基础 了解如何捕获和处理错误!

最后更新:2026-03-29