03.揭秘:创建NestJS自定义日志中间件的艺术

202 阅读3分钟

什么是nestjs的log中间件?

NestJS 支持自定义中间件,允许你在请求/响应周期的特定点执行任意代码。中间件函数可以在路由处理程序之前或之后执行操作,包括访问和修改请求和响应对象。

自定义中间件主要用于以下几种场景:

  1. 日志记录:记录请求和响应数据,如请求方法、URL、状态码、响应时间等。
  2. 身份验证:验证请求是否携带有效的身份认证凭据。
  3. 数据转换:在路由处理程序之前转换请求数据,如解析请求正文或执行其他转换。
  4. 错误处理:捕获异常并处理错误。

要创建自定义中间件,你需要实现 NestMiddleware 接口并提供一个 use 方法。

下面是使用日志中间件记录请求日志的步骤如下:

  1. 定义日志中间件

首先,我们需要定义一个日志中间件类,它需要实现 NestMiddleware 接口。在这个中间件中,我们可以记录请求的各种信息,如请求方法、URL、状态码、响应时间等。

import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  private logger = new Logger('HTTP');

  use(req: Request, res: Response, next: NextFunction) {
    const { ip, method, originalUrl } = req;
    const userAgent = req.get('user-agent') || '';

    res.on('finish', () => {
      const { statusCode } = res;
      const contentLength = res.get('content-length');
      this.logger.log(
        `${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip}`,
      );
    });

    next();
  }
}

在这个例子中,我们使用 res.on('finish', ...) 来监听响应结束事件,从而获取状态码和响应长度等信息。然后将这些信息与请求方法、URL、用户代理和 IP 地址一起记录到日志中。

  1. 注册中间件

接下来,我们需要在应用程序的模块中注册这个中间件。

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './logger.middleware';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, LoggerMiddleware],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('*');
  }
}

在 configure 方法中,我们使用 consumer.apply(LoggerMiddleware).forRoutes('*') 来注册中间件,并指定它应用于所有路由。

  1. 启动应用程序

最后,启动应用程序,日志中间件将会自动运行,并记录每个请求的相关信息。

# 运行应用程序
$ npm run start

启动应用程序后,每次收到请求时,你将在控制台看到类似以下的日志:

[HTTP] GET / 200 - - ::1
[HTTP] POST /api/users 201 375 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3 ::1

日志的打印效果如下: image.png 这样,我们就可以使用日志中间件来记录每个请求的详细信息,对于调试和监控非常有用。

你可以根据需要自定义日志格式和记录的信息,也可以考虑使用更强大的第三方日志库,如 Winston 或 Bunyan 等。

总结

除了全局中间件,NestJS 还支持路由中间件,可以将中间件应用于特定的控制器或路由。你可以使用 @UseMiddleware() 装饰器来注册路由中间件。

总之,NestJS 的自定义中间件提供了在请求/响应周期中执行任意逻辑的能力,有助于实现日志记录、身份验证、数据转换和错误处理等功能。你可以根据具体需求创建和注册自定义中间件。