Nestjs项目实战 日志记录与监控系统集成

在Nestjs项目中集成日志记录与监控系统时,如何选择合适的日志库(如Winston、Pino)并实现多层级(DEBUG/INFO/ERROR)分类输出?
如何将日志自动按日期或大小切割存储,同时避免日志文件过大影响性能?
监控系统(如Prometheus+Grafana)对接Nestjs的最佳实践是什么?需要重点关注哪些性能指标(请求延迟、内存使用等)?
在生产环境中,如何通过中间件或拦截器统一处理请求日志,并确保敏感信息(如用户密码)不被记录?
分布式部署时怎样将多实例日志集中管理(ELK方案或其他推荐工具)?是否需考虑日志的异步写入机制?

3 回复

在Nestjs项目中集成日志记录与监控系统,可以使用@nestjs/common自带的Logger模块,并结合第三方工具如winstonpino实现更强大的日志功能。

首先安装winston

npm install winston

创建一个自定义Logger服务:

import { Injectable } from '@nestjs/common';
import * as winston from 'winston';

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
    new winston.transports.File({ filename: 'logs/combined.log' }),
  ],
});

@Injectable()
export class CustomLogger {
  log(message: any) {
    logger.info(message);
  }

  error(message: any, trace: string) {
    logger.error(message, { trace });
  }

  warn(message: any) {
    logger.warn(message);
  }
}

在模块中注入该服务并使用。对于监控,可以集成Prometheus和Grafana。安装@promster/metrics

npm install @promster/metrics

创建Prometheus服务:

import { Injectable } from '@nestjs/common';
import { MetricsService } from '@promster/metrics';

@Injectable()
export class PrometheusService {
  constructor(private readonly metrics: MetricsService) {}

  registerMetrics() {
    this.metrics.setCounter('http_requests_total', 'Total number of HTTP requests');
    // 其他指标...
  }
}

在应用启动时注册这些指标即可。


在NestJS项目中实现日志记录与监控系统集成,可以按以下步骤进行:

  1. 引入日志库:推荐使用pinowinston。例如,通过npm安装pino:

    npm install pino
    

    然后在main.ts中配置日志:

    import * as pino from 'pino';
    const logger = pino();
    app.useLogger(logger);
    
  2. 监控系统集成:可以集成Prometheus+Grafana。首先安装[@nestjs](/user/nestjs)/microservices[@promster](/user/promster)/nestjs

    npm install [@nestjs](/user/nestjs)/microservices [@promster](/user/promster)/nestjs
    

    配置app.module.ts启用监控:

    import { PrometheusModule } from '[@promster](/user/promster)/nestjs';
    

@Module({ imports: [ PrometheusModule.register({ endpoint: ‘/metrics’, }), ], }) export class AppModule {}


3. **自定义日志格式**:在`logger.service.ts`中定义日志格式,支持上下文信息:
```typescript
export class LoggerService {
  log(message: string, context?: string) {
    this.logger.info(`[${context}] ${message}`);
  }
}
  1. 错误处理与监控:通过中间件捕获异常并上报至监控系统:
    app.useGlobalFilters(new AllExceptionsFilter());
    

这样,你的NestJS应用就能实现高效的日志记录与监控功能了。

在NestJS项目中集成日志记录和监控系统的最佳实践如下:

  1. 日志记录方案: 推荐使用NestJS内置的Logger结合Winston:
// logger.service.ts
import { Injectable, LoggerService } from '@nestjs/common';
import * as winston from 'winston';

@Injectable()
export class AppLogger implements LoggerService {
  private logger: winston.Logger;

  constructor() {
    this.logger = winston.createLogger({
      level: 'info',
      format: winston.format.json(),
      transports: [
        new winston.transports.File({ filename: 'error.log', level: 'error' }),
        new winston.transports.File({ filename: 'combined.log' }),
      ],
    });
  }

  log(message: string) {
    this.logger.info(message);
  }
  error(message: string, trace: string) {
    this.logger.error(message, { trace });
  }
  warn(message: string) {
    this.logger.warn(message);
  }
}
  1. 监控系统集成: 推荐使用Prometheus + Grafana组合:
// prometheus.module.ts
import { Module } from '@nestjs/common';
import { PrometheusModule } from '@willsoto/nestjs-prometheus';

@Module({
  imports: [PrometheusModule.register()],
})
export class AppPrometheusModule {}
  1. 性能监控: 使用@nestjs/platform-express的拦截器:
// logging.interceptor.ts
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`Execution time: ${Date.now() - now}ms`)),
      );
  }
}
  1. 健康检查: 使用@nestjs/terminus
npm install @nestjs/terminus
// health.controller.ts
import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HealthCheck } from '@nestjs/terminus';

@Controller('health')
export class HealthController {
  constructor(private health: HealthCheckService) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([]);
  }
}

部署建议:

  1. 生产环境应将日志发送到ELK或类似系统
  2. 设置日志轮转防止磁盘爆满
  3. 敏感信息需过滤后再记录
  4. 监控指标应包含API响应时间、错误率、请求量等关键指标
回到顶部