【问题标题】:Nestjs log response data objectNestjs 日志响应数据对象
【发布时间】:2020-03-17 03:39:15
【问题描述】:

我想在 NestJs 中记录传入的请求和传出的响应。我从这里Logging request/response in Nest.js 和文档NestJs Aspect Interception 获取信息。

不使用外部包来实现这一点会很棒,所以我更喜欢原生的“Nest”解决方案。

对于我目前使用此代码的请求日志记录

@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();
  }
}

这将为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,
        }),
      ),
    );
  }
}

这将为GET /users 记录以下结果

但是我怎样才能访问发回给客户端的数据呢?

【问题讨论】:

    标签: javascript typescript express nestjs


    【解决方案1】:

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

    其次,要获取回传给客户端的数据,在你的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,
            })
          )
        );
      }
    }
    

    如果您决定将其拆分为两个单独的拦截器,这也将起作用,但拥有一个也可以更容易地确定调用时间。

    【讨论】:

    • 格式化的响应正文记录器对我不起作用,我必须将其写为 return next.handle().pipe(tap(data =&gt; console.log({ statusCode, data }))); 以防其他人有一个正在与他们作斗争的 linter
    猜你喜欢
    • 2020-01-27
    • 2019-07-06
    • 2019-10-30
    • 2020-12-11
    • 2011-12-02
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多