This commit is contained in:
shiziyuan9527 2020-10-28 16:42:45 +08:00
commit f3f496b484
4 changed files with 504 additions and 324 deletions

View File

@ -1,6 +1,6 @@
package io.metersphere.commons.constants;
public enum ReportKeys {
LoadChart, ResponseTimeChart, Errors, ErrorsTop5, RequestStatistics, Overview, TimeInfo, ResultStatus
LoadChart, ResponseTimeChart, ResponseCodeChart, Errors, ErrorsTop5, RequestStatistics, Overview, TimeInfo, ResultStatus, ErrorsChart
}

View File

@ -95,6 +95,16 @@ public class PerformanceReportController {
return reportService.getResponseTimeChartData(reportId);
}
@GetMapping("/content/error_chart/{reportId}")
public List<ChartsData> getErrorChartData(@PathVariable String reportId) {
return reportService.getErrorChartData(reportId);
}
@GetMapping("/content/response_code_chart/{reportId}")
public List<ChartsData> getResponseCodeChartData(@PathVariable String reportId) {
return reportService.getResponseCodeChartData(reportId);
}
@GetMapping("/{reportId}")
public LoadTestReportWithBLOBs getLoadTestReport(@PathVariable String reportId) {
return reportService.getLoadTestReport(reportId);

View File

@ -256,4 +256,16 @@ public class ReportService {
List<String> ids = reportRequest.getIds();
ids.forEach(this::deleteReport);
}
public List<ChartsData> getErrorChartData(String id) {
checkReportStatus(id);
String content = getContent(id, ReportKeys.ErrorsChart);
return JSON.parseArray(content, ChartsData.class);
}
public List<ChartsData> getResponseCodeChartData(String id) {
checkReportStatus(id);
String content = getContent(id, ReportKeys.ResponseCodeChart);
return JSON.parseArray(content, ChartsData.class);
}
}

View File

