59 votes

Comment utiliser le service de journalisation de nestjs

J'ai essayé d'utiliser le système interne Logger de nestjs (décrit sur https://docs.nestjs.com/techniques/logger -> mais sans description de la manière de l'utiliser)

Mais j'ai eu des problèmes (j'ai essayé d'injecter LoggerService et ainsi de suite)

Quelqu'un peut-il m'expliquer comment faire ?

0 votes

Vous voulez utiliser le logger dans tous les services automatiquement ? !

159voto

Kim Kern Points 8727

Meilleure pratique

Mieux que d'accéder à la Logger statiquement est de créer une instance pour votre classe :

@Controller()
export class AppController {
  private readonly logger = new Logger(AppController.name);

  @Get()
  async get() {
    this.logger.log('Getting stuff');
  }
}

Pourquoi est-ce mieux ?

  1. Vous pouvez fournir un contexte dans le constructeur comme suit new Logger(AppController.name) afin que le nom de la classe (ou tout autre élément) fasse partie de tous les messages d'enregistrement de cette classe.

  2. Si, à un moment donné, vous souhaitez étendre ou remplacer l'option par défaut LoggerService Vous n'avez pas besoin de modifier le code de votre application en dehors de la définition du nouveau logger. Votre nouveau logger sera automatiquement utilisé. Si vous y accédez de manière statique, il continuera à utiliser l'implémentation par défaut.

    const app = await NestFactory.create(AppModule, {logger: new MyLogger()});

  3. Vous pouvez vous moquer de la Logger dans vos tests :

    module.useLogger(new NoOpLogger());

30voto

Dani Mach Points 301

Vous devez d'abord importer dans votre classe :

import { Logger } from '@nestjs/common';

et vous pourrez alors commencer à vous connecter :

Logger.log('info')
Logger.warn('warning')
Logger.error('something went wrong! ', error)

5 votes

Cela fonctionne, mais la réponse de Kim est meilleure, car vous avez également le nom de la classe dans la sortie.

1 votes

J'ai essayé cela et il n'invoque pas l'implémentation personnalisée s'il est utilisé sans new .

4voto

Joey587 Points 21

Cette réponse pourrait être utile à d'autres personnes qui essaient de mettre en œuvre un CustomLogger. J'essaie de montrer un exemple d'implémentation de logger personnalisé et comment il peut être injecté dans le framework Nestjs.

Je comprends que Nestjs utilise intrinsèquement le logger pino. C'est juste une implémentation personnalisée du service de logger (que vous pouvez remplacer par bunyan, winston, etc.). Voici la structure de dossier que j'utilise :

> src /  
>   modules /
>      database /
>        ...
>        database.module.ts
>      api /
>        services /
>        controllers /
>        interceptors /
>        middlewares /
>        models /
>        schemas /
>      shared /
>        services /
>           app.util.service.ts
>           pino.logger.service.ts
>        utils / 
>        interceptors /
>        filters /
>        main.ts    
>        app.controller.ts    
>        app.service.ts
>        server.util.service.ts 

Voici l'essentiel de la situation. Le service de journalisation est donc implémenté comme suit

import {Injectable, LoggerService, Scope} from "@nestjs/common";
import * as pino from 'pino';
import {AppUtilService} from "./app.util.service";
import * as os from "os";
import {APP_LOG_REDACT, APP_MESSAGE_KEY} from "../utils/app.constants";

    @Injectable({
        scope: Scope.DEFAULT
    })
    export class PinoLoggerService implements LoggerService{
        constructor(private appUtilService: AppUtilService) {

        }

        logService = (fileNameString): pino.Logger => {
            return pino({
                useLevelLabels: true,
                prettyPrint: this.appUtilService.isDevEnv(),
                // tslint:disable-next-line: object-literal-sort-keys
                messageKey: APP_MESSAGE_KEY,
                level: this.appUtilService.getLogLevel(),
                redact: {
                    paths: APP_LOG_REDACT,
                    censor: '**SECRET-INFO**'
                },
                base: {
                    hostName: os.hostname(),
                    platform: os.platform(),
                    processId: process.pid,
                    timestamp: this.appUtilService.getCurrentLocaleTimeZone(),
                    // tslint:disable-next-line: object-literal-sort-keys
                    fileName: this.appUtilService.getFileName(fileNameString),
                },
            });
        }

        debug(message: any, context?: string): any {
        }

        error(message: any, trace?: string, context?: string): any {
        }

        log(message: any, context?: string): any {
        }

        warn(message: any, context?: string): any {
        }

    }

L'implémentation personnalisée est mise en œuvre avec les options qui me sont propres dans pinojs github. J'utilise fastifyjs au lieu d'express (encore une fois pour répondre aux besoins de mon projet). J'ai donc ajouté le logger dans les options du serveur fastify js. Si vous utilisez express, il est préférable de spécifier la nouvelle implémentation personnalisée dans l'adaptateur de l'application Nest comme indiqué ci-dessus.

Mon service utilitaire qui s'occupe de l'implémentation du serveur fastify

import * as fastify from "fastify";
import {Http2Server, Http2ServerRequest, Http2ServerResponse} from "http2";
import {DocumentBuilder, SwaggerModule} from "@nestjs/swagger";
import * as fs from "fs";
import * as path from "path";
import * as uuid from "uuid";
import * as qs from "query-string";
import {PinoLoggerService} from "./modules/shared/services/pino.logger.service";
import {AppUtilService} from "./modules/shared/services/app.util.service";
import {AppConstantsService} from "./modules/shared/services/app.constants.service";
import {AppModel} from "./modules/shared/model/app.model";
import {Reflector} from "@nestjs/core";
export class ServerUtilService {
    private logService;
    private appConstantsService;
    private appUtilServiceInstance: AppUtilService;
    private fastifyInstance: fastify.FastifyInstance<Http2Server, Http2ServerRequest, Http2ServerResponse>;
    constructor() {
        this.appUtilServiceInstance = new AppUtilService();
        this.logService = new PinoLoggerService(this.appUtilServiceInstance);
        this.appConstantsService = new AppConstantsService(this.appUtilServiceInstance);
    }

    retrieveAppConstants(): AppModel {
        return this.appConstantsService.getServerConstants();
    }

    retrieveAppUtilService(): AppUtilService {
        return this.appConstantsService;
    }
    createFastifyServerInstance = (): fastify.FastifyInstance<Http2Server, Http2ServerRequest, Http2ServerResponse> => {
        const serverConstants = this.appConstantsService.getServerConstants();
        const httpsOptions = {
            cert: fs.readFileSync(path.join(process.cwd() + '/https-keys/cert.pem')),
            key: fs.readFileSync(path.join(process.cwd() + '/https-keys/key.pem')),

            allowHTTP1: true,
            rejectUnauthorized: true,
        };
        this.fastifyInstance = fastify({

            http2: true,
            https: httpsOptions,
            bodyLimit: 26214400,
            pluginTimeout: 20000,
            genReqId: () => {
                return uuid.v4().toString();
            },
            requestIdHeader: serverConstants.requestIdHeader,
            modifyCoreObjects: true,
            trustProxy: serverConstants.trustProxy,
            ignoreTrailingSlash: true,
            logger: this.logService,
            querystringParser: (str) => {
                return qs.parse(str);
            },
        });
        this.addContentTypeParser();
        return this.fastifyInstance;
    };

    private addContentTypeParser() {
        this.fastifyInstance.addContentTypeParser('*', (req, done) => {
            let data = '';
            req.on('data', chunk => {
                console.log('inside data listener event');
                return data += chunk; });
            req.on('end', () => {
                done(null,data);
            })
        });
    }

}
export const ServerUtilServiceInstance = new ServerUtilService();

Et dans mon main.ts

async function bootstrap() {
  const fastifyServerInstance = 
  ServerUtilServiceInstance.createFastifyServerInstance();
  const serverConstants = ServerUtilServiceInstance.retrieveAppConstants();
  const app: NestFastifyApplication = await NestFactory.create<NestFastifyApplication>(
      AppModule,
      new FastifyAdapter(fastifyServerInstance)
  );
    ....
    ... // global filters, interceptors, pipes
    ....
    await app.listen(serverConstants.port, '0.0.0.0');

}

2voto

maku_at Points 371

La réponse est simple. Il existe des méthodes statiques sur la classe Logger.

par exemple

static log(message: string, context = '', isTimeDiffEnabled = true) 

Utilisation :

Logger.log('Only a test');

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X