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;
|