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
text/typescript
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
});
}
}