import { Inject, Injectable } from '@nestjs/common'; import { PinoLogger } from 'nestjs-pino'; import { LOGGER_OPTIONS } from './constants'; import { LoggerModuleOptions } from './logger.module'; import { ClsService } from 'nestjs-cls'; /** * @interface LoggerMeta * @description Interface representing metadata for logging purposes. * * @property {any} [ctx] - Optional context information to be logged. Used for audit logging. */ interface LoggerMeta { ctx?: any; [key: string]: any; } @Injectable() export class LoggerService { constructor( private readonly logger: PinoLogger, private readonly cls: ClsService, ) {} private withAdditionalTraceId(meta?: LoggerMeta) { const xcTraceId: string | undefined = this.cls.get('xcTraceId'); const xcActionId: string | undefined = this.cls.get('xcActionId'); const xcModule: string | undefined = this.cls.get('xcModule'); const xcDialerCampaign: string | undefined = this.cls.get('xcDialerCampaign'); return { ...meta, xcTraceId: xcTraceId ?? meta?.xcTraceId, xcActionId: xcActionId ?? meta?.xcActionId, xcModule: xcModule ?? meta?.xcModule, xcDialerCampaign: xcDialerCampaign ?? meta?.xcDialerCampaign, }; } debug(msg: string, meta?: LoggerMeta): void { this.logger.debug({ meta: this.withAdditionalTraceId(meta) }, msg); } warn(msg: string, meta?: LoggerMeta): void { this.logger.warn({ meta: this.withAdditionalTraceId(meta) }, msg); } error(msg: string, meta?: LoggerMeta): void { this.logger.error({ meta: this.withAdditionalTraceId(meta) }, msg); } fatal(msg: string, meta?: LoggerMeta): void { this.logger.fatal({ meta: this.withAdditionalTraceId(meta) }, msg); } info(msg: string, meta?: LoggerMeta): void { // LOG EVENTS // // LOG CORRELATION -- You can see correlation between spans and logs // const tracer = api.trace.getTracer(process.env.npm_package_name, process.env.npm_package_version); // tracer.startActiveSpan('try-span', span => { // this.logger.info({ message: 'log correlation...' }, 'ciao'); // span.end(); // }); this.logger.info({ meta: this.withAdditionalTraceId(meta) }, msg); } trace(msg: string, meta?: LoggerMeta): void { this.logger.trace({ meta: this.withAdditionalTraceId(meta) }, msg); } // Esempio di uso corretto: someMethod() { this.cls.run(() => { this.cls.set('xcTraceId', 'my-trace-id'); // Tutto il codice asincrono che parte da qui vedrà il valore this.logger.info('Log con trace id'); // Qui funziona setTimeout(() => { this.logger.info('Anche qui funziona'); }, 100); }); // Qui fuori il valore NON è disponibile } }