Nestjs日志响应数据对象

hrp*_*xQ4 5 javascript express typescript nestjs

我想在NestJs中记录传入请求和传出响应。我从此处获取了Nest.js中的记录请求/响应信息以及docs NestJs Aspect Interception文档。

通过不使用外部软件包来实现此目标将是非常棒的,因此我非常希望使用本机的“嵌套”解决方案。

对于请求记录,我目前使用此代码

@Injectable()
export class RequestInterceptor implements NestInterceptor {
  private logger: Logger = new Logger(RequestInterceptor.name);

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const {
      originalUrl,
      method,
      params,
      query,
      body,
    } = context.switchToHttp().getRequest();

    this.logger.log({
      originalUrl,
      method,
      params,
      query,
      body,
    });

    return next.handle();
  }
}
Run Code Online (Sandbox Code Playgroud)

这将记录以下结果 GET /users

在此处输入图片说明

我还想记录传出的响应。目前,我使用此拦截器

@Injectable()
export class ResponseInterceptor implements NestInterceptor {
  private logger: Logger = new Logger(ResponseInterceptor.name);

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const { statusCode } = context.switchToHttp().getResponse();

    return next.handle().pipe(
      tap(() =>
        this.logger.log({
          statusCode,
        }),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这将记录以下结果 GET /users

在此处输入图片说明

但是如何访问发送回客户端的数据?

Jay*_*iel 8

首先,我建议将这些组合到一个记录器中,这样所有的记录逻辑都在一个地方。

其次,要获取返回给客户端的数据,在你的tap函数中你需要给函数添加一个参数,通常我们称之为数据,这样你就可以知道返回的是什么。这有点被 Nest 掩盖了,因为 observable 正在做什么并不是很清楚,但最终,这样的事情最终对你有用:

@Injectable()
export class AspectLogger implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler) {
    const req = context.switchToHttp().getRequest();
    const { statusCode } = context.switchToHttp().getResponse();
    const { originalUrl, method, params, query, body } = req;

    console.log({
      originalUrl,
      method,
      params,
      query,
      body,
    });

    return next.handle().pipe(
      tap((data) =>
        console.log({
          statusCode,
          data,
        })
      )
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您决定将其分解为两个独立的拦截器,这也将起作用,但是拥有一个拦截器也可以更轻松地确定调用时间。

  • 由于格式化的响应正文记录器对我不起作用,我必须将其写为“return next.handle().pipe(tap(data =&gt; console.log({ statusCode, data })));”以防万一其他人都有与他们作斗争的短绒棉 (2认同)