XNSim/XNSimHtml/routes/SystemMonitor.js

249 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express');
const router = express.Router();
const { startMonitorSystemInfo, stopMonitorSystemInfo, getSystemInfo, getAllThreadInfo } = require('../modules/cleanup');
// 存储监控服务的状态
let monitorStatus = {
isMonitoring: false,
lastError: null
};
// 存储线程频率历史数据
const threadFrequencyHistory = new Map(); // Map<threadId, number[]>
const MAX_HISTORY_SIZE = 100;
// 存储线程频率统计
const threadFrequencyStats = new Map(); // Map<threadId, {max: number, min: number, avg: number}>
// 频率转周期单位ms
function frequencyToPeriod(frequency) {
return frequency === 0 ? 0 : (1000 / frequency);
}
// 更新线程频率统计
function updateThreadFrequencyStats(threadId, currentFrequency, setFrequency) {
// 初始化历史数据
if (!threadFrequencyHistory.has(threadId)) {
threadFrequencyHistory.set(threadId, []);
}
// 初始化统计数据
if (!threadFrequencyStats.has(threadId)) {
threadFrequencyStats.set(threadId, {
max: setFrequency,
min: setFrequency,
avg: setFrequency
});
}
const history = threadFrequencyHistory.get(threadId);
const stats = threadFrequencyStats.get(threadId);
// 更新最大最小值
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 = startMonitorSystemInfo();
if (result && result.includes('失败')) {
monitorStatus.lastError = result;
return res.status(500).json({ error: result });
}
// 清空历史数据和统计数据
threadFrequencyHistory.clear();
threadFrequencyStats.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: '系统监控未在运行' });
}
stopMonitorSystemInfo();
monitorStatus.isMonitoring = false;
monitorStatus.lastError = null;
// 清空历史数据和统计数据
threadFrequencyHistory.clear();
threadFrequencyStats.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('/system-info', async (req, res) => {
try {
if (!monitorStatus.isMonitoring) {
return res.status(400).json({ error: '系统监控未在运行' });
}
const result = getSystemInfo();
if (result && result.includes('失败')) {
monitorStatus.lastError = result;
return res.status(500).json({ error: result });
}
// 解析JSON字符串
const data = JSON.parse(result);
const engineStatus = data.engineStatus;
// 构造响应数据
const responseData = {
engineInfo: {
name: engineStatus.engineName,
id: engineStatus.engineID,
status: engineStatus.engineStatus,
affinity: engineStatus.engineAffinity,
threadCount: engineStatus.threadCount
},
coreStatus: {
fw: engineStatus.coreStatus.fwStatus,
tm: engineStatus.coreStatus.tmStatus,
em: engineStatus.coreStatus.emStatus,
sd: engineStatus.coreStatus.sdStatus,
thm: engineStatus.coreStatus.thmStatus,
mm: engineStatus.coreStatus.mmStatus,
sm: engineStatus.coreStatus.smStatus,
dm: engineStatus.coreStatus.dmStatus
}
};
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('/thread-info', async (req, res) => {
try {
if (!monitorStatus.isMonitoring) {
return res.status(400).json({ error: '系统监控未在运行' });
}
const result = getAllThreadInfo();
if (result && result.includes('失败')) {
monitorStatus.lastError = result;
return res.status(500).json({ error: result });
}
// 解析JSON字符串
const data = JSON.parse(result);
if (!data.threadStatus) {
return res.status(500).json({ error: '线程状态数据缺失' });
}
const threadStatus = data.threadStatus;
// 构造响应数据
const responseData = Object.entries(threadStatus).map(([threadId, thread]) => {
if (!thread.threadCurrentFrequency || !thread.threadSetFrequency ||
!thread.threadName || !thread.threadAffinity ||
!thread.threadPro || !thread.threadRunCount ||
!thread.threadStatus) {
throw new Error('线程数据不完整');
}
// 更新频率统计
updateThreadFrequencyStats(
parseInt(threadId),
thread.threadCurrentFrequency,
thread.threadSetFrequency
);
const stats = threadFrequencyStats.get(parseInt(threadId));
if (!stats) {
throw new Error('线程频率统计数据缺失');
}
// 计算周期值
const currentPeriod = frequencyToPeriod(thread.threadCurrentFrequency);
const setPeriod = frequencyToPeriod(thread.threadSetFrequency);
const maxPeriod = frequencyToPeriod(stats.min);
const minPeriod = frequencyToPeriod(stats.max);
const avgPeriod = frequencyToPeriod(stats.avg);
return {
id: parseInt(threadId),
name: thread.threadName,
affinity: thread.threadAffinity,
priority: thread.threadPro,
runCount: thread.threadRunCount,
status: thread.threadStatus,
// 频率值
currentFrequency: thread.threadCurrentFrequency,
setFrequency: thread.threadSetFrequency,
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;