Nestjs教程使用Prometheus进行监控与报警

最近在Nestjs项目中集成Prometheus时遇到一些问题,想请教大家:

  1. 如何在Nestjs中正确配置Prometheus的metrics端点?官方文档的示例不太清晰,尝试后/metrics返回404
  2. 自定义业务指标(比如API调用次数)应该怎样注入到Prometheus中?是否需要额外的装饰器或中间件?
  3. 报警规则配置有什么最佳实践?比如针对HTTP 5xx错误或响应延迟的阈值设置
  4. 本地开发时一切正常,但部署到Kubernetes后Prometheus无法抓取数据,是否和service mesh的sidecar有关?
  5. 有没有开箱即用的Nestjs+Prometheus监控面板模板推荐?Grafana官方库没找到适配的仪表盘

项目中用的是@nestjs/prometheus包,但感觉文档太少,社区案例基本都是Java/Go的,求大佬分享实战经验!


3 回复

在NestJS中使用Prometheus进行监控和报警的步骤如下:

  1. 安装依赖
    首先需要安装[@willsoto](/user/willsoto)/nestjs-prometheus包来集成Prometheus。

    npm install [@willsoto](/user/willsoto)/nestjs-prometheus
    
  2. 配置模块
    在你的NestJS项目中引入PrometheusModule并配置它。

    import { Module } from '[@nestjs](/user/nestjs)/common';
    import { PrometheusModule } from '[@willsoto](/user/willsoto)/nestjs-prometheus';
    
    [@Module](/user/Module)({
      imports: [
        PrometheusModule.register({
          defaultLabels: { app: 'my-app' },
        }),
      ],
    })
    export class AppModule {}
    
  3. 创建指标
    使用装饰器定义监控指标。

    import { Controller, Get, MetricsController, promMetrics } from '[@willsoto](/user/willsoto)/nestjs-prometheus';
    import { Counter } from '[@willsoto](/user/willsoto)/nestjs-prometheus/build/src/prom.types';
    
    [@Controller](/user/Controller)()
    export class AppController {
      @Counter({ name: 'http_requests_total', help: 'Total number of HTTP requests' })
      private readonly httpRequests;
    
      constructor() {
        this.httpRequests = promMetrics().getCounter('http_requests_total');
      }
    
      @Get()
      root() {
        this.httpRequests.inc();
        return { message: 'Hello World!' };
      }
    }
    
  4. 启动服务
    启动NestJS应用后,访问/metrics即可获取Prometheus格式的数据。

  5. 设置报警规则
    在Prometheus配置文件中添加报警规则,例如:

    groups:
      - name: example
        rules:
          - alert: HighRequestRate
            expr: increase(http_requests_total[5m]) > 100
            for: 1m
            labels:
              severity: warning
            annotations:
              summary: "High request rate detected"
    

通过以上步骤,你可以实现NestJS应用的监控和报警功能。


要使用Prometheus监控NestJS应用,首先安装@nestjs/microservicesprom-client库。创建一个服务,用于暴露监控指标。

  1. 安装依赖:
npm install @nestjs/microservices prom-client
  1. 创建监控服务:
import { Injectable } from '@nestjs/common';
import { Counter, Gauge, Histogram, Registry } from 'prom-client';

@Injectable()
export class MetricsService {
  private readonly _requestCounter = new Counter({
    name: 'http_requests_total',
    help: 'Total HTTP requests',
    labelNames: ['method', 'endpoint', 'status_code'],
  });

  private readonly _responseTimeHistogram = Histogram.build({
    name: 'http_response_time_ms',
    help: 'HTTP response time in milliseconds',
    labelNames: ['method', 'endpoint'],
    buckets: [50, 100, 200, 300, 400, 500],
  });

  constructor() {
    // 注册到全局Registry
    Registry.setDefaultLabels({ app: 'my-nest-app' });
    Registry.register(this._requestCounter);
    Registry.register(this._responseTimeHistogram);
  }

  // 在请求处理时更新计数器
  trackRequest(method: string, endpoint: string, statusCode: number) {
    this._requestCounter.inc({ method, endpoint, status_code: statusCode.toString() });
  }

  // 在响应时记录耗时
  recordResponseTime(method: string, endpoint: string, durationMs: number) {
    this._responseTimeHistogram.observe({ method, endpoint }, durationMs);
  }
}
  1. 在全局拦截器中使用该服务记录数据:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { MetricsService } from './metrics.service';

@Injectable()
export class MetricsInterceptor implements NestInterceptor {
  constructor(private readonly metricsService: MetricsService) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    const { method, url } = request;
    const start = Date.now();

    return next.handle().pipe(
      finalize(() => {
        const duration = Date.now() - start;
        const statusCode = request.res.statusCode;
        this.metricsService.trackRequest(method, url, statusCode);
        this.metricsService.recordResponseTime(method, url, duration);
      }),
    );
  }
}
  1. AppModule中注册拦截器:
import { Module, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MetricsInterceptor } from './metrics.interceptor';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, MetricsService],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(MetricsInterceptor)
      .exclude({ path: '*', method: RequestMethod.GET })
      .forRoutes('*');
  }
}
  1. 启动NestJS应用后,Prometheus可以通过抓取/metrics路径获取数据。配置Prometheus Job来抓取你的应用数据,并设置警报规则。

NestJS集成Prometheus进行监控和报警的简明教程:

  1. 首先安装必要依赖:
npm install @willsoto/nestjs-prometheus prom-client
  1. 在AppModule中导入Prometheus模块:
import { Module } from '@nestjs/common';
import { PrometheusModule } from '@willsoto/nestjs-prometheus';

@Module({
  imports: [
    PrometheusModule.register({
      defaultMetrics: {
        enabled: true,
      },
    }),
  ],
})
export class AppModule {}
  1. 创建自定义指标(示例计数器):
import { Injectable } from '@nestjs/common';
import { Counter } from 'prom-client';
import { InjectMetric } from '@willsoto/nestjs-prometheus';

@Injectable()
export class AppService {
  constructor(
    @InjectMetric('http_requests_total') 
    private counter: Counter<string>,
  ) {}

  getHello() {
    this.counter.inc(); // 每次调用增加计数器
    return 'Hello World!';
  }
}
  1. 设置/metrics端点: 默认会暴露在/metrics路径,可直接访问获取指标数据。

  2. 报警配置建议:

  • 使用Prometheus Alertmanager设置规则
  • 常见报警规则示例:
groups:
- name: example
  rules:
  - alert: HighRequestRate
    expr: rate(http_requests_total[1m]) > 100
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High request rate on {{ $labels.instance }}"
  1. 可视化: 推荐使用Grafana连接到Prometheus数据源,创建监控仪表板。

注意:生产环境应考虑添加认证中间件保护/metrics端点,防止敏感指标信息暴露。

回到顶部