// Modul logger untuk aplikasi const winston = require('winston'); const path = require('path'); const fs = require('fs'); // Buat direktori logs jika belum ada const logsDir = path.join(process.cwd(), 'logs'); if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir, { recursive: true }); } // Format untuk log const logFormat = winston.format.printf(({ level, message, timestamp }) => { return `${timestamp} ${level}: ${message}`; }); // Konfigurasi logger const logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', exitOnError: false, // Jangan exit saat uncaught exception (e.g. koneksi MikroTik gagal) format: winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat ), transports: [ // Log ke file new winston.transports.File({ filename: path.join(logsDir, 'error.log'), level: 'error' }), new winston.transports.File({ filename: path.join(logsDir, 'combined.log') }), // Log ke console new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat ) }) ], exceptionHandlers: [ new winston.transports.File({ filename: path.join(logsDir, 'exceptions.log') }), new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat ) }) ], rejectionHandlers: [ new winston.transports.File({ filename: path.join(logsDir, 'rejections.log') }) ] }); module.exports = { logger };