Kord/src/utils/logger.ts

73 lines
1.7 KiB
TypeScript

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();