220 lines
6.4 KiB
JavaScript
220 lines
6.4 KiB
JavaScript
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;
|