diff --git a/backend/coldstart/server.js b/backend/coldstart/server.js index 19862c14..f3b30b71 100644 --- a/backend/coldstart/server.js +++ b/backend/coldstart/server.js @@ -10,17 +10,47 @@ const config = require("./config.json"); const PORT = config.serverPort || 3014; const WEBHOOK_URL = config.webhookUrl; const LOG_PATH = path.join(__dirname, config.logPath); +const HISTORY_PATH = path.join(__dirname, config.historyPath); const RETRY_COUNT = config.retryCount || 3; +const AUTO_CLEAN_DAYS = config.autoCleanDays || 7; // 确保日志目录存在 if (!fs.existsSync(LOG_PATH)) { fs.mkdirSync(LOG_PATH, { recursive: true }); } +// 初始化历史记录文件 +const initHistoryFile = () => { + if (!fs.existsSync(HISTORY_PATH)) { + fs.writeFileSync(HISTORY_PATH, JSON.stringify([], null, 2), "utf8"); + } +}; +initHistoryFile(); // 日志写入函数 const writeLog = (content) => { const logFile = path.join(LOG_PATH, `warmup-${moment().format("YYYY-MM-DD")}.log`); - const logContent = `[${moment().toISOString()}] ${content}\\n`; + const logContent = `[${moment().toISOString()}] ${content}\n`; fs.appendFileSync(logFile, logContent, "utf8"); }; +// 读取历史记录 +const readHistory = () => { + const rawData = fs.readFileSync(HISTORY_PATH, "utf8"); + return JSON.parse(rawData) || []; +}; +// 写入历史记录 +const writeHistory = (data) => { + fs.writeFileSync(HISTORY_PATH, JSON.stringify(data, null, 2), "utf8"); +}; +// 自动清理旧记录 +const cleanOldHistory = () => { + const history = readHistory(); + const now = moment(); + const filteredHistory = history.filter(item => { + return now.diff(moment(item.timestamp), "days") < AUTO_CLEAN_DAYS; + }); + if (filteredHistory.length !== history.length) { + writeHistory(filteredHistory); + writeLog(`自动清理历史记录:移除${history.length - filteredHistory.length}条超过${AUTO_CLEAN_DAYS}天的记录`); + } +}; // 飞书Webhook通知函数 const sendFeishuWebhook = async (warmupData) => { if (!WEBHOOK_URL) { @@ -63,9 +93,14 @@ const warmup = async () => { elapsed, details }; + // 写入历史记录+自动清理 + const history = readHistory(); + history.push(warmupData); + cleanOldHistory(); + writeHistory(history); + writeLog(`热身完成:${JSON.stringify(warmupData)},已写入历史记录`); // 发送Webhook通知(不阻塞热身流程) sendFeishuWebhook(warmupData); - writeLog(`热身完成:${JSON.stringify(warmupData)}`); return warmupData; }; // 自动热身(带失败重试) @@ -96,7 +131,8 @@ app.get("/warmup/auto", (req, res) => { data: { autoWarmupEnabled: true, retryCount: RETRY_COUNT, - lastRun: moment().subtract(5, "minutes").toISOString() + lastRun: moment().subtract(5, "minutes").toISOString(), + autoCleanDays: AUTO_CLEAN_DAYS } }); }); @@ -105,7 +141,7 @@ app.get("/warmup/logs", (req, res) => { try { const logFile = path.join(LOG_PATH, `warmup-${moment().format("YYYY-MM-DD")}.log`); if (fs.existsSync(logFile)) { - const logs = fs.readFileSync(logFile, "utf8").split("\\n").filter(line => line); + const logs = fs.readFileSync(logFile, "utf8").split("\n").filter(line => line); res.json({ code: 200, msg: "success", data: logs }); } else { res.json({ code: 200, msg: "success", data: ["暂无日志"] }); @@ -131,10 +167,38 @@ app.post("/warmup/notify", async (req, res) => { res.json({ code: 500, msg: "fail", error: error.message }); } }); +// 环节4新增:查询热身历史记录API(支持?days=N筛选) +app.get("/warmup/history", (req, res) => { + try { + const { days } = req.query; + const filterDays = days ? parseInt(days) : AUTO_CLEAN_DAYS; + let history = readHistory(); + const now = moment(); + // 按天数筛选 + if (!isNaN(filterDays)) { + history = history.filter(item => { + return now.diff(moment(item.timestamp), "days") < filterDays; + }); + } + // 按时间倒序排列 + history = history.sort((a, b) => moment(b.timestamp) - moment(a.timestamp)); + res.json({ + code: 200, + msg: "success", + data: { + count: history.length, + filterDays, + records: history + } + }); + } catch (error) { + res.json({ code: 500, msg: "fail", error: error.message }); + } +}); // 启动服务+自动热身 app.listen(PORT, () => { console.log(`冷启动热身服务启动成功,端口:${PORT}`); - writeLog(`服务启动成功,端口:${PORT}`); + writeLog(`服务启动成功,端口:${PORT},自动清理天数:${AUTO_CLEAN_DAYS}天`); autoWarmup(); // 启动时执行自动热身 }); module.exports = app;