NestJS OpenTelemetry (OTEL) 完全指南:从入门到精通的一站式教程
【免费下载链接】nestjs-otelOpenTelemetry (Tracing + Metrics) module for Nest framework (node.js) 🔭项目地址: https://gitcode.com/gh_mirrors/ne/nestjs-otel
NestJS OpenTelemetry(OTEL)模块是专为Nest框架设计的可观测性解决方案,它整合了OpenTelemetry的追踪(Tracing)和指标(Metrics)功能,帮助开发者轻松构建可观测的Node.js应用。本教程将带你从基础安装到高级功能应用,掌握NestJS应用的可观测性实践。
为什么选择NestJS OpenTelemetry?
在现代微服务架构中,可观测性至关重要。OpenTelemetry提供了统一的标准,支持多种数据导出和指标类型(如Prometheus指标)。nestjs-otel模块简化了OpenTelemetry在NestJS应用中的集成,让开发者无需深入了解底层细节即可实现分布式追踪和性能监控。
核心概念:可观测性三支柱
可观测性建立在三个核心信号之上:
- 追踪(Tracing):记录请求在系统中的传播路径,帮助定位性能瓶颈
- 指标(Metrics):量化系统行为,如请求量、错误率、响应时间
- 日志(Logs):记录系统事件,提供调试上下文
图:NestJS OpenTelemetry可观测性三支柱示意图
快速安装步骤
1. 安装核心依赖
npm i nestjs-otel @opentelemetry/sdk-node --save2. 安装可选依赖
根据需要的导出器类型安装额外依赖:
npm i @opentelemetry/exporter-prometheus --save基础配置指南
创建Tracing配置文件
在项目根目录创建tracing.ts文件:
import { NodeSDK } from '@opentelemetry/sdk-node'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'; import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'; import { JaegerExporter } from '@opentelemetry/exporter-jaeger'; import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks'; const otelSDK = new NodeSDK({ metricReader: new PrometheusExporter({ port: 8081 }), spanProcessor: new BatchSpanProcessor(new JaegerExporter()), contextManager: new AsyncLocalStorageContextManager(), instrumentations: [getNodeAutoInstrumentations()], }); export default otelSDK;集成到NestJS应用
在应用入口文件(通常是main.ts)中启动OTEL SDK:
import otelSDK from './tracing'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { // 在创建Nest应用前启动OTEL SDK await otelSDK.start(); const app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap();注册OpenTelemetry模块
在AppModule中配置OpenTelemetry模块:
import { OpenTelemetryModule } from 'nestjs-otel'; @Module({ imports: [ OpenTelemetryModule.forRoot({ metrics: { hostMetrics: true } // 启用主机指标收集 }) ] }) export class AppModule {}追踪功能详解
使用@Span装饰器创建自定义追踪
@Span装饰器可用于标记需要追踪的方法,支持自定义名称和属性:
import { Span } from 'nestjs-otel'; export class BooksService { // 自定义span名称 @Span('getBooks') async getBooks() { return ['Harry Potter', 'The Hobbit']; } // 动态设置span属性 @Span((id) => ({ attributes: { bookId: id } })) async getBook(id: number) { return { id, title: 'NestJS in Action' }; } }使用@Traceable装饰器追踪类所有方法
对类使用@Traceable装饰器可自动追踪所有方法:
import { Traceable } from 'nestjs-otel'; @Injectable() @Traceable() export class UsersService { findAll() { return []; } findOne(id: string) { return {}; } }访问当前Span
使用@CurrentSpan装饰器在控制器中获取当前span:
import { Controller, Get } from '@nestjs/common'; import { CurrentSpan } from 'nestjs-otel'; import { Span } from '@opentelemetry/api'; @Controller('cats') export class CatsController { @Get() findAll(@CurrentSpan() span: Span) { span?.setAttribute('custom.attribute', 'value'); return 'This action returns all cats'; } }指标监控实战
使用MetricService创建指标
通过MetricService可以创建和管理各种类型的指标:
import { MetricService } from 'nestjs-otel'; import { Counter } from '@opentelemetry/api'; @Injectable() export class BookService { private bookCounter: Counter; constructor(private metricService: MetricService) { this.bookCounter = this.metricService.getCounter('book_requests_total', { description: 'Total number of book requests' }); } async getBooks() { this.bookCounter.add(1); return ['Book 1', 'Book 2']; } }方法级指标装饰器
使用@OtelMethodCounter装饰器自动统计方法调用次数:
@Controller() export class AppController { @Get() @OtelMethodCounter() // 自动生成 app_AppController_doSomething_calls_total 指标 doSomething() { // 业务逻辑 } }Prometheus指标导出
配置Prometheus导出器后,指标将在http://localhost:8081/metrics端点可用,可直接被Prometheus抓取。
高级功能:Wide Events
Wide Events(宽事件)模式在单个请求生命周期中累积属性,最终生成一个上下文丰富的事件。
注册WideEventInterceptor
import { APP_INTERCEPTOR } from '@nestjs/core'; import { WideEventInterceptor } from 'nestjs-otel'; @Module({ providers: [ { provide: APP_INTERCEPTOR, useClass: WideEventInterceptor } ] }) export class AppModule {}使用WideEventService丰富事件
import { WideEventService } from 'nestjs-otel'; @Injectable() export class CheckoutService { constructor(private wideEvent: WideEventService) {} async checkout(cart: Cart) { this.wideEvent.setMany({ 'user.id': cart.userId, 'cart.items': cart.items.length, 'cart.total': cart.total }); const timer = this.wideEvent.startTimer('payment.duration_ms'); await this.processPayment(cart); timer(); // 停止计时并记录 } }与日志集成
Pino日志集成
通过OpenTelemetry instrumentation自动将traceId和spanId注入日志:
import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino'; const otelSDK = new NodeSDK({ instrumentations: [new PinoInstrumentation()] });完整示例项目
查看完整的示例项目,包含NestJS应用与Prometheus、Grafana、Loki和Tempo的集成:
- nestjs-otel-prom-grafana-tempo
总结
NestJS OpenTelemetry模块为Nest应用提供了强大的可观测性能力,通过简单的配置和装饰器即可实现分布式追踪和指标监控。无论是小型项目还是大型微服务架构,nestjs-otel都能帮助你构建更可靠、更易于维护的应用系统。
开始使用NestJS OpenTelemetry,提升你的应用可观测性,快速定位问题,优化性能!
【免费下载链接】nestjs-otelOpenTelemetry (Tracing + Metrics) module for Nest framework (node.js) 🔭项目地址: https://gitcode.com/gh_mirrors/ne/nestjs-otel
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考