错误记录表格

This commit is contained in:
shiziyuan9527 2020-03-26 14:18:26 +08:00
parent d6f285a1d4
commit e81c86cade
6 changed files with 212 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.controller.request.ReportRequest;
import io.metersphere.dto.ReportDTO;
import io.metersphere.report.base.Errors;
import io.metersphere.report.base.RequestStatistics;
import io.metersphere.report.base.RequestStatisticsDTO;
import io.metersphere.service.ReportService;
@ -59,5 +60,10 @@ public class ReportController {
return reportService.getReport(reportId);
}
@GetMapping("/content/errors/{reportId}")
public List<Errors> getReportErrors(@PathVariable String reportId) {
return reportService.getReportErrors(reportId);
}
}

View File

@ -3,9 +3,11 @@ package io.metersphere.report;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import io.metersphere.report.base.Errors;
import io.metersphere.report.base.Metric;
import io.metersphere.report.base.RequestStatistics;
import io.metersphere.report.base.RequestStatisticsDTO;
import org.apache.commons.lang3.StringUtils;
import java.io.Reader;
import java.io.StringReader;
@ -79,7 +81,7 @@ public class JtlResolver {
Integer tp90 = elapsedList.size()*90/100;
Integer tp95 = elapsedList.size()*95/100;
Integer tp99 = elapsedList.size()*99/100;
Long l = Long.valueOf(timestampList.get(index-1)) - Long.valueOf(timestampList.get(0));
Long l = Long.valueOf(timestampList.get(timestampList.size()-1)) - Long.valueOf(timestampList.get(0));
RequestStatistics requestStatistics = new RequestStatistics();
requestStatistics.setRequestLabel(label);
@ -104,7 +106,7 @@ public class JtlResolver {
/**
* 所有的相同请求的bytes总和 / 1024 / 请求持续运行的时间=sum(bytes)/1024/total time
*/
// todo Avg Bandwidth(KBytes/s)
// todo Avg Bandwidth(KBytes/s) 请求之间时间戳间隔l 可能为0
requestStatistics.setKbPerSec(String.format("%.2f",totalBytes*1.0/1024/(l*1.0/1000)));
requestStatisticsList.add(requestStatistics);
}
@ -140,10 +142,40 @@ public class JtlResolver {
return statisticsDTO;
}
// Aggregate Report
public static RequestStatisticsDTO getRequestStatistics(String jtlString) {
List<Metric> totalLines = resolver(jtlString);
Map<String, List<Metric>> map = totalLines.stream().collect(Collectors.groupingBy(Metric::getLabel));
return getOneRpsResult(map);
}
// Errors
public static List<Errors> getErrorsList(String jtlString) {
List<Metric> totalLines = resolver(jtlString);
List<Metric> falseList = totalLines.stream().filter(metric -> StringUtils.equals("false", metric.getSuccess())).collect(Collectors.toList());
List<Errors> errorsList = new ArrayList<>();
Map<String, List<Metric>> collect = falseList.stream().collect(Collectors.groupingBy(JtlResolver::getResponseCodeAndFailureMessage));
Iterator<Map.Entry<String, List<Metric>>> iterator = collect.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<Metric>> next = iterator.next();
String key = next.getKey();
List<Metric> value = next.getValue();
Errors errors = new Errors();
errors.setErrorType(key);
errors.setErrorNumber(String.valueOf(value.size()));
Integer errorSize = value.size();
Integer errorAllSize = falseList.size();
Integer allSamples = totalLines.size();
DecimalFormat df = new DecimalFormat("0.00");
errors.setPrecentOfErrors(df.format((double)errorSize / errorAllSize * 100) + "%");
errors.setPrecentOfAllSamples(df.format((double)errorSize / allSamples * 100) + "%");
errorsList.add(errors);
}
return errorsList;
}
private static String getResponseCodeAndFailureMessage(Metric metric) {
return metric.getResponseCode() + "/" + metric.getResponseMessage();
}
}

View File

