AdvisorServer/html/monitor.html
2025-04-14 15:07:14 +08:00

297 lines
10 KiB
HTML
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.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.15.14/theme-chalk/index.min.css">
<title>Interface Monitor</title>
<script src="https://cdn.staticfile.org/vue/2.7.14/vue.min.js"></script>
<script src="https://cdn.staticfile.org/blueimp-md5/2.19.0/js/md5.min.js"></script>
<script src="https://cdn.staticfile.org/axios/1.6.5/axios.js"></script>
<script src="https://cdn.staticfile.org/element-ui/2.15.14/index.js"></script>
<script src="https://cdn.staticfile.net/dayjs/1.11.10/dayjs.min.js"></script>
<script src="https://cdn.staticfile.net/echarts/5.4.3/echarts.min.js"></script>
<style>
body {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
}
.el-form-item {
display: flex;
height: 50px;
width: 100%;
align-items: center;
justify-content: flex-start;
}
.el-form-item__content {
margin-left: 20px !important;
}
.resu {
margin-left: 30%;
width: 70%;
min-height: 1080px;
}
.line {
width: 1000px;
height: 300px;
}
</style>
</head>
<body>
<div id="app">
<div style="width:30%;position: fixed;padding: 20px 0 0 50px;">
<el-form label-width="80px">
<el-form-item label="Host:">
<div style="width: 108%;">
<el-select v-model="query.host" placeholder="请选择">
<el-option v-for="item in data.host" :key="item" :label="item" :value="item"></el-option>
</el-select>
</div>
</el-form-item>
<el-form-item label="开始时间:">
<el-date-picker v-model="query.startTime" type="datetime" placeholder="选择开始时间">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间:">
<el-date-picker v-model="query.endTime" type="datetime" placeholder="选择结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="IP:">
<el-select v-model="query.ip" placeholder="请选择">
<el-option v-for="item in data.ip" :key="item" :label="item" :value="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="接口:">
<el-select v-model="query.name" placeholder="请选择">
<el-option v-for="item in data.name" :key="item" :label="item" :value="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="分组方式:">
<el-radio v-for="item in data.groupBy" v-model="query.groupBy" :label="item">{{ item }}</el-radio>
</el-form-item>
<el-form-item>
<div style="margin-left: 20%; display: flex;">
<el-button type="primary" @click="listData()">查询曲线</el-button>
<el-button type="primary" @click="groupData()">查询分组</el-button>
</div>
</el-form-item>
</el-form>
</div>
<div class="resu">
<div id="total" class="line"></div>
<div id="average" class="line"></div>
<div id="failure" class="line"></div>
<div id="timeout" class="line"></div>
</div>
</div>
<script>
const HttpReq = axios.create({
// baseURL, // api的base_url
timeout: 10000, // 请求超时时间,
method: "post"
});
HttpReq.interceptors.request.use(config => {
config.data = config.data || {}
config.data.ticket = md5(`hello_syzb_${dayjs().format('YYYYMMDD')}`)
if(config.data.ip == '全部'){
config.data.ip = ''
}
if(config.data.name == '全部'){
config.data.name = ''
}
return config;
}, error => {
return Promise.reject(error);
});
HttpReq.interceptors.response.use(resp => {
if (resp.code) {
console.log({
title: "HttpRequestError-" + resp.code,
content: resp.message,
});
}
return resp.data.data;
})
function post(host, url, data) {
if (!host) {
return;
}
const targetUrl = (host + url)
return HttpReq({
url: targetUrl,
data,
})
}
function fillTimeData(startTime, endTime, data) {
const result = [];
const timeMap = new Map();
// 建立已有数据的映射key 是时间字符串
data.forEach(item => {
timeMap.set(item.time, item);
});
let current = dayjs(startTime).second(0);
console.log(current.minute());
while (current.minute() % 5 !== 0) {
current = current.add(1, 'minute');
}
const end = dayjs(endTime);
console.log(current.isSameOrBefore);
while (current.isBefore(end) || current.isSame(end)) {
const timeStr = current.format('YYYY-MM-DD HH:mm:ss');
if (timeMap.has(timeStr)) {
result.push(timeMap.get(timeStr));
} else {
result.push({
averageTime: 0,
failure: 0,
interfaceName: null,
ip: null,
maxTime: 0,
minTime: 0,
over1000ms: 0,
over100ms: 0,
over10ms: 0,
over5000ms: 0,
over500ms: 0,
over50ms: 0,
time: timeStr,
total: 0
});
}
current = current.add(5, 'minute');
}
return result;
}
function drawLine(data, div, field, filter) {
if (data && data.length) {
const xyData = data.map(v => [v.time, v[field]]);
const myChart = echarts.init(document.getElementById(div));
myChart.setOption({
title: {
text: field
},
xAxis: {
type: 'time',
// data: xDate
},
yAxis: {
type: 'value'
},
tooltip: {
trigger: 'axis'
},
series: [
{
type: 'line',
data: xyData,
showSymbol: false,
}
]
})
}
}
const API = {
listIP: function (host, data) {
return post(host, '/admin/monitor/listIP', data);
},
listInterface: function (host, data) {
return post(host, '/admin/monitor/listInterface', data);
},
listData: function (host, data) {
return post(host, '/admin/monitor/listData', data);
},
groupData: function (host, data) {
return post(host, '/admin/monitor/groupData', data);
},
}
new Vue({
el: '#app',
data() {
return {
query: {
host: "http://8.138.144.54:8080",
// startTime: dayjs().format('YYYY-MM-DD 00:00:00'),
// endTime: dayjs().add(1, 'day').format('YYYY-MM-DD 00:00:00'),
startTime: dayjs().subtract(1, 'day').format('YYYY-MM-DD 00:00:00'),
endTime: dayjs().format('YYYY-MM-DD 00:00:00'),
ip: "",
name: "",
groupBy: "name",
},
data: {
host: ["http://8.138.144.54:8080"],
ip: [],
name: [],
groupBy: ["name", "ip"],
},
monitor: [],
interval: null,
};
},
methods: {
async init() {
const ip = await API.listIP(this.query.host, this.query)
if(ip){
ip.unshift("全部")
this.data.ip = ip;
this.query.ip = ip[0];
}
const name = await API.listInterface(this.query.host, this.query)
if(name){
name.unshift("全部")
this.data.name = name;
this.query.name = name[0];
}
},
async listData() {
let data = await API.listData(this.query.host, this.query);
// console.log('before', data);
data = fillTimeData(this.query.startTime, this.query.endTime, data);
// console.log('after', data);
drawLine(data, 'total', 'total');
drawLine(data, 'average', 'averageTime');
drawLine(data, 'failure', 'failure');
drawLine(data, 'timeout', 'over5000ms');
},
},
async mounted() {
this.init();
},
watch: {
'query.host': async function (newVal) {
if (this.interval) {
clearTimeout(this.interval)
}
this.interval = setTimeout(async () => {
this.init();
}, 100);
},
},
});
</script>
</body>
</html>