node/src/utils/logger.ts
2025-04-06 20:20:28 +03:00

112 lines
3.6 KiB
TypeScript

import { createLogger, format, transports } from 'winston';
import fs from 'fs';
import path from 'path';
// Create logs directory if it doesn't exist
const logsDir = path.join(process.cwd(), 'logs');
if (!fs.existsSync(logsDir)) {
fs.mkdirSync(logsDir);
}
// Define colors for different service types
const colors: any = {
error: '\x1b[31m', // red
warn: '\x1b[33m', // yellow
info: '\x1b[32m', // green
debug: '\x1b[36m', // cyan
reset: '\x1b[0m', // reset
// Service specific colors
IPFS: '\x1b[36m', // cyan
HEARTBEAT: '\x1b[33m', // yellow
SOCKET: '\x1b[34m', // blue
'LOAD-BALANCER': '\x1b[35m', // magenta
DEFAULT: '\x1b[37m', // white
};
// Custom format for console output with colors
const customConsoleFormat = format.printf(({ level, message, timestamp, service }: any) => {
// Truncate error messages
if (level === 'error' && typeof message === 'string' && message.length > 300) {
message = message.substring(0, 300) + '... [truncated]';
}
// Handle objects and errors
if (typeof message === 'object' && message !== null) {
if (message instanceof Error) {
message = message.message;
// Truncate error messages
if (message.length > 300) {
message = message.substring(0, 300) + '... [truncated]';
}
} else {
try {
message = JSON.stringify(message, null, 2);
} catch (_e) {
message = '[Object]';
}
}
}
const serviceColor = service && colors[service] ? colors[service] : colors.DEFAULT;
const levelColor = colors[level] || colors.DEFAULT;
const serviceTag = service ? `[${service}]` : '';
return `${timestamp} ${levelColor}${level}${colors.reset}: ${serviceColor}${serviceTag}${colors.reset} ${message}`;
});
// Custom format for file output (no colors)
const customFileFormat = format.printf(({ level, message, timestamp, service }) => {
// Handle objects and errors
if (typeof message === 'object' && message !== null) {
if (message instanceof Error) {
message = message.message;
} else {
try {
message = JSON.stringify(message);
} catch (_e) {
message = '[Object]';
}
}
}
const serviceTag = service ? `[${service}]` : '';
return `${timestamp} ${level}: ${serviceTag} ${message}`;
});
// Create the logger
const logger = createLogger({
level: process.env.LOG_LEVEL || 'info',
format: format.combine(format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.splat()),
defaultMeta: { service: 'DEFAULT' },
transports: [
// Console transport
new transports.Console({
format: format.combine(format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), customConsoleFormat),
}),
// Combined log file
new transports.File({
filename: path.join(logsDir, 'app.log'),
format: format.combine(format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), customFileFormat),
}),
// Error log file
new transports.File({
filename: path.join(logsDir, 'error.log'),
level: 'error',
format: format.combine(format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), customFileFormat),
}),
],
});
// Helper function to create a logger for a specific service
export const createServiceLogger = (serviceName: string) => {
return {
error: (message: any, ...meta: any[]) => logger.error(message, { service: serviceName, ...meta }),
warn: (message: any, ...meta: any[]) => logger.warn(message, { service: serviceName, ...meta }),
info: (message: any, ...meta: any[]) => logger.info(message, { service: serviceName, ...meta }),
debug: (message: any, ...meta: any[]) => logger.debug(message, { service: serviceName, ...meta }),
};
};
export default logger;