在Nest.js中记录请求/响应

问题描述 投票:0回答:1

Nest.js新手, 我正在尝试实现一个简单的记录器来跟踪HTTP请求,例如:

:method :url :status :res[content-length] - :response-time ms

根据我的理解,最好的地方是interceptors。但我也使用Guards并提到,卫兵是在中间件之后但在拦截器之前触发的。

意思是,我的forrbidden访问不会被记录。我可以在两个不同的地方写日志部分,但不是。任何的想法?

谢谢!

我的拦截器代码:

import { Injectable, NestInterceptor, ExecutionContext, HttpException, HttpStatus } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';

@Injectable()
export class HTTPLoggingInterceptor implements NestInterceptor {

  intercept(context: ExecutionContext, call$: Observable<any>): Observable<any> {
    const now = Date.now();
    const request = context.switchToHttp().getRequest();

    const method = request.method;
    const url = request.originalUrl;

    return call$.pipe(
      tap(() => {
        const response = context.switchToHttp().getResponse();
        const delay = Date.now() - now;
        console.log(`${response.statusCode} | [${method}] ${url} - ${delay}ms`);
      }),
      catchError((error) => {
        const response = context.switchToHttp().getResponse();
        const delay = Date.now() - now;
        console.error(`${response.statusCode} | [${method}] ${url} - ${delay}ms`);
        return throwError(error);
      }),
    );
  }
}
typescript nestjs
1个回答
0
投票

由于拦截器之后运行的过滤器,我在记录正确的状态代码时遇到了类似的问题。我能够接受的唯一解决方案就是在拦截器中实现日志记录。与您在代码中的表现非常相似。当拦截器运行后过滤器运行时,可以利用observable在成功完成或错误后执行函数。

对我来说,诀窍是即使在tap或catchError运算符中也无法保证响应上的状态代码正确设置。我通过检查请求的方法来解决这个问题,如果它是POST方法,那么我知道成功的响应是201,否则它总是200。 如果我收到错误,我会从错误中获取状态代码,并使用该代码而不是响应对象上的状态代码。由于我的异常过滤器将在observable完成之前运行,因此我知道此时我的错误对象上将存在statusCode。


0
投票

我最终在原始应用程序上注入了一个经典的记录器。此解决方案不是最好的,因为它没有集成到Nest流程中,但适用于标准日志记录需求。

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { ApplicationModule } from './app.module';
import * as morgan from 'morgan';

async function bootstrap() {
    const app = await NestFactory.create<NestFastifyApplication>(ApplicationModule, new FastifyAdapter());
    app.use(morgan('tiny'));

    await app.listen(process.env.PORT, '0.0.0.0');
}

if (isNaN(parseInt(process.env.PORT))) {
    console.error('No port provided. 👏');
    process.exit(666);
}

bootstrap().then(() => console.log('Service listening 👍: ', process.env.PORT));
© www.soinside.com 2019 - 2024. All rights reserved.