web-dev-qa-db-fra.com

Demande de journalisation / réponse à Nest.js

Nouveau à Nest.js,
[.____] J'essaie de mettre en œuvre un enregistreur simple pour rechercher des demandes HTTP telles que:

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

De ma compréhension, le meilleur endroit pour cela serait Intercepteurs . Mais j'utilise aussi gardes et comme mentionné, des gardes sont déclenchés après Middlewares mais avant Intercepteurs.

Signification, mes accès forcés ne sont pas enregistrés. Je pourrais écrire la partie de journalisation dans deux endroits différents mais plutôt pas. Une idée?

Merci!

Mon code d'intercepteur:

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);
      }),
    );
  }
}
16
Julien

J'ai décidé d'utiliser Morgan comme middleware pour intercepter les demandes puisque j'aime les options de formatage, tout en utilisant l'enregistreur de nid standard pour gérer la sortie pour conserver la cohérence avec le reste de mon application.

// middleware/request-logging.ts
import { Logger } from '@nestjs/common';
import morgan, { format } from 'morgan';

export function useRequestLogging(app) {
    const logger = new Logger('Request');
    app.use(
        morgan('tiny', {
            stream: {
                write: (message) => logger.log(message.replace('\n', '')),
            },
        }),
    );
}
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { useRequestLogging } from './middleware/request-logging';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    useRequestLogging(app);
    await app.listen(configService.get<number>('SERVER_PORT'));
    logger.log(`Application is running on: ${await app.getUrl()}`);
}
0
Craig Myles

J'ai eu un problème similaire avec la journalisation du code d'état correct en raison des filtres exécutés après l'intercepteur. La seule solution que je puisse venir à cela, j'étais à l'aise de mettre en œuvre la journalisation de l'intercepteur. Très similaire à la façon dont vous l'avez fait dans votre code. Pendant que le filtre fonctionne une fois que l'intercepteur exécute l'observable peut être levé pour exécuter une fonction après avoir terminé avec succès ou des erreurs.

L'astuce pour moi était que le code de statut de la réponse ne soit pas garanti d'être réglé correctement même dans les opérateurs TAP ou les opérateurs CatchError. J'ai résolu ceci en vérifiant la méthode de la demande et si c'est un POST Méthode, je sais que la réponse réussie est une année, elle est toujours à 200.
[.____] Si je reçois une erreur, je saisis le code d'état de l'erreur et utilisez-le au lieu du code d'état de l'objet de réponse. Étant donné que mon filtre d'exception fonctionnera avant que l'observable complète, je sache qu'un code de statut existera sur mon objet d'erreur pour le moment.

0
gluestick