XNSim/XNSimHtml/routes/ModelMonitor.js

220 lines
6.4 KiB
JavaScript
Raw Permalink Normal View History

const express = require('express');
const router = express.Router();
const { startMonitorModelInfo, stopMonitorModelInfo, getModelInfo } = require('../utils/systemMonitor');
// 存储监控服务的状态
let monitorStatus = {
isMonitoring: false,
lastError: null
};
// 存储模型频率历史数据
const modelFrequencyHistory = new Map(); // Map<modelId, number[]>
const MAX_HISTORY_SIZE = 100;
// 存储模型频率统计
const modelFrequencyStats = new Map(); // Map<modelId, {max: number, min: number, avg: number}>
// 频率转周期单位ms
function frequencyToPeriod(frequency) {
return frequency === 0 ? 0 : (1000 / frequency);
}
// 更新模型频率统计
function updateModelFrequencyStats(modelId, currentFrequency, setFrequency) {
// 初始化历史数据
if (!modelFrequencyHistory.has(modelId)) {
modelFrequencyHistory.set(modelId, []);
}
// 初始化统计数据
if (!modelFrequencyStats.has(modelId)) {
modelFrequencyStats.set(modelId, {
max: setFrequency,
min: setFrequency,
avg: setFrequency
});
}
const history = modelFrequencyHistory.get(modelId);
const stats = modelFrequencyStats.get(modelId);
// 更新最大最小值
stats.max = Math.max(stats.max, currentFrequency);
stats.min = Math.min(stats.min, currentFrequency);
// 更新历史数据
history.push(currentFrequency);
if (history.length > MAX_HISTORY_SIZE) {
history.shift(); // 移除最旧的数据
}
// 计算平均值
stats.avg = history.reduce((sum, freq) => sum + freq, 0) / history.length;
}
// 启动模型监控
router.post('/start', async (req, res) => {
try {
if (monitorStatus.isMonitoring) {
return res.status(400).json({ error: '模型监控已经在运行' });
}
const result = startMonitorModelInfo();
if (result && result.includes('失败')) {
monitorStatus.lastError = result;
return res.status(500).json({ error: result });
}
// 清空历史数据和统计数据
modelFrequencyHistory.clear();
modelFrequencyStats.clear();
monitorStatus.isMonitoring = true;
monitorStatus.lastError = null;
res.json({
message: '模型监控启动成功',
status: monitorStatus
});
} catch (error) {
console.error('启动模型监控失败:', error);
monitorStatus.lastError = error.message;
res.status(500).json({ error: '启动模型监控失败', message: error.message });
}
});
// 停止模型监控
router.post('/stop', async (req, res) => {
try {
if (!monitorStatus.isMonitoring) {
return res.status(400).json({ error: '模型监控未在运行' });
}
stopMonitorModelInfo();
monitorStatus.isMonitoring = false;
monitorStatus.lastError = null;
// 清空历史数据和统计数据
modelFrequencyHistory.clear();
modelFrequencyStats.clear();
res.json({
message: '模型监控停止成功',
status: monitorStatus
});
} catch (error) {
console.error('停止模型监控失败:', error);
monitorStatus.lastError = error.message;
res.status(500).json({ error: '停止模型监控失败', message: error.message });
}
});
// 获取模型信息
router.get('/model-info', async (req, res) => {
try {
if (!monitorStatus.isMonitoring) {
return res.status(400).json({ error: '模型监控未在运行' });
}
const result = getModelInfo();
if (result && result.includes('失败')) {
monitorStatus.lastError = result;
return res.status(500).json({ error: result });
}
// 解析JSON字符串
let data;
try {
data = JSON.parse(result);
} catch (error) {
console.error('解析模型信息JSON失败:', error);
return res.status(500).json({ error: '解析模型信息失败', message: error.message });
}
// 检查数据结构
if (!data || typeof data !== 'object') {
return res.status(500).json({ error: '模型信息数据格式错误' });
}
// 检查顶层modelStatus字段
if (!data.modelStatus || typeof data.modelStatus !== 'object') {
return res.status(500).json({ error: '模型状态数据缺失' });
}
// 构造响应数据
const responseData = Object.entries(data.modelStatus).map(([modelId, model]) => {
// 检查必要字段
const requiredFields = [
'modelName', 'modelID', 'modelStatus', 'modelThreadID',
'modelNode', 'modelPriority', 'modelRunCount',
'modelCurrentFrequency', 'modelSetFrequency'
];
const missingFields = requiredFields.filter(field =>
model[field] === undefined || model[field] === null
);
if (missingFields.length > 0) {
throw new Error(`模型数据不完整: 缺少 ${missingFields.join(', ')}`);
}
// 更新频率统计
updateModelFrequencyStats(
parseInt(modelId),
model.modelCurrentFrequency,
model.modelSetFrequency
);
const stats = modelFrequencyStats.get(parseInt(modelId));
if (!stats) {
throw new Error('模型频率统计数据缺失');
}
// 计算周期值
const currentPeriod = frequencyToPeriod(model.modelCurrentFrequency);
const setPeriod = frequencyToPeriod(model.modelSetFrequency);
const maxPeriod = frequencyToPeriod(stats.min);
const minPeriod = frequencyToPeriod(stats.max);
const avgPeriod = frequencyToPeriod(stats.avg);
return {
id: parseInt(modelId),
name: model.modelName,
status: model.modelStatus,
threadId: model.modelThreadID,
node: model.modelNode,
priority: model.modelPriority,
runCount: model.modelRunCount,
// 频率值
currentFrequency: model.modelCurrentFrequency,
setFrequency: model.modelSetFrequency,
maxFrequency: stats.max,
minFrequency: stats.min,
avgFrequency: stats.avg,
// 周期值单位ms
currentPeriod: currentPeriod,
setPeriod: setPeriod,
maxPeriod: maxPeriod,
minPeriod: minPeriod,
avgPeriod: avgPeriod
};
});
res.json({
data: responseData,
status: monitorStatus
});
} catch (error) {
console.error('获取模型信息失败:', error);
monitorStatus.lastError = error.message;
res.status(500).json({ error: '获取模型信息失败', message: error.message });
}
});
// 获取监控状态
router.get('/status', (req, res) => {
res.json(monitorStatus);
});
module.exports = router;