diff --git a/html/monitor.html b/html/monitor.html
index 8235ea9..c1bcc86 100644
--- a/html/monitor.html
+++ b/html/monitor.html
@@ -1,9 +1,9 @@
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
- {{ item }}
+ {{ item }}
- 查询曲线
- 查询分组
+ 查询曲线
+ 查询分组
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -176,20 +195,19 @@
total: 0
});
}
-
current = current.add(5, 'minute');
}
return result;
}
- function drawLine(data, div, field, filter) {
+ function drawLine(data, title, 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({
+ const chart = echarts.init(document.getElementById(div));
+ chart.setOption({
title: {
- text: field
+ text: title
},
xAxis: {
type: 'time',
@@ -206,6 +224,9 @@
type: 'line',
data: xyData,
showSymbol: false,
+ lineStyle: {
+ color: '#409eff' // 设置折线的颜色为红色
+ },
}
]
})
@@ -232,38 +253,44 @@
data() {
return {
query: {
- host: "http://8.138.144.54:8080",
+ host: "https://do.tgsys.sztg.com",
// 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'),
+ startTime: dayjs().format('YYYY-MM-DD 00:00:00'),
+ endTime: dayjs().add(1, 'day').format('YYYY-MM-DD 00:00:00'),
ip: "",
name: "",
groupBy: "name",
+ orderBy: "",
},
data: {
- host: ["http://8.138.144.54:8080"],
+ host: ["https://do.tgsys.sztg.com", "http://8.138.144.54:8080", "http://127.0.0.1:8080"],
ip: [],
name: [],
groupBy: ["name", "ip"],
+ groupData: [],
+ showLine: false,
+ showTable: false,
},
monitor: [],
interval: null,
};
},
methods: {
- async init() {
+ async init(loadName = true) {
const ip = await API.listIP(this.query.host, this.query)
- if(ip){
+ 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];
+ if (loadName) {
+ 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() {
@@ -271,24 +298,40 @@
// 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');
+ drawLine(data, '总流量', 'total', 'total');
+ drawLine(data, '平均耗时', 'average', 'averageTime');
+ drawLine(data, '失败流量', 'failure', 'failure');
+ drawLine(data, '超时流量', 'timeout', 'over5000ms');
+ this.data.showLine = true;
+ this.data.showTable = false;
},
+ async groupData() {
+ let groupData = await API.groupData(this.query.host, this.query);
+ // groupData = groupData.filter(data => data.interfaceName && data.interfaceName.indexOf('/admin/monitor') === -1);
+ this.data.groupData = groupData;
+ this.data.showLine = false;
+ this.data.showTable = true;
+ },
+ async sortChange({column, prop, order}) {
+ console.log('sortChange', column, prop, order);
+ this.query.orderBy = prop;
+ this.query.order = order;
+ console.log(this.query);
+ this.groupData();
+ }
},
async mounted() {
this.init();
},
watch: {
- 'query.host': async function (newVal) {
- if (this.interval) {
- clearTimeout(this.interval)
- }
- this.interval = setTimeout(async () => {
- this.init();
- }, 100);
- },
+ // 'query.host': async function (newVal) {
+ // if (this.interval) {
+ // clearTimeout(this.interval)
+ // }
+ // this.interval = setTimeout(async () => {
+ // this.init();
+ // }, 100);
+ // },
},
});
diff --git a/src/main/java/com/syzb/monitor/query/MonitorQuery.java b/src/main/java/com/syzb/monitor/query/MonitorQuery.java
index a949a06..ad2f60a 100644
--- a/src/main/java/com/syzb/monitor/query/MonitorQuery.java
+++ b/src/main/java/com/syzb/monitor/query/MonitorQuery.java
@@ -19,6 +19,10 @@ public class MonitorQuery {
private String groupBy;
+ private String orderBy;
+
+ private String order;
+
public LocalDateTime getStartTime() {
return startTime;
}
@@ -66,4 +70,20 @@ public class MonitorQuery {
public void setGroupBy(String groupBy) {
this.groupBy = groupBy;
}
+
+ public String getOrderBy() {
+ return orderBy;
+ }
+
+ public void setOrderBy(String orderBy) {
+ this.orderBy = orderBy;
+ }
+
+ public String getOrder() {
+ return order;
+ }
+
+ public void setOrder(String order) {
+ this.order = order;
+ }
}
diff --git a/src/main/java/com/syzb/monitor/service/MonitorService.java b/src/main/java/com/syzb/monitor/service/MonitorService.java
index 479b55c..7e82f12 100644
--- a/src/main/java/com/syzb/monitor/service/MonitorService.java
+++ b/src/main/java/com/syzb/monitor/service/MonitorService.java
@@ -1,11 +1,14 @@
package com.syzb.monitor.service;
+import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.hazelcast.core.HazelcastInstance;
import com.syzb.common.handler.BizException;
import com.syzb.common.result.ResponseStatus;
@@ -13,16 +16,16 @@ import com.syzb.monitor.entity.InterfaceMonitor;
import com.syzb.monitor.mapper.InterfaceMonitorMapper;
import com.syzb.monitor.query.MonitorQuery;
import com.syzb.monitor.vo.MonitorResult;
-import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Service
@@ -39,6 +42,23 @@ public class MonitorService {
// 记录保存天数
private static final int SAVE_DAY = 15;
+ // 固定排序字段和列关系,防止SQL注入
+ private static Map
ORDER_BY_MAP = new HashMap<>();
+
+ static {
+ ORDER_BY_MAP.put("total", "total");
+ ORDER_BY_MAP.put("averageTime", "average_time");
+ ORDER_BY_MAP.put("maxTime", "max_time");
+ ORDER_BY_MAP.put("minTime", "min_time");
+ ORDER_BY_MAP.put("failure", "failure");
+ ORDER_BY_MAP.put("over10ms", "over_10ms");
+ ORDER_BY_MAP.put("over50ms", "over_50ms");
+ ORDER_BY_MAP.put("over100ms", "over_100ms");
+ ORDER_BY_MAP.put("over500ms", "over_500ms");
+ ORDER_BY_MAP.put("over1000ms", "over_1000ms");
+ ORDER_BY_MAP.put("over5000ms", "over_5000ms");
+ }
+
@PostConstruct
private void loadHost() {
host = hazelcastInstance.getCluster().getLocalMember().getAddress().getHost();
@@ -54,13 +74,32 @@ public class MonitorService {
this.results.add(new MonitorResult(name, time, code));
}
- @Scheduled(cron = "0 * * * * ?")
- public void save() {
- List list = this.statistic();
- interfaceMonitorMapper.insertBatchSomeColumn(list);
+ // 使用自定义线程池+任务实现定时器,避免scheduledEnable条件,只跑admin服务
+ @PostConstruct
+ public void init() {
+ // 创建一个调度线程池
+ ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
+
+ // 每分钟 保存日志
+ scheduler.scheduleAtFixedRate(() -> save(), 1, 1, TimeUnit.MINUTES);
+
+ // 每天 清理日子
+ scheduler.scheduleAtFixedRate(() -> clear(), 0, 1, TimeUnit.DAYS);
}
- @Scheduled(cron = "0 1 2 * * ?")
+// @Scheduled(cron = "0 * * * * ?")
+ public void save() {
+ // 5分钟执行一次
+ if (LocalDateTime.now().getMinute() % 5 != 0) {
+ return;
+ }
+ List list = this.statistic();
+ if (CollUtil.isNotEmpty(list)) {
+ interfaceMonitorMapper.insertBatchSomeColumn(list);
+ }
+ }
+
+// @Scheduled(cron = "0 1 2 * * ?")
public void clear() {
LocalDateTime time = LocalDate.now().minusDays(SAVE_DAY).atStartOfDay();
LambdaQueryWrapper wrapper = Wrappers.lambdaQuery()
@@ -126,6 +165,11 @@ public class MonitorService {
} else {
throw new BizException(ResponseStatus.OUTSYS_ERROR);
}
+ String orderBy = query.getOrderBy();
+ if (StrUtil.isNotEmpty(orderBy)) {
+ orderBy = ORDER_BY_MAP.get(orderBy);
+ }
+ String order = query.getOrder();
QueryWrapper wrapper = Wrappers.query()
.select(groupColumn,
"sum(total) as total", "avg(average_time) as average_time", "max(max_time) as max_time", "min(min_time) as min_time",
@@ -134,7 +178,9 @@ public class MonitorService {
.ge("time", startTime)
.lt("time", endTime)
.groupBy(groupColumn)
- .orderByAsc(groupColumn);
+ .orderByAsc(StrUtil.isEmpty(orderBy) || (!"ascending".equals(order) && !"descending".equals(order)), groupColumn)
+ .orderByAsc(StrUtil.isNotEmpty(orderBy) && "ascending".equals(order), orderBy)
+ .orderByDesc(StrUtil.isNotEmpty(orderBy) && "descending".equals(order), orderBy);
return interfaceMonitorMapper.selectList(wrapper);
}