完善monitor
This commit is contained in:
parent
57baf86fbf
commit
45d58895cf
@ -1,9 +1,9 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||||
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.15.14/theme-chalk/index.min.css">
|
<link href="https://cdn.staticfile.org/element-ui/2.15.14/theme-chalk/index.min.css" rel="stylesheet">
|
||||||
<title>Interface Monitor</title>
|
<title>Interface Monitor</title>
|
||||||
<script src="https://cdn.staticfile.org/vue/2.7.14/vue.min.js"></script>
|
<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/blueimp-md5/2.19.0/js/md5.min.js"></script>
|
||||||
@ -28,17 +28,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item__content {
|
.el-form-item__content {
|
||||||
margin-left: 20px !important;
|
margin-left: 6px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resu {
|
.resu {
|
||||||
margin-left: 30%;
|
margin-left: 360px;
|
||||||
width: 70%;
|
width: 1160px;
|
||||||
min-height: 1080px;
|
min-height: 700px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line {
|
.line {
|
||||||
width: 1000px;
|
width: 1100px;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -46,51 +46,70 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<div style="width:30%;position: fixed;padding: 20px 0 0 50px;">
|
<div style="width:320px; position: fixed; padding: 20px 0 0 30px;">
|
||||||
<el-form label-width="80px">
|
<el-form label-width="80px">
|
||||||
<el-form-item label="Host:">
|
<el-form-item label="Host:">
|
||||||
<div style="width: 108%;">
|
<div style="width: 108%;">
|
||||||
<el-select v-model="query.host" placeholder="请选择">
|
<el-select @change="init()" placeholder="请选择" v-model="query.host">
|
||||||
<el-option v-for="item in data.host" :key="item" :label="item" :value="item"></el-option>
|
<el-option :key="item" :label="item" :value="item" v-for="item in data.host"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="开始时间:">
|
<el-form-item label="开始时间:">
|
||||||
<el-date-picker v-model="query.startTime" type="datetime" placeholder="选择开始时间">
|
<el-date-picker @change="init()" placeholder="选择开始时间" type="datetime" v-model="query.startTime">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="结束时间:">
|
<el-form-item label="结束时间:">
|
||||||
<el-date-picker v-model="query.endTime" type="datetime" placeholder="选择结束时间">
|
<el-date-picker @change="init()" placeholder="选择结束时间" type="datetime" v-model="query.endTime">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="IP:">
|
<el-form-item label="IP:">
|
||||||
<el-select v-model="query.ip" placeholder="请选择">
|
<el-select placeholder="请选择" v-model="query.ip">
|
||||||
<el-option v-for="item in data.ip" :key="item" :label="item" :value="item">
|
<el-option :key="item" :label="item" :value="item" @change="init()" v-for="item in data.ip">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="接口:">
|
<el-form-item label="接口:">
|
||||||
<el-select v-model="query.name" placeholder="请选择">
|
<el-select @change="init(false)" placeholder="请选择" v-model="query.name">
|
||||||
<el-option v-for="item in data.name" :key="item" :label="item" :value="item">
|
<el-option :key="item" :label="item" :value="item" v-for="item in data.name">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="分组方式:">
|
<el-form-item label="分组方式:">
|
||||||
<el-radio v-for="item in data.groupBy" v-model="query.groupBy" :label="item">{{ item }}</el-radio>
|
<el-radio :label="item" @change="groupData()" v-for="item in data.groupBy" v-model="query.groupBy">{{ item }}</el-radio>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<div style="margin-left: 20%; display: flex;">
|
<div style="margin-left: 20%; display: flex;">
|
||||||
<el-button type="primary" @click="listData()">查询曲线</el-button>
|
<el-button @click="listData()" type="primary">查询曲线</el-button>
|
||||||
<el-button type="primary" @click="groupData()">查询分组</el-button>
|
<el-button @click="groupData()" type="primary">查询分组</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="resu">
|
<div class="resu">
|
||||||
<div id="total" class="line"></div>
|
<div id="line" v-show="data.showLine">
|
||||||
<div id="average" class="line"></div>
|
<div class="line" id="total"></div>
|
||||||
<div id="failure" class="line"></div>
|
<div class="line" id="average"></div>
|
||||||
<div id="timeout" class="line"></div>
|
<div class="line" id="failure"></div>
|
||||||
|
<div class="line" id="timeout"></div>
|
||||||
|
</div>
|
||||||
|
<div id="table" v-show="data.showTable">
|
||||||
|
<el-table :data="data.groupData" :default-sort = "{prop: 'total', order: 'descending'}" @sort-change="sortChange" height="700" >
|
||||||
|
<el-table-column label="IP" prop="ip" v-if="query.groupBy === 'ip'" width="120"></el-table-column>
|
||||||
|
<el-table-column label="接口" prop="interfaceName" v-if="query.groupBy === 'name'" width="230"></el-table-column>
|
||||||
|
<el-table-column label="数量" prop="total" width="80" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="失败" prop="failure" width="80" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="平均" prop="averageTime" width="80" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="最大" prop="maxTime" width="80" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="最小" prop="minTime" width="80" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="10ms" prop="over10ms" width="80" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="50ms" prop="over50ms" width="80" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="100ms" prop="over100ms" width="88" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="500ms" prop="over500ms" width="88" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="1000ms" prop="over1000ms" width="96" sortable='custom'></el-table-column>
|
||||||
|
<el-table-column label="5000ms" prop="over5000ms" width="96" sortable='custom'></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -176,20 +195,19 @@
|
|||||||
total: 0
|
total: 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
current = current.add(5, 'minute');
|
current = current.add(5, 'minute');
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawLine(data, div, field, filter) {
|
function drawLine(data, title, div, field, filter) {
|
||||||
if (data && data.length) {
|
if (data && data.length) {
|
||||||
const xyData = data.map(v => [v.time, v[field]]);
|
const xyData = data.map(v => [v.time, v[field]]);
|
||||||
const myChart = echarts.init(document.getElementById(div));
|
const chart = echarts.init(document.getElementById(div));
|
||||||
myChart.setOption({
|
chart.setOption({
|
||||||
title: {
|
title: {
|
||||||
text: field
|
text: title
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
@ -206,6 +224,9 @@
|
|||||||
type: 'line',
|
type: 'line',
|
||||||
data: xyData,
|
data: xyData,
|
||||||
showSymbol: false,
|
showSymbol: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#409eff' // 设置折线的颜色为红色
|
||||||
|
},
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@ -232,38 +253,44 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
query: {
|
query: {
|
||||||
host: "http://8.138.144.54:8080",
|
host: "https://do.tgsys.sztg.com",
|
||||||
// startTime: 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'),
|
// endTime: dayjs().add(1, 'day').format('YYYY-MM-DD 00:00:00'),
|
||||||
startTime: dayjs().subtract(1, 'day').format('YYYY-MM-DD 00:00:00'),
|
startTime: dayjs().format('YYYY-MM-DD 00:00:00'),
|
||||||
endTime: dayjs().format('YYYY-MM-DD 00:00:00'),
|
endTime: dayjs().add(1, 'day').format('YYYY-MM-DD 00:00:00'),
|
||||||
ip: "",
|
ip: "",
|
||||||
name: "",
|
name: "",
|
||||||
groupBy: "name",
|
groupBy: "name",
|
||||||
|
orderBy: "",
|
||||||
},
|
},
|
||||||
data: {
|
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: [],
|
ip: [],
|
||||||
name: [],
|
name: [],
|
||||||
groupBy: ["name", "ip"],
|
groupBy: ["name", "ip"],
|
||||||
|
groupData: [],
|
||||||
|
showLine: false,
|
||||||
|
showTable: false,
|
||||||
},
|
},
|
||||||
monitor: [],
|
monitor: [],
|
||||||
interval: null,
|
interval: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async init() {
|
async init(loadName = true) {
|
||||||
const ip = await API.listIP(this.query.host, this.query)
|
const ip = await API.listIP(this.query.host, this.query)
|
||||||
if(ip){
|
if (ip) {
|
||||||
ip.unshift("全部")
|
ip.unshift("全部")
|
||||||
this.data.ip = ip;
|
this.data.ip = ip;
|
||||||
this.query.ip = ip[0];
|
this.query.ip = ip[0];
|
||||||
}
|
}
|
||||||
const name = await API.listInterface(this.query.host, this.query)
|
if (loadName) {
|
||||||
if(name){
|
const name = await API.listInterface(this.query.host, this.query)
|
||||||
name.unshift("全部")
|
if(name){
|
||||||
this.data.name = name;
|
name.unshift("全部")
|
||||||
this.query.name = name[0];
|
this.data.name = name;
|
||||||
|
this.query.name = name[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async listData() {
|
async listData() {
|
||||||
@ -271,24 +298,40 @@
|
|||||||
// console.log('before', data);
|
// console.log('before', data);
|
||||||
data = fillTimeData(this.query.startTime, this.query.endTime, data);
|
data = fillTimeData(this.query.startTime, this.query.endTime, data);
|
||||||
// console.log('after', data);
|
// console.log('after', data);
|
||||||
drawLine(data, 'total', 'total');
|
drawLine(data, '总流量', 'total', 'total');
|
||||||
drawLine(data, 'average', 'averageTime');
|
drawLine(data, '平均耗时', 'average', 'averageTime');
|
||||||
drawLine(data, 'failure', 'failure');
|
drawLine(data, '失败流量', 'failure', 'failure');
|
||||||
drawLine(data, 'timeout', 'over5000ms');
|
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() {
|
async mounted() {
|
||||||
this.init();
|
this.init();
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'query.host': async function (newVal) {
|
// 'query.host': async function (newVal) {
|
||||||
if (this.interval) {
|
// if (this.interval) {
|
||||||
clearTimeout(this.interval)
|
// clearTimeout(this.interval)
|
||||||
}
|
// }
|
||||||
this.interval = setTimeout(async () => {
|
// this.interval = setTimeout(async () => {
|
||||||
this.init();
|
// this.init();
|
||||||
}, 100);
|
// }, 100);
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -19,6 +19,10 @@ public class MonitorQuery {
|
|||||||
|
|
||||||
private String groupBy;
|
private String groupBy;
|
||||||
|
|
||||||
|
private String orderBy;
|
||||||
|
|
||||||
|
private String order;
|
||||||
|
|
||||||
public LocalDateTime getStartTime() {
|
public LocalDateTime getStartTime() {
|
||||||
return startTime;
|
return startTime;
|
||||||
}
|
}
|
||||||
@ -66,4 +70,20 @@ public class MonitorQuery {
|
|||||||
public void setGroupBy(String groupBy) {
|
public void setGroupBy(String groupBy) {
|
||||||
this.groupBy = 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
package com.syzb.monitor.service;
|
package com.syzb.monitor.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DatePattern;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.crypto.SecureUtil;
|
import cn.hutool.crypto.SecureUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
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.hazelcast.core.HazelcastInstance;
|
||||||
import com.syzb.common.handler.BizException;
|
import com.syzb.common.handler.BizException;
|
||||||
import com.syzb.common.result.ResponseStatus;
|
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.mapper.InterfaceMonitorMapper;
|
||||||
import com.syzb.monitor.query.MonitorQuery;
|
import com.syzb.monitor.query.MonitorQuery;
|
||||||
import com.syzb.monitor.vo.MonitorResult;
|
import com.syzb.monitor.vo.MonitorResult;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.Map;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@ -39,6 +42,23 @@ public class MonitorService {
|
|||||||
// 记录保存天数
|
// 记录保存天数
|
||||||
private static final int SAVE_DAY = 15;
|
private static final int SAVE_DAY = 15;
|
||||||
|
|
||||||
|
// 固定排序字段和列关系,防止SQL注入
|
||||||
|
private static Map<String, String> 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
|
@PostConstruct
|
||||||
private void loadHost() {
|
private void loadHost() {
|
||||||
host = hazelcastInstance.getCluster().getLocalMember().getAddress().getHost();
|
host = hazelcastInstance.getCluster().getLocalMember().getAddress().getHost();
|
||||||
@ -54,13 +74,32 @@ public class MonitorService {
|
|||||||
this.results.add(new MonitorResult(name, time, code));
|
this.results.add(new MonitorResult(name, time, code));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "0 * * * * ?")
|
// 使用自定义线程池+任务实现定时器,避免scheduledEnable条件,只跑admin服务
|
||||||
public void save() {
|
@PostConstruct
|
||||||
List<InterfaceMonitor> list = this.statistic();
|
public void init() {
|
||||||
interfaceMonitorMapper.insertBatchSomeColumn(list);
|
// 创建一个调度线程池
|
||||||
|
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<InterfaceMonitor> list = this.statistic();
|
||||||
|
if (CollUtil.isNotEmpty(list)) {
|
||||||
|
interfaceMonitorMapper.insertBatchSomeColumn(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Scheduled(cron = "0 1 2 * * ?")
|
||||||
public void clear() {
|
public void clear() {
|
||||||
LocalDateTime time = LocalDate.now().minusDays(SAVE_DAY).atStartOfDay();
|
LocalDateTime time = LocalDate.now().minusDays(SAVE_DAY).atStartOfDay();
|
||||||
LambdaQueryWrapper<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>lambdaQuery()
|
LambdaQueryWrapper<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>lambdaQuery()
|
||||||
@ -126,6 +165,11 @@ public class MonitorService {
|
|||||||
} else {
|
} else {
|
||||||
throw new BizException(ResponseStatus.OUTSYS_ERROR);
|
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<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>query()
|
QueryWrapper<InterfaceMonitor> wrapper = Wrappers.<InterfaceMonitor>query()
|
||||||
.select(groupColumn,
|
.select(groupColumn,
|
||||||
"sum(total) as total", "avg(average_time) as average_time", "max(max_time) as max_time", "min(min_time) as min_time",
|
"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)
|
.ge("time", startTime)
|
||||||
.lt("time", endTime)
|
.lt("time", endTime)
|
||||||
.groupBy(groupColumn)
|
.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);
|
return interfaceMonitorMapper.selectList(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user