1import pino from 'pino';
2
3const logLevel = process.env.NODE_ENV === 'development' ? 'debug' : 'info';
4
5class LoggerService {
6 private static instance: LoggerService;
7 private logger: pino.Logger;
8 private moduleLoggers: Map<string, Logger>;
9
10 private constructor() {
11 this.logger = pino({
12 transport: {
13 target: 'pino-pretty',
14 options: {
15 colorize: true,
16 translateTime: 'HH:MM:ss',
17 ignore: 'pid,hostname',
18 },
19 },
20 level: logLevel,
21 });
22 this.moduleLoggers = new Map();
23 }
24
25 public static getInstance(): LoggerService {
26 if (!LoggerService.instance) {
27 LoggerService.instance = new LoggerService();
28 }
29 return LoggerService.instance;
30 }
31
32 public getLogger(module: string): Logger {
33 if (!this.moduleLoggers.has(module)) {
34 this.moduleLoggers.set(module, {
35 debug: (msg: string, obj = {}) => this.logger.debug({ module, ...obj }, msg),
36 info: (msg: string, obj = {}) => this.logger.info({ module, ...obj }, msg),
37 warn: (msg: string, obj = {}) => this.logger.warn({ module, ...obj }, msg),
38 error: (msg: string, obj = {}) => this.logger.error({ module, ...obj }, msg)
39 });
40 }
41 return this.moduleLoggers.get(module)!;
42 }
43}
44
45export interface Logger {
46 debug: (msg: string, obj?: object) => void;
47 info: (msg: string, obj?: object) => void;
48 warn: (msg: string, obj?: object) => void;
49 error: (msg: string, obj?: object) => void;
50}
51
52// Export a function to get a logger for a specific module
53export const createLogger = (module: string): Logger => {
54 return LoggerService.getInstance().getLogger(module);
55};