UNPKG

coddyger

Version:

Coddyger est une bibliothèque JavaScript/TypeScript qui fournit des fonctions communes et des plugins pour la gestion des données, la communication entre services, et des utilitaires avancés pour le développement d'applications.

175 lines (159 loc) 4.25 kB
import * as path from 'path'; import * as fs from 'fs'; import pino from 'pino'; import coddyger from '../coddyger'; export enum LogLevel { Info = 'info', Debug = 'debug', Warn = 'warn', Error = 'error', Fatal = 'fatal', Trace = 'trace' } export class LoggerService { private static instance: pino.Logger; private static logDirectory: string; private static getInstance(): pino.Logger { if (!LoggerService.instance) { const isProduction = process.env.NODE_ENV === 'production'; const currentDate = coddyger.dateOnlyFormat(new Date().toISOString()); LoggerService.logDirectory = path.join(coddyger.root(), '/src/logs/'); // Création du répertoire de logs s'il n'existe pas if (!fs.existsSync(LoggerService.logDirectory)) { fs.mkdirSync(LoggerService.logDirectory, { recursive: true }); } const transport = pino.transport({ targets: [ // Fichier de logs pour tous les niveaux { target: 'pino/file', options: { destination: path.join(LoggerService.logDirectory, `${currentDate}.log`), mkdir: true }, level: 'trace' }, // Fichier séparé pour les erreurs { target: 'pino/file', options: { destination: path.join(LoggerService.logDirectory, `${currentDate}-error.log`), mkdir: true }, level: 'error' }, // Console avec formatage pretty en développement { target: 'pino-pretty', options: { colorize: true, translateTime: 'SYS:standard', ignore: 'pid,hostname', }, level: isProduction ? 'info' : 'debug' } ] }); LoggerService.instance = pino({ level: isProduction ? 'info' : 'debug', timestamp: pino.stdTimeFunctions.isoTime, formatters: { level: (label) => { return { level: label.toUpperCase() }; } }, redact: { paths: ['password', 'token', 'secret', '*.password', '*.token', '*.secret'], remove: true } }, transport); } return LoggerService.instance; } static log(payload: { type: LogLevel; content: any; location: string; method: string; context?: Record<string, any>; }) { const { type, content, location, method, context = {} } = payload; const logger = LoggerService.getInstance(); const logData = { location, method, ...context, msg: typeof content === 'string' ? content : JSON.stringify(content) }; switch (type) { case LogLevel.Debug: logger.debug(logData); break; case LogLevel.Info: logger.info(logData); break; case LogLevel.Warn: logger.warn(logData); break; case LogLevel.Error: logger.error(logData); break; case LogLevel.Fatal: logger.fatal(logData); break; case LogLevel.Trace: logger.trace(logData); break; default: logger.error({ ...logData, msg: 'Invalid log type' }); } } // Méthodes utilitaires pour un logging plus simple static debug(message: string, context?: Record<string, any>) { this.log({ type: LogLevel.Debug, content: message, location: 'app', method: 'debug', context }); } static info(message: string, context?: Record<string, any>) { this.log({ type: LogLevel.Info, content: message, location: 'app', method: 'info', context }); } static warn(message: string, context?: Record<string, any>) { this.log({ type: LogLevel.Warn, content: message, location: 'app', method: 'warn', context }); } static error(message: string | Error, context?: Record<string, any>) { const errorMessage = message instanceof Error ? message.stack || message.message : message; this.log({ type: LogLevel.Error, content: errorMessage, location: 'app', method: 'error', context }); } static fatal(message: string | Error, context?: Record<string, any>) { const errorMessage = message instanceof Error ? message.stack || message.message : message; this.log({ type: LogLevel.Fatal, content: errorMessage, location: 'app', method: 'fatal', context }); } }