import fs from 'node:fs'; import path from 'node:path'; import winston from 'winston'; import { config } from '../config.js'; fs.mkdirSync(config.logDir, { recursive: true }); const logFormat = winston.format.combine( winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json() ); export const logger = winston.createLogger({ level: config.isProduction ? 'info' : 'debug', format: logFormat, transports: [ new winston.transports.File({ filename: path.join(config.logDir, 'system.log'), maxsize: 5_000_000, maxFiles: 5 }), ...(!config.isProduction ? [new winston.transports.Console({ format: winston.format.combine(winston.format.colorize(), winston.format.simple()) })] : []) ] }); export function readSystemLog(limit = 300) { // System logs are line-delimited JSON; malformed historic lines are returned as plain messages. const file = path.join(config.logDir, 'system.log'); if (!fs.existsSync(file)) return []; const content = fs.readFileSync(file, 'utf8'); return content .trim() .split('\n') .filter(Boolean) .slice(-limit) .map((line) => { try { return JSON.parse(line); } catch { return { level: 'info', message: line }; } }); }