96 lines
2.4 KiB
JavaScript
96 lines
2.4 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// 日志级别枚举
|
|
const LOG_LEVELS = {
|
|
ERROR: 0,
|
|
WARN: 1,
|
|
INFO: 2,
|
|
DEBUG: 3,
|
|
};
|
|
|
|
// 创建logs目录
|
|
const logsDir = path.join(__dirname, 'logs');
|
|
if (!fs.existsSync(logsDir)) {
|
|
fs.mkdirSync(logsDir);
|
|
}
|
|
|
|
// 日志记录器类
|
|
class Logger {
|
|
constructor(level = 'INFO') {
|
|
this.level = LOG_LEVELS[level.toUpperCase()] || LOG_LEVELS.INFO;
|
|
this.logFilePath = path.join(logsDir, `server-${new Date().toISOString().split('T')[0]}.log`);
|
|
}
|
|
|
|
_shouldLog(level) {
|
|
return LOG_LEVELS[level.toUpperCase()] <= this.level;
|
|
}
|
|
|
|
_writeLog(level, message, meta = {}) {
|
|
if (!this._shouldLog(level)) return;
|
|
|
|
const timestamp = new Date().toISOString();
|
|
const logEntry = {
|
|
timestamp,
|
|
level,
|
|
message,
|
|
...meta,
|
|
};
|
|
|
|
// 控制台输出
|
|
console.log(`[${timestamp}] [${level}] ${message}`, meta);
|
|
|
|
// 文件输出
|
|
try {
|
|
const logLine = JSON.stringify(logEntry) + '\n';
|
|
fs.appendFileSync(this.logFilePath, logLine);
|
|
} catch (err) {
|
|
console.error('Failed to write to log file:', err);
|
|
}
|
|
}
|
|
|
|
error(message, meta = {}) {
|
|
this._writeLog('ERROR', message, meta);
|
|
}
|
|
|
|
warn(message, meta = {}) {
|
|
this._writeLog('WARN', message, meta);
|
|
}
|
|
|
|
info(message, meta = {}) {
|
|
this._writeLog('INFO', message, meta);
|
|
}
|
|
|
|
debug(message, meta = {}) {
|
|
this._writeLog('DEBUG', message, meta);
|
|
}
|
|
|
|
// HTTP请求日志专用方法
|
|
http(req, res, startTime, error = null) {
|
|
const duration = Date.now() - startTime;
|
|
const logMeta = {
|
|
method: req.method,
|
|
url: req.url,
|
|
statusCode: res.statusCode,
|
|
duration: `${duration}ms`,
|
|
userAgent: req.headers['user-agent'],
|
|
ip: req.ip || req.connection.remoteAddress,
|
|
...(error ? { error: error.message || error } : {})
|
|
};
|
|
|
|
const statusCategory = Math.floor(res.statusCode / 100);
|
|
let level = 'INFO';
|
|
if (error || statusCategory >= 5) {
|
|
level = 'ERROR';
|
|
} else if (statusCategory >= 4) {
|
|
level = 'WARN';
|
|
}
|
|
|
|
this._writeLog(level, `HTTP ${req.method} ${req.url} ${res.statusCode} ${duration}ms`, logMeta);
|
|
}
|
|
}
|
|
|
|
// 创建全局日志实例
|
|
const logger = new Logger(process.env.LOG_LEVEL || 'INFO');
|
|
|
|
module.exports = { logger, LOG_LEVELS }; |