@ -0,0 +1,41 @@
package io.metersphere.report.base;
public class Errors {
private String errorType;
private String errorNumber;
private String precentOfErrors;
private String precentOfAllSamples;
public String getErrorType() {
return errorType;
}
public void setErrorType(String errorType) {
this.errorType = errorType;
}
public String getErrorNumber() {
return errorNumber;
}
public void setErrorNumber(String errorNumber) {
this.errorNumber = errorNumber;
}
public String getPrecentOfErrors() {
return precentOfErrors;
}
public void setPrecentOfErrors(String precentOfErrors) {
this.precentOfErrors = precentOfErrors;
}
public String getPrecentOfAllSamples() {
return precentOfAllSamples;
}
public void setPrecentOfAllSamples(String precentOfAllSamples) {
this.precentOfAllSamples = precentOfAllSamples;
}
}

View File

@ -7,6 +7,7 @@ import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
import io.metersphere.controller.request.ReportRequest;
import io.metersphere.dto.ReportDTO;
import io.metersphere.report.JtlResolver;
import io.metersphere.report.base.Errors;
import io.metersphere.report.base.RequestStatistics;
import io.metersphere.report.base.RequestStatisticsDTO;
import org.springframework.stereotype.Service;
@ -51,4 +52,11 @@ public class ReportService {
RequestStatisticsDTO requestStatistics = JtlResolver.getRequestStatistics(content);
return requestStatistics;
}
public List<Errors> getReportErrors(String id) {
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
String content = loadTestReport.getContent();
List<Errors> errors = JtlResolver.getErrorsList(content);
return errors;
}
}

View File

@ -41,7 +41,7 @@
<ms-report-request-statistics :id="reportId"/>
</el-tab-pane>
<el-tab-pane :label="$t('report.test_error_log')">
<ms-report-error-log />
<ms-report-error-log :id="reportId"/>
</el-tab-pane>
<el-tab-pane :label="$t('report.test_log_details')">
<ms-report-log-details />

View File

@ -1,32 +1,123 @@
<template>
<div>
<span class="table-title">Errors</span>
<el-table
:data="tableData"
border
stripe
style="width: 100%"
:default-sort = "{prop: 'elementLabel'}"
>
<el-table-column
prop="typeOfError"
prop="errorType"
label="Type of Error"
sortable>
</el-table-column>
<el-table-column
prop="numberOfErrors"
prop="errorNumber"
label="Number of errors"
sortable>
</el-table-column>
<el-table-column
prop="error"
prop="precentOfErrors"
label="% in errors"
sortable>
</el-table-column>
<el-table-column
prop="allSamples"
prop="precentOfAllSamples"
label="% in all samples"
sortable>
</el-table-column>
</el-table>
<div style="margin-top: 40px;"></div>
<span class="table-title">Top 5 Errors by sampler </span>
<el-table
:data="tableData"
border
stripe
style="width: 100%"
>
<el-table-column
prop="errorType"
label="Sample"
width="400"
>
</el-table-column>
<el-table-column
prop="errorNumber"
label="#Samples"
width="120"
>
</el-table-column>
<el-table-column
prop="#Errors"
label="#Errors"
width="100"
>
</el-table-column>
<el-table-column
prop="Error"
label="Error"
width="400"
>
</el-table-column>
<el-table-column
prop="#Errors"
label="#Errors"
width="100"
>
</el-table-column>
<el-table-column
prop="Error"
label="Error"
width="400"
>
</el-table-column>
<el-table-column
prop="#Errors"
label="#Errors"
width="100"
>
</el-table-column>
<el-table-column
prop="Error"
label="Error"
width="400"
>
</el-table-column>
<el-table-column
prop="#Errors"
label="#Errors"
width="100"
>
</el-table-column>
<el-table-column
prop="Error"
label="Error"
width="400"
>
</el-table-column>
<el-table-column
prop="#Errors"
label="#Errors"
width="100"
>
</el-table-column>
<el-table-column
prop="Error"
label="Error"
width="400"
>
</el-table-column>
<el-table-column
prop="#Errors"
label="#Errors"
width="100"
>
</el-table-column>
</el-table>
</div>
</template>
@ -39,11 +130,36 @@
}
},
methods: {
initTableData() {
this.$get("/report/content/errors/" + this.id, res => {
this.tableData = res.data;
})
}
},
created() {
this.initTableData();
},
props: ['id'],
watch: {
'$route'(to) {
if (to.name === "perReportView") {
let reportId = to.path.split('/')[4];
if(reportId){
this.$get("/report/content/errors/" + this.id, res => {
this.tableData = res.data;
})
}
}
}
}
}
</script>
<style scoped>
.table-title {
font-size: 20px;
color: #8492a6;
display: block;
margin-bottom: 8px;
}
</style>