@ -4,7 +4,7 @@
<el-col :span="4">
<el-card shadow="always" class="ms-card-index-1">
<span class="ms-card-data">
<span class="ms-card-data-digital">{{maxUsers}}</span>
<span class="ms-card-data-digital">{{ maxUsers }}</span>
<span class="ms-card-data-unit"> VU</span>
</span>
<span class="ms-card-desc">Max Users</span>
@ -13,7 +13,7 @@
<el-col :span="4">
<el-card shadow="always" class="ms-card-index-2">
<span class="ms-card-data">
<span class="ms-card-data-digital">{{avgThroughput}}</span>
<span class="ms-card-data-digital">{{ avgThroughput }}</span>
<span class="ms-card-data-unit"> Hits/s</span>
</span>
<span class="ms-card-desc">Avg.Throughput</span>
@ -22,7 +22,7 @@
<el-col :span="4">
<el-card shadow="always" class="ms-card-index-3">
<span class="ms-card-data">
<span class="ms-card-data-digital">{{errors}}</span>
<span class="ms-card-data-digital">{{ errors }}</span>
<span class="ms-card-data-unit"> %</span>
</span>
<span class="ms-card-desc">Errors</span>
@ -31,7 +31,7 @@
<el-col :span="4">
<el-card shadow="always" class="ms-card-index-4">
<span class="ms-card-data">
<span class="ms-card-data-digital">{{avgResponseTime}}</span>
<span class="ms-card-data-digital">{{ avgResponseTime }}</span>
<span class="ms-card-data-unit"> s</span>
</span>
<span class="ms-card-desc">Avg.Response Time</span>
@ -40,7 +40,7 @@
<el-col :span="4">
<el-card shadow="always" class="ms-card-index-5">
<span class="ms-card-data">
<span class="ms-card-data-digital">{{responseTime90}}</span>
<span class="ms-card-data-digital">{{ responseTime90 }}</span>
<span class="ms-card-data-unit"> s</span>
</span>
<span class="ms-card-desc">90% Response Time</span>
@ -49,7 +49,7 @@
<el-col :span="4">
<el-card shadow="always" class="ms-card-index-6">
<span class="ms-card-data">
<span class="ms-card-data-digital">{{avgBandwidth}}</span>
<span class="ms-card-data-digital">{{ avgBandwidth }}</span>
<span class="ms-card-data-unit"> KiB/s</span>
</span>
<span class="ms-card-desc">Avg.Bandwidth</span>
@ -65,6 +65,14 @@
<ms-chart ref="chart2" :options="resOption" class="chart-config" :autoresize="true"></ms-chart>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<ms-chart ref="chart3" :options="errorOption" class="chart-config" :autoresize="true"></ms-chart>
</el-col>
<el-col :span="12">
<ms-chart ref="chart3" :options="resCodeOption" class="chart-config" :autoresize="true"></ms-chart>
</el-col>
</el-row>
</div>
</template>
@ -84,6 +92,8 @@ export default {
avgBandwidth: "0",
loadOption: {},
resOption: {},
errorOption: {},
resCodeOption: {},
id: ''
}
},
@ -106,6 +116,12 @@ export default {
this.avgBandwidth = '0';
this.$warning(this.$t('report.generation_error'));
})
this.getLoadChart();
this.getResChart();
this.getErrorChart();
this.getResponseCodeChart();
},
getLoadChart() {
this.$get("/performance/report/content/load_chart/" + this.id).then(res => {
let data = res.data.data;
let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis);
@ -181,6 +197,8 @@ export default {
}).catch(() => {
this.loadOption = {};
})
},
getResChart() {
this.$get("/performance/report/content/res_chart/" + this.id).then(res => {
let data = res.data.data;
let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis);
@ -264,6 +282,146 @@ export default {
this.resOption = {};
})
},
getErrorChart() {
this.$get("/performance/report/content/error_chart/" + this.id).then(res => {
let data = res.data.data;
let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis);
let yAxisListMax = this._getChartMax(yAxisList);
let yAxisIndex0List = data.filter(m => m.yAxis2 === -1).map(m => m.groupName);
yAxisIndex0List = this._unique(yAxisIndex0List);
let errorOption = {
title: {
text: 'Errors',
left: 'center',
top: 20,
textStyle: {
color: '#99743C'
},
},
tooltip: {
show: true,
trigger: 'axis',
extraCssText: 'z-index: 999;',
formatter: function (params, ticket, callback) {
let result = "";
let name = params[0].name;
result += name + "<br/>";
for (let i = 0; i < params.length; i++) {
let seriesName = params[i].seriesName;
if (seriesName.length > 100) {
seriesName = seriesName.substring(0, 100);
}
let value = params[i].value;
let marker = params[i].marker;
result += marker + seriesName + ": " + value[1] + "<br/>";
}
return result;
}
},
legend: {},
xAxis: {},
yAxis: [
{
name: 'No',
type: 'value',
min: 0,
max: yAxisListMax,
interval: yAxisListMax / 5
}
],
series: []
}
let setting = {
series: [
{
name: 'users',
color: '#0CA74A',
}
]
}
yAxisIndex0List.forEach(item => {
setting["series"].splice(0, 0, {name: item, yAxisIndex: '0'})
})
this.errorOption = this.generateOption(errorOption, data, setting);
}).catch(() => {
this.errorOption = {};
})
},
getResponseCodeChart() {
this.$get("/performance/report/content/response_code_chart/" + this.id).then(res => {
let data = res.data.data;
let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis);
let yAxisListMax = this._getChartMax(yAxisList);
let yAxisIndex0List = data.filter(m => m.yAxis2 === -1).map(m => m.groupName);
yAxisIndex0List = this._unique(yAxisIndex0List);
let resCodeOption = {
title: {
text: 'Response code',
left: 'center',
top: 20,
textStyle: {
color: '#99743C'
},
},
tooltip: {
show: true,
trigger: 'axis',
extraCssText: 'z-index: 999;',
formatter: function (params, ticket, callback) {
let result = "";
let name = params[0].name;
result += name + "<br/>";
for (let i = 0; i < params.length; i++) {
let seriesName = params[i].seriesName;
if (seriesName.length > 100) {
seriesName = seriesName.substring(0, 100);
}
let value = params[i].value;
let marker = params[i].marker;
result += marker + seriesName + ": " + value[1] + "<br/>";
}
return result;
}
},
legend: {},
xAxis: {},
yAxis: [
{
name: 'No',
type: 'value',
min: 0,
max: yAxisListMax,
interval: yAxisListMax / 5
}
],
series: []
}
let setting = {
series: [
{
name: 'users',
color: '#0CA74A',
}
]
}
yAxisIndex0List.forEach(item => {
setting["series"].splice(0, 0, {name: item, yAxisIndex: '0'})
})
this.resCodeOption = this.generateOption(resCodeOption, data, setting);
}).catch(() => {
this.resCodeOption = {};
})
},
generateOption(option, data, setting) {
let chartData = data;
let seriesArray = [];
@ -350,87 +508,87 @@ export default {
}
},
props: ['report']
}
}
</script>
<style scoped>
.ms-card-data {
.ms-card-data {
text-align: left;
display: block;
margin-bottom: 5px;
}
}
.ms-card-desc {
.ms-card-desc {
display: block;
text-align: left;
}
}
.ms-card-data-digital {
.ms-card-data-digital {
font-size: 21px;
}
}
.ms-card-data-unit {
.ms-card-data-unit {
color: #8492a6;
font-size: 15px;
}
}
.ms-card-index-1 .ms-card-data-digital {
.ms-card-index-1 .ms-card-data-digital {
color: #44b349;
}
}
.ms-card-index-1 {
.ms-card-index-1 {
border-left-color: #44b349;
border-left-width: 3px;
}
}
.ms-card-index-2 .ms-card-data-digital {
.ms-card-index-2 .ms-card-data-digital {
color: #65A2FF;
}
}
.ms-card-index-2 {
.ms-card-index-2 {
border-left-color: #65A2FF;
border-left-width: 3px;
}
}
.ms-card-index-3 .ms-card-data-digital {
.ms-card-index-3 .ms-card-data-digital {
color: #E6113C;
}
}
.ms-card-index-3 {
.ms-card-index-3 {
border-left-color: #E6113C;
border-left-width: 3px;
}
}
.ms-card-index-4 .ms-card-data-digital {
.ms-card-index-4 .ms-card-data-digital {
color: #99743C;
}
}
.ms-card-index-4 {
.ms-card-index-4 {
border-left-color: #99743C;
border-left-width: 3px;
}
}
.ms-card-index-5 .ms-card-data-digital {
.ms-card-index-5 .ms-card-data-digital {
color: #99743C;
}
}
.ms-card-index-5 {
.ms-card-index-5 {
border-left-color: #99743C;
border-left-width: 3px;
}
}
.ms-card-index-6 .ms-card-data-digital {
.ms-card-index-6 .ms-card-data-digital {
color: #3C9899;
}
}
.ms-card-index-6 {
.ms-card-index-6 {
border-left-color: #3C9899;
border-left-width: 3px;
}
}
.chart-config {
.chart-config {
width: 100%;
}
}
</style>