智能错误检测 + 提示版本(原生 HTML + JS + ECharts),这样:
3 B" h- R( `$ Y3 d* I如果数据为空或 metricId 未定义,会显示 “暂无监控数据”;
# b& W! A2 o3 {8 [1 x- k如果 Gnocchi API 401(Token 过期),会提示 “Token 无效”;
5 [; [$ T9 n, h( _+ ~. X: m- m7 e
如果取到数据,则正常绘图。
* T# e2 ^0 q$ ~) e5 X3 T# I6 Q✅ 完整示例(直接可替换你的前端代码)
$ e u. d9 H6 V假设你模板变量是 metrics 和 token:
! @1 s! n" R6 u8 ?3 X# O8 ]<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>资源监控</title>
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<style>
.chart-box {
width: 48%;
height: 300px;
display: inline-block;
margin: 10px;
border: 1px solid #eee;
position: relative;
}
.chart-error {
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
color: #888;
font-size: 14px;
}
</style>
</head>
<body>
<h2>资源监控</h2>
% E5 E5 u% K6 S' ~, P I0 z <div id="cpu" class="chart-box"></div>
<div id="memory" class="chart-box"></div>
<div id="disk" class="chart-box"></div>
<div id="network" class="chart-box"></div>
% V* S* x6 h6 ]" v
<script>
const metrics = {
cpu: "{{ metrics.cpu }}",
memory: "{{ metrics.memory.usage }}",
disk: "{{ metrics.disk.root.size }}",
network: "{{ metrics.compute.instance.booting.time }}"
};
! O' r! |5 c- ~2 r
const token = "{{ token }}"; // 后端传入 Keystone Token
& T, z+ g. q3 B4 E2 z. a& e const charts = {
cpu: echarts.init(document.getElementById('cpu')),
memory: echarts.init(document.getElementById('memory')),
disk: echarts.init(document.getElementById('disk')),
network: echarts.init(document.getElementById('network'))
};
- }9 _9 u) j+ s7 _/ z& A4 g% z const titles = {
cpu: "CPU 使用率",
memory: "内存使用率",
disk: "磁盘 I/O",
network: "网络活动"
};
" b4 d; b6 F6 t T1 x: z
const colors = {
cpu: "#e74c3c",
memory: "#3498db",
disk: "#2ecc71",
network: "#9b59b6"
};
* F6 K7 B: g# Y9 b+ w, T/ ?
async function loadMetric(chart, metricId, title, color) {
// 没有 metricId,直接提示
if (!metricId || metricId === 'None' || metricId === 'undefined') {
chart.clear();
chart.getDom().innerHTML = `<div class="chart-error">⚠️ 暂无监控数据</div>`;
return;
}
5 h8 z0 v" P Z# f9 w0 t2 C try {
const res = await fetch(`http://controller:8041/v1/metric/${metricId}/measures`, {
headers: { "X-Auth-Token": token }
});
2 C/ R; L' J5 j* p
if (res.status === 401) {
chart.getDom().innerHTML = `<div class="chart-error">