Skip to content

Sentry

Sentry 是一个错误追踪与性能监控平台,可帮助开发者实时识别并修复问题。本篇秘籍展示了如何在 NestJS 应用中集成 Sentry 的 NestJS SDK

安装

首先,安装所需依赖:

bash
$ npm install --save @sentry/nestjs @sentry/profiling-node

提示

@sentry/profiling-node 是可选的,但建议启用以支持性能分析。

基础设置

要开始使用 Sentry,你需要创建一个名为 instrument.ts 的文件,并且它应当在应用中其他任何模块之前被导入:

typescript
// instrument.ts
const Sentry = require("@sentry/nestjs");
const { nodeProfilingIntegration } = require("@sentry/profiling-node");

// Ensure to call this before requiring any other modules!
Sentry.init({
  dsn: SENTRY_DSN,
  integrations: [
    // Add our Profiling integration
    nodeProfilingIntegration(),
  ],

  // Add Tracing by setting tracesSampleRate
  // We recommend adjusting this value in production
  tracesSampleRate: 1.0,

  // Set sampling rate for profiling
  // This is relative to tracesSampleRate
  profilesSampleRate: 1.0,
});

更新你的 main.ts 文件,在其他导入之前先导入 instrument.ts

typescript
// main.ts
// Import this first!
import "./instrument";

// Now import other modules
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}

bootstrap();

之后,在你的主模块中将 SentryModule 作为根模块引入:

typescript
// app.module.ts
import { Module } from "@nestjs/common";
import { SentryModule } from "@sentry/nestjs/setup";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";

@Module({
  imports: [
    SentryModule.forRoot(),
    // ...other modules
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

异常处理

如果你使用了一个全局兜底异常过滤器(即通过 app.useGlobalFilters() 注册的过滤器,或在应用模块 providers 中注册、并使用无参数 @Catch() 装饰的过滤器),请在过滤器的 catch() 方法上添加 @SentryExceptionCaptured() 装饰器。该装饰器会把所有被你的全局错误过滤器接收到的意外错误上报给 Sentry:

typescript
import { Catch, ExceptionFilter } from '@nestjs/common';
import { SentryExceptionCaptured } from '@sentry/nestjs';

@Catch()
export class YourCatchAllExceptionFilter implements ExceptionFilter {
  @SentryExceptionCaptured()
  catch(exception, host): void {
    // your implementation here
  }
}

默认情况下,只有那些未被错误过滤器捕获的未处理异常才会上报到 Sentry。HttpExceptions(包括其派生类)默认也不会被捕获,因为它们通常主要承担控制流程的作用。

如果你没有全局兜底异常过滤器,请将 SentryGlobalFilter 添加到主模块的 providers 中。这个过滤器会把那些未被其他错误过滤器捕获的未处理错误上报给 Sentry。

警告

SentryGlobalFilter 必须注册在其他所有异常过滤器之前。

typescript
// app.module.ts
import { Module } from "@nestjs/common";
import { APP_FILTER } from "@nestjs/core";
import { SentryGlobalFilter } from "@sentry/nestjs/setup";

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: SentryGlobalFilter,
    },
    // ..other providers
  ],
})
export class AppModule {}

可读的堆栈追踪

取决于你的项目配置方式,Sentry 中错误的堆栈追踪信息可能看起来并不像你的实际代码。

要修复这个问题,请将 source map 上传到 Sentry。最简单的方式是使用 Sentry Wizard:

bash
npx @sentry/wizard@latest -i sourcemaps

测试集成

为了验证你的 Sentry 集成是否正常工作,可以添加一个会主动抛出错误的测试端点:

typescript
@Get("debug-sentry")
getError() {
  throw new Error("My first Sentry error!");
}

在应用中访问 /debug-sentry,你应该就能在 Sentry 控制台中看到这条错误。

总结

关于 Sentry NestJS SDK 的完整文档,包括高级配置选项与特性,请访问 Sentry 官方文档

虽然修软件 bug 是 Sentry 的事,但 bug 依然是我们写出来的。如果你在安装 SDK 时遇到任何问题,请提交一个 GitHub Issue 或在 Discord 中联系他们。

基于 NestJS 官方文档翻译