import { mkdirSync } from 'fs'; import log4js from 'log4js'; import { resolve } from 'path'; import { env } from '../config/env'; const LOG_LEVELS = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'] as const; type LogLevel = (typeof LOG_LEVELS)[number]; function resolveLogLevel(): LogLevel { const raw = env.LOG_LEVEL.toLowerCase(); return (LOG_LEVELS as readonly string[]).includes(raw) ? (raw as LogLevel) : 'info'; } /** Resolves LOG_DIR from .env: absolute paths unchanged; relative paths from cwd. */ function resolveLogDir(raw: string): string { const trimmed = raw.trim(); if (!trimmed) { return resolve('logs'); } return resolve(trimmed); } function ensureLogDir(dir: string): void { try { mkdirSync(dir, { recursive: true }); } catch (err) { const msg = err instanceof Error ? err.message : String(err); process.stderr.write(`[kord] Failed to create LOG_DIR "${dir}": ${msg}\n`); throw err; } } const logDir = resolveLogDir(env.LOG_DIR); const level = resolveLogLevel(); ensureLogDir(logDir); log4js.configure({ appenders: { console: { type: 'stdout', layout: { type: 'pattern', pattern: '%[[%p]%] %m', }, }, file: { type: 'dateFile', filename: resolve(logDir, 'kord.log'), pattern: 'yyyy-MM-dd', alwaysIncludePattern: true, numBackups: 7, layout: { type: 'pattern', pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %m', }, }, }, categories: { default: { appenders: ['console', 'file'], level }, }, }); process.on('exit', () => { try { log4js.shutdown(); } catch { // ignore } }); export const logger = log4js.getLogger();