Sentry 安装与配置 #
注册 Sentry 账户 #
选择部署方式 #
Sentry 提供两种部署方式:
text
┌─────────────────────────────────────────────────────────────┐
│ Sentry 部署方式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. SaaS(Sentry.io) │
│ ✅ 无需运维,开箱即用 │
│ ✅ 自动升级和扩展 │
│ ✅ 免费额度充足 │
│ ⚠️ 数据存储在云端 │
│ │
│ 2. 自托管(Self-hosted) │
│ ✅ 数据完全自主控制 │
│ ✅ 可定制化 │
│ ✅ 内网部署 │
│ ⚠️ 需要运维能力 │
│ │
└─────────────────────────────────────────────────────────────┘
注册 SaaS 账户 #
- 访问 https://sentry.io
- 点击 “Start for Free” 或 “Sign Up”
- 选择注册方式:
- 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