|
|
import fs from 'fs'; |
|
|
|
|
|
|
|
|
export const LogLevel = { |
|
|
DEBUG: 'DEBUG', |
|
|
INFO: 'INFO', |
|
|
WARN: 'WARN', |
|
|
ERROR: 'ERROR' |
|
|
}; |
|
|
|
|
|
|
|
|
const LOG_CONFIG = { |
|
|
logFile: './logs/app.log', |
|
|
logDir: './logs', |
|
|
enableConsole: true, |
|
|
enableFile: true, |
|
|
logLevel: LogLevel.INFO |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function ensureLogDirectory() { |
|
|
if (!fs.existsSync(LOG_CONFIG.logDir)) { |
|
|
fs.mkdirSync(LOG_CONFIG.logDir, { recursive: true }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function formatMessage(...args) { |
|
|
return args.map(arg => |
|
|
typeof arg === 'object' ? JSON.stringify(arg) : String(arg) |
|
|
).join(' '); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function writeToFile(level, message) { |
|
|
if (!LOG_CONFIG.enableFile) return; |
|
|
|
|
|
ensureLogDirectory(); |
|
|
const timestamp = new Date().toISOString(); |
|
|
const logEntry = `[${timestamp}] [${level}] ${message}\n`; |
|
|
|
|
|
try { |
|
|
fs.appendFileSync(LOG_CONFIG.logFile, logEntry); |
|
|
} catch (error) { |
|
|
|
|
|
console.error('写入日志文件失败:', error); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function writeToConsole(level, ...args) { |
|
|
if (!LOG_CONFIG.enableConsole) return; |
|
|
|
|
|
switch (level) { |
|
|
case LogLevel.DEBUG: |
|
|
console.debug(...args); |
|
|
break; |
|
|
case LogLevel.INFO: |
|
|
console.log(...args); |
|
|
break; |
|
|
case LogLevel.WARN: |
|
|
console.warn(...args); |
|
|
break; |
|
|
case LogLevel.ERROR: |
|
|
console.error(...args); |
|
|
break; |
|
|
default: |
|
|
console.log(...args); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function writeLog(level, ...args) { |
|
|
const message = formatMessage(...args); |
|
|
|
|
|
|
|
|
writeToConsole(level, ...args); |
|
|
|
|
|
|
|
|
writeToFile(level, message); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function debug(...args) { |
|
|
writeLog(LogLevel.DEBUG, ...args); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function info(...args) { |
|
|
writeLog(LogLevel.INFO, ...args); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function warn(...args) { |
|
|
writeLog(LogLevel.WARN, ...args); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function error(...args) { |
|
|
writeLog(LogLevel.ERROR, ...args); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function getRecentLogs(lines = 100) { |
|
|
try { |
|
|
if (!fs.existsSync(LOG_CONFIG.logFile)) { |
|
|
return []; |
|
|
} |
|
|
|
|
|
const content = fs.readFileSync(LOG_CONFIG.logFile, 'utf8'); |
|
|
const logLines = content.trim().split('\n').filter(line => line.length > 0); |
|
|
|
|
|
|
|
|
return logLines.slice(-lines); |
|
|
} catch (err) { |
|
|
console.error('读取日志文件失败:', err); |
|
|
return []; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function clearLogFile() { |
|
|
try { |
|
|
ensureLogDirectory(); |
|
|
fs.writeFileSync(LOG_CONFIG.logFile, ''); |
|
|
info('日志文件已清空'); |
|
|
return true; |
|
|
} catch (err) { |
|
|
error('清空日志文件失败:', err); |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function configureLogger(config = {}) { |
|
|
Object.assign(LOG_CONFIG, config); |
|
|
} |
|
|
|
|
|
|
|
|
export const log = info; |
|
|
export const logError = error; |
|
|
|
|
|
|
|
|
export default { |
|
|
debug, |
|
|
info, |
|
|
warn, |
|
|
error, |
|
|
log: info, |
|
|
logError: error, |
|
|
getRecentLogs, |
|
|
clearLogFile, |
|
|
configureLogger, |
|
|
LogLevel |
|
|
}; |
|
|
|