报告-请求统计表格
This commit is contained in:
parent
20099c351e
commit
55d7a806fd
|
@ -8,6 +8,7 @@ import io.metersphere.commons.utils.PageUtils;
|
||||||
import io.metersphere.commons.utils.Pager;
|
import io.metersphere.commons.utils.Pager;
|
||||||
import io.metersphere.controller.request.ReportRequest;
|
import io.metersphere.controller.request.ReportRequest;
|
||||||
import io.metersphere.dto.ReportDTO;
|
import io.metersphere.dto.ReportDTO;
|
||||||
|
import io.metersphere.report.base.RequestStatistics;
|
||||||
import io.metersphere.service.ReportService;
|
import io.metersphere.service.ReportService;
|
||||||
import io.metersphere.user.SessionUtils;
|
import io.metersphere.user.SessionUtils;
|
||||||
import org.apache.shiro.authz.annotation.Logical;
|
import org.apache.shiro.authz.annotation.Logical;
|
||||||
|
@ -52,5 +53,10 @@ public class ReportController {
|
||||||
return reportService.getReportTestAndProInfo(reportId);
|
return reportService.getReportTestAndProInfo(reportId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/content/{reportId}")
|
||||||
|
public List<RequestStatistics> getReportContent(@PathVariable String reportId) {
|
||||||
|
return reportService.getReport(reportId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,13 @@ import io.metersphere.report.base.RequestStatistics;
|
||||||
|
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class JtlResolver {
|
public class JtlResolver {
|
||||||
|
|
||||||
private List<Metric> resolver(String jtlString) {
|
private static List<Metric> resolver(String jtlString) {
|
||||||
HeaderColumnNameMappingStrategy<Metric> ms = new HeaderColumnNameMappingStrategy<>();
|
HeaderColumnNameMappingStrategy<Metric> ms = new HeaderColumnNameMappingStrategy<>();
|
||||||
ms.setType(Metric.class);
|
ms.setType(Metric.class);
|
||||||
try (Reader reader = new StringReader(jtlString)) {
|
try (Reader reader = new StringReader(jtlString)) {
|
||||||
|
@ -32,7 +33,7 @@ public class JtlResolver {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RequestStatistics> getOneRpsResult(Map<String, List<Metric>> map){
|
private static List<RequestStatistics> getOneRpsResult(Map<String, List<Metric>> map){
|
||||||
List<RequestStatistics> requestStatisticsList = new ArrayList<>();
|
List<RequestStatistics> requestStatisticsList = new ArrayList<>();
|
||||||
Iterator<Map.Entry<String, List<Metric>>> iterator = map.entrySet().iterator();
|
Iterator<Map.Entry<String, List<Metric>>> iterator = map.entrySet().iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
|
@ -45,7 +46,7 @@ public class JtlResolver {
|
||||||
int sumElapsed=0;
|
int sumElapsed=0;
|
||||||
Integer failSize = 0;
|
Integer failSize = 0;
|
||||||
Integer totalBytes = 0;
|
Integer totalBytes = 0;
|
||||||
List<Integer> elapsedList = new ArrayList<Integer>();
|
List<Integer> elapsedList = new ArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
try {
|
try {
|
||||||
|
@ -84,7 +85,9 @@ public class JtlResolver {
|
||||||
RequestStatistics requestStatistics = new RequestStatistics();
|
RequestStatistics requestStatistics = new RequestStatistics();
|
||||||
requestStatistics.setRequestLabel(label);
|
requestStatistics.setRequestLabel(label);
|
||||||
requestStatistics.setSamples(index+"");
|
requestStatistics.setSamples(index+"");
|
||||||
requestStatistics.setAverage(sumElapsed/index+"");
|
DecimalFormat df = new DecimalFormat("0.00");
|
||||||
|
String s = df.format((float)sumElapsed/index);
|
||||||
|
requestStatistics.setAverage(s+"");
|
||||||
/**
|
/**
|
||||||
* TP90的计算
|
* TP90的计算
|
||||||
* 1,把一段时间内全部的请求的响应时间,从小到大排序,获得序列A
|
* 1,把一段时间内全部的请求的响应时间,从小到大排序,获得序列A
|
||||||
|
@ -104,7 +107,7 @@ public class JtlResolver {
|
||||||
return requestStatisticsList;
|
return requestStatisticsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RequestStatistics> getRequestStatistics(String jtlString) {
|
public static List<RequestStatistics> getRequestStatistics(String jtlString) {
|
||||||
List<Metric> totalLines = resolver(jtlString);
|
List<Metric> totalLines = resolver(jtlString);
|
||||||
Map<String, List<Metric>> map = totalLines.stream().collect(Collectors.groupingBy(Metric::getLabel));
|
Map<String, List<Metric>> map = totalLines.stream().collect(Collectors.groupingBy(Metric::getLabel));
|
||||||
return getOneRpsResult(map);
|
return getOneRpsResult(map);
|
||||||
|
|
|
@ -6,6 +6,8 @@ import io.metersphere.base.mapper.LoadTestReportMapper;
|
||||||
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
|
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
|
||||||
import io.metersphere.controller.request.ReportRequest;
|
import io.metersphere.controller.request.ReportRequest;
|
||||||
import io.metersphere.dto.ReportDTO;
|
import io.metersphere.dto.ReportDTO;
|
||||||
|
import io.metersphere.report.JtlResolver;
|
||||||
|
import io.metersphere.report.base.RequestStatistics;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -42,7 +44,10 @@ public class ReportService {
|
||||||
return extLoadTestReportMapper.getReportTestAndProInfo(reportId);
|
return extLoadTestReportMapper.getReportTestAndProInfo(reportId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoadTestReport getReport(String id) {
|
public List<RequestStatistics> getReport(String id) {
|
||||||
return loadTestReportMapper.selectByPrimaryKey(id);
|
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
|
||||||
|
String content = loadTestReport.getContent();
|
||||||
|
List<RequestStatistics> requestStatistics = JtlResolver.getRequestStatistics(content);
|
||||||
|
return requestStatistics;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,6 +199,7 @@ public class JtlTest {
|
||||||
"1584602504095,65,https://rddev2.fit2cloud.com/auth/realms/cmp/login-actions/authenticate?session_code=YWUneSay4qlQuHRZsD4kPaZDIIR50KJLaNpW7uhsD-Q&execution=c7620733-54ab-46b2-802b-66764e42682b&client_id=cmp-client&tab_id=S8xOQPgCmhQ,400,Bad Request,Thread Group 1-7,text,false,,4469,1745,3,3,https://rddev2.fit2cloud.com/auth/realms/cmp/login-actions/authenticate,65,0,4\n" +
|
"1584602504095,65,https://rddev2.fit2cloud.com/auth/realms/cmp/login-actions/authenticate?session_code=YWUneSay4qlQuHRZsD4kPaZDIIR50KJLaNpW7uhsD-Q&execution=c7620733-54ab-46b2-802b-66764e42682b&client_id=cmp-client&tab_id=S8xOQPgCmhQ,400,Bad Request,Thread Group 1-7,text,false,,4469,1745,3,3,https://rddev2.fit2cloud.com/auth/realms/cmp/login-actions/authenticate,65,0,4\n" +
|
||||||
"1584602504200,12,https://rddev2.fit2cloud.com/dashboard/web-public/project/html/notification-menus.html?_t=1577351137654,200,OK,Thread Group 1-3,text,true,,1570,582,2,2,https://rddev2.fit2cloud.com/dashboard/web-public/project/html/notification-menus.html?_t=1577351137654,12,0,0\n";
|
"1584602504200,12,https://rddev2.fit2cloud.com/dashboard/web-public/project/html/notification-menus.html?_t=1577351137654,200,OK,Thread Group 1-3,text,true,,1570,582,2,2,https://rddev2.fit2cloud.com/dashboard/web-public/project/html/notification-menus.html?_t=1577351137654,12,0,0\n";
|
||||||
List<Metric> metrics = beanBuilderExample(jtlString);
|
List<Metric> metrics = beanBuilderExample(jtlString);
|
||||||
|
// 根据label分组,label作为map的key
|
||||||
Map<String, List<Metric>> map = metrics.stream().collect(Collectors.groupingBy(Metric::getLabel));
|
Map<String, List<Metric>> map = metrics.stream().collect(Collectors.groupingBy(Metric::getLabel));
|
||||||
getOneRpsResult(map);
|
getOneRpsResult(map);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +216,8 @@ public class JtlTest {
|
||||||
int sumElapsed=0;
|
int sumElapsed=0;
|
||||||
Integer failSize = 0;
|
Integer failSize = 0;
|
||||||
Integer totalBytes = 0;
|
Integer totalBytes = 0;
|
||||||
List<Integer> elapsedList = new ArrayList<Integer>();
|
// 响应时间的列表排序之后 用于计算90%line、95%line、99line
|
||||||
|
List<Integer> elapsedList = new ArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<ms-report-test-overview />
|
<ms-report-test-overview />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('report.test_request_statistics')">
|
<el-tab-pane :label="$t('report.test_request_statistics')">
|
||||||
<ms-report-request-statistics />
|
<ms-report-request-statistics :id="reportId"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('report.test_error_log')">
|
<el-tab-pane :label="$t('report.test_error_log')">
|
||||||
<ms-report-error-log />
|
<ms-report-error-log />
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
border
|
border
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
:default-sort = "{prop: 'elementLabel'}"
|
:default-sort = "{prop: 'samples'}"
|
||||||
>
|
>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="elementLabel"
|
prop="requestLabel"
|
||||||
label="Element Label"
|
label="Element Label"
|
||||||
fixed
|
fixed
|
||||||
width="150"
|
width="450"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="samples"
|
prop="samples"
|
||||||
|
@ -20,59 +20,59 @@
|
||||||
sortable>
|
sortable>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="avgResponseTime"
|
prop="average"
|
||||||
label="Avg Response Time(ms)"
|
label="Avg Response Time(ms)"
|
||||||
width="220"
|
width="220"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="avgHits"
|
prop="avgHits"
|
||||||
label="Avg Hits/s"
|
label="Avg Hits/s"
|
||||||
width="150"
|
width="150"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="90line"
|
prop="tp90"
|
||||||
label="90% line(ms)"
|
label="90% line(ms)"
|
||||||
width="150"
|
width="150"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="95line"
|
prop="tp95"
|
||||||
label="95% line(ms)"
|
label="95% line(ms)"
|
||||||
width="150"
|
width="150"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="99line"
|
prop="tp99"
|
||||||
label="99% line(ms)"
|
label="99% line(ms)"
|
||||||
width="150"
|
width="150"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="minResponseTime"
|
prop="min"
|
||||||
label="Min Response Time(ms)"
|
label="Min Response Time(ms)"
|
||||||
width="220"
|
width="220"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="maxResponseTime"
|
prop="max"
|
||||||
label="Max Response Time(ms)"
|
label="Max Response Time(ms)"
|
||||||
width="220"
|
width="220"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="avgBandwidth"
|
prop="kbPerSec"
|
||||||
label="Avg Bandwidth(KBytes/s)"
|
label="Avg Bandwidth(KBytes/s)"
|
||||||
width="220"
|
width="220"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="errorPercentage"
|
prop="errors"
|
||||||
label="Error Percentage"
|
label="Error Percentage"
|
||||||
width="180"
|
width="180"
|
||||||
fixed="right"
|
fixed="right"
|
||||||
sortable>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -83,11 +83,29 @@
|
||||||
name: "RequestStatistics",
|
name: "RequestStatistics",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tableData: [{},{},{},{},{}]
|
tableData: [{},{},{},{},{}],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initTableData() {
|
||||||
|
this.$get("/report/content/" + this.id, res => {
|
||||||
|
this.tableData = res.data;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initTableData()
|
||||||
|
},
|
||||||
|
props: ['id'],
|
||||||
|
watch: {
|
||||||
|
'$route'(to) {
|
||||||
|
let reportId = to.path.split('/')[4];
|
||||||
|
if(reportId){
|
||||||
|
this.$get("/report/content/" + reportId, res => {
|
||||||
|
this.tableData = res.data;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue