import { DynamicModule, Global, Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { LoggerModule as LoggerModulePino } from 'nestjs-pino'; import { LoggerService } from './logger.service'; import { LOGGER_OPTIONS } from './constants'; import { ClsModule } from 'nestjs-cls'; export interface LoggerModuleOptions { 'resource.service.name': string; 'resource.service.namespace': string; 'resource.service.version'?: string; 'resource.service.environment'?: string; 'resource.service.deployment.environment'?: string; 'resource.service.deployment.id'?: string; 'resource.service.deployment.revision'?: string; autoLogging?: boolean; } @Global() export class LoggerModule { static forRoot(options: LoggerModuleOptions): DynamicModule { const loggerOptions = { provide: LOGGER_OPTIONS, useValue: options, }; const providers = [LoggerService, loggerOptions]; const exports = [LoggerService, loggerOptions]; return { module: LoggerModule, providers, exports, imports: [ ClsModule, LoggerModulePino.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: async (config: ConfigService) => { const projectName = process.env.npm_package_name || 'default_project'; return { pinoHttp: { customLogLevel: (req, res) => { if (res.statusCode >= 500) return 'error'; if (res.statusCode >= 400) return 'warn'; return 'info'; }, level: config.get('LOG_LEVEL') || 'info', autoLogging: options.autoLogging || true, // customErrorMessage?: ((req: IM, res: SR, error: Error) => string) | undefined; // customErrorMessage: (req, res, error) => { // return 'Auto generated error' + error?.message; // }, // customSuccessMessage(req, res, responseTime) { // return 'Auto generated success'; // }, // autoLogging: true, // level: config.get('LOG_LEVEL') || 'info', // stream: pino.destination(`./logs/info.log`), redact: { paths: ['req.headers.cookie', 'req.headers.authorization'], }, transport: { targets: [ { level: 'debug', target: 'pino-pretty', options: { colorize: true, }, }, // { // level: 'error', // target: 'pino/file', // options: { // destination: './logs/error.log', // }, // }, { level: config.get('LOG_LEVEL') || 'info', target: 'pino/file', options: { destination: process.env.LOG_OUT_DIR ? process.env.LOG_OUT_DIR + `${projectName}.log` : `./logs/${projectName}.log`, mkdir: true, append: true, }, }, ], }, base: { 'resource.service.name': options['resource.service.name'], 'resource.service.namespace': options['resource.service.namespace'], 'resource.service.version': options['resource.service.version'] || process.env.npm_package_version || 'unknown', 'resource.service.environment': options['resource.service.environment'] || process.env.npm_config_environment || process.env.NODE_ENV || 'development', }, // genReqId: () => { // Non't needed with pino instrumentation // const activeSpan = api.trace.getSpan(api.context.active()); // return activeSpan.spanContext().traceId; // }, }, }; }, }), ], }; } }