Sentry 是什么?
Sentry 是一个实时错误监控和性能监控平台,主要用于:
- 错误监控:捕获和跟踪应用程序中的异常和错误
- 性能监控:监测应用程序的性能指标
- 发布健康度跟踪:监控部署后的应用状态
- 用户反馈收集:收集用户遇到问题时的反馈
- 告警通知:当出现问题时及时通知开发团队
支持的平台:
这里只截图了一些比较热门的技术栈,但是Sentry基本上从前端到后端,移动端以及一些比较冷门的技术栈都有支持,所以算是比较通用的一个监控方案。
Next.js 中使用 Sentry
1. 安装依赖
npm install @sentry/nextjs # 或 yarn add @sentry/nextjs
2. 初始化配置
运行初始化命令:
npx @sentry/wizard@latest -i nextjs
3. 配置文件
创建
sentry.client.config.js
:import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, tracesSampleRate: 1.0, debug: false, replaysOnErrorSampleRate: 1.0, replaysSessionSampleRate: 0.1, integrations: [ new Sentry.Replay({ maskAllText: true, blockAllMedia: true, }), ], });
创建
sentry.server.config.js
:import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 1.0, debug: false, });
4. Next.js 配置
在
next.config.js
中:const { withSentryConfig } = require('@sentry/nextjs'); const nextConfig = { // 你的 Next.js 配置 }; const sentryWebpackPluginOptions = { silent: true, org: "your-org", project: "your-project", }; module.exports = withSentryConfig(nextConfig, sentryWebpackPluginOptions);
5. 使用示例
import * as Sentry from "@sentry/nextjs"; // 手动捕获错误 try { // 可能出错的代码 } catch (error) { Sentry.captureException(error); } // 添加面包屑 Sentry.addBreadcrumb({ message: 'User clicked button', level: 'info', }); // 设置用户信息 Sentry.setUser({ id: user.id, email: user.email, });
Go 中使用 Sentry
1. 安装依赖
go get github.com/getsentry/sentry-go
2. 初始化配置
package main import ( "fmt" "log" "time" "github.com/getsentry/sentry-go" ) func main() { err := sentry.Init(sentry.ClientOptions{ Dsn: "YOUR_DSN_HERE", Debug: true, TracesSampleRate: 1.0, ProfilesSampleRate: 1.0, }) if err != nil { log.Fatalf("sentry.Init: %s", err) } defer sentry.Flush(2 * time.Second) // 你的应用代码 }
3. 错误捕获示例
// 捕获异常 func riskyFunction() error { defer sentry.Recover() // 可能 panic 的代码 panic("Something went wrong!") } // 手动捕获错误 func handleError() { if err := someOperation(); err != nil { sentry.CaptureException(err) } } // 添加上下文信息 func processUser(userID string) { sentry.ConfigureScope(func(scope *sentry.Scope) { scope.SetUser(sentry.User{ID: userID}) scope.SetTag("section", "user-processing") }) // 处理用户相关逻辑 }
4. HTTP 中间件
import "github.com/getsentry/sentry-go/http/sentryhttp" func main() { sentryHandler := sentryhttp.New(sentryhttp.Options{}) http.Handle("/", sentryHandler.Handle(&handler{})) http.ListenAndServe(":8080", nil) }
NestJS 中使用 Sentry
1. 安装依赖
npm install @sentry/node @sentry/tracing # 或 yarn add @sentry/node @sentry/tracing
2. 创建 Sentry 模块
// sentry.module.ts import { Module, Global } from '@nestjs/common'; import { APP_INTERCEPTOR } from '@nestjs/core'; import * as Sentry from '@sentry/node'; import { SentryInterceptor } from './sentry.interceptor'; @Global() @Module({ providers: [ { provide: APP_INTERCEPTOR, useClass: SentryInterceptor, }, ], }) export class SentryModule { static forRoot() { Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 1.0, debug: process.env.NODE_ENV === 'development', }); return { module: SentryModule, }; } }
3. 创建拦截器
// sentry.interceptor.ts import { Injectable, NestInterceptor, ExecutionContext, CallHandler, } from '@nestjs/common'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import * as Sentry from '@sentry/node'; @Injectable() export class SentryInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { return next.handle().pipe( catchError((error) => { Sentry.captureException(error); return throwError(() => error); }), ); } }
4. 在 main.ts 中配置
// main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import * as Sentry from '@sentry/node'; async function bootstrap() { // 初始化 Sentry Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 1.0, }); const app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap();
5. 在 AppModule 中导入
// app.module.ts import { Module } from '@nestjs/common'; import { SentryModule } from './sentry/sentry.module'; @Module({ imports: [ SentryModule.forRoot(), // 其他模块 ], }) export class AppModule {}
6. 使用示例
// user.service.ts import { Injectable } from '@nestjs/common'; import * as Sentry from '@sentry/node'; @Injectable() export class UserService { async findUser(id: string) { try { // 数据库操作 const user = await this.userRepository.findById(id); // 设置用户上下文 Sentry.setUser({ id: user.id, email: user.email, }); return user; } catch (error) { // 手动捕获错误 Sentry.captureException(error); throw error; } } }
环境变量配置
创建
.env
文件:# Next.js NEXT_PUBLIC_SENTRY_DSN=https://your-dsn@sentry.io/project-id SENTRY_DSN=https://your-dsn@sentry.io/project-id # Go / NestJS SENTRY_DSN=https://your-dsn@sentry.io/project-id
最佳实践
- 不要记录敏感信息:确保不会将密码、token 等敏感数据发送到 Sentry
- 设置合适的采样率:在生产环境中调整采样率以控制数据量
- 使用环境区分:为不同环境设置不同的项目
- 添加上下文信息:包含用户 ID、请求 ID 等有助于调试的信息
- 设置告警规则:配置合适的告警规则以及时响应问题