From ee582bf41b26ab9fa6bf22725e9f6bd7a96e7b94 Mon Sep 17 00:00:00 2001 From: shiziyuan9527 Date: Tue, 7 Apr 2020 16:43:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=A6=82=E8=A7=88ResponseTim?= =?UTF-8?q?e=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/report/JtlResolver.java | 29 +- .../report/components/TestOverview.vue | 276 +++++++++--------- 2 files changed, 162 insertions(+), 143 deletions(-) diff --git a/backend/src/main/java/io/metersphere/report/JtlResolver.java b/backend/src/main/java/io/metersphere/report/JtlResolver.java index 1c7e8870f9..1df5e56974 100644 --- a/backend/src/main/java/io/metersphere/report/JtlResolver.java +++ b/backend/src/main/java/io/metersphere/report/JtlResolver.java @@ -8,7 +8,6 @@ import io.metersphere.report.base.*; import io.metersphere.report.dto.ErrorsTop5DTO; import io.metersphere.report.dto.RequestStatisticsDTO; import org.apache.commons.lang3.StringUtils; - import java.io.Reader; import java.io.StringReader; import java.text.DecimalFormat; @@ -20,7 +19,6 @@ import java.util.stream.Collectors; public class JtlResolver { private static final Integer ERRORS_TOP_SIZE = 5; - private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static List resolver(String jtlString) { HeaderColumnNameMappingStrategy ms = new HeaderColumnNameMappingStrategy<>(); @@ -378,27 +376,37 @@ public class JtlResolver { entries.sort(JtlResolver::sortByDate); List resTimeList = new ArrayList<>(); + List users = new ArrayList<>(); List timestampList = new ArrayList<>(); for (Map.Entry> entry : entries) { List metricList = entry.getValue(); + Map> metricsMap = metricList.stream().collect(Collectors.groupingBy(Metric::getThreadName)); + int maxUsers = metricsMap.size(); int sumElapsedTime = metricList.stream().mapToInt(metric -> Integer.parseInt(metric.getElapsed())).sum(); timestampList.add(entry.getKey()); + users.add(String.valueOf(maxUsers)); resTimeList.add(String.valueOf(sumElapsedTime / metricList.size())); } + Map resultMap = new HashMap<>(2); + resultMap.put("users", users); + resultMap.put("resTime", resTimeList); + JSONObject serices = new JSONObject(resultMap); chartsData.setxAxis(StringUtils.join(",", timestampList)); - chartsData.setSerices(StringUtils.join(",", resTimeList)); + chartsData.setSerices(serices.toString()); return chartsData; } - private static String stampToDate(String s) { - long lt = Long.parseLong(s); + private static String stampToDate(String timeStamp) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + long lt = Long.parseLong(timeStamp); Date date = new Date(lt); return simpleDateFormat.format(date); } private static int sortByDate(Map.Entry> map1, Map.Entry> map2) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date1 = null, date2 = null; try { date1 = simpleDateFormat.parse(map1.getKey()); @@ -406,6 +414,15 @@ public class JtlResolver { } catch (ParseException e) { e.printStackTrace(); } - return (int) (Objects.requireNonNull(date1).getTime() - Objects.requireNonNull(date2).getTime()); + + Long time1 = date1.getTime(); + Long time2 = date2.getTime(); + + if (time1.equals(time2)) { + return 0; + } else { + return time1 > time2 ? 1 : -1; + } + } } \ No newline at end of file diff --git a/frontend/src/business/components/performance/report/components/TestOverview.vue b/frontend/src/business/components/performance/report/components/TestOverview.vue index 7af763c7cd..ef9e253eb3 100644 --- a/frontend/src/business/components/performance/report/components/TestOverview.vue +++ b/frontend/src/business/components/performance/report/components/TestOverview.vue @@ -59,10 +59,10 @@ - + - + @@ -79,84 +79,8 @@ avgResponseTime: "0", responseTime90: "0", avgBandwidth: "0", - option: { - legend: { - top: 20, - data: ['Users', 'Hits/s', 'Error(s)'] - }, - xAxis: { - type: 'category', - }, - yAxis: [{ - name: 'User', - type: 'value', - min: 0, - splitNumber: 5, - // interval: 10 / 5 - }, - { - name: 'Hits/s', - type: 'value', - splitNumber: 5, - min: 0, - // max: 5, - // interval: 5 / 5 - } - ], - series: [ - { - name: 'Users', - color: '#0CA74A', - type: 'line', - yAxisIndex: 0 - }, - { - name: 'Hits/s', - color: '#65A2FF', - type: 'line', - yAxisIndex: 1 - }, - { - name: 'Error(s)', - color: '#E6113C', - type: 'line', - yAxisIndex: 1 - } - ] - }, - option2: { - legend: { - top: 20, - data: ['Users', 'Response Time'] - }, - xAxis: { - type: 'category', - data: [] - }, - yAxis: [{ - name: 'User', - type: 'value', - }, - { - name: 'Response Time', - type: 'value' - } - ], - series: [ - { - name: 'Users', - color: '#0CA74A', - data: [], - type: 'line', - }, - { - name: 'Response Time', - color: '#99743C', - data: [], - type: 'line', - } - ] - } + loadOption: {}, + resOption: {} } }, methods: { @@ -172,7 +96,108 @@ }) this.$get("/report/content/load_chart/" + this.id, res => { let data = res.data; - this.option = this.generateOption(data); + let loadOption = { + title: { + text: 'Load', + left: 'center', + top: 20, + textStyle: { + color: '#65A2FF' + }, + }, + legend: { + bottom: 10, + data: ['Users', 'Hits/s', 'Error(s)'] + }, + xAxis: { + type: 'category', + }, + yAxis: [{ + name: 'User', + type: 'value', + min: 0, + splitNumber: 5, + // interval: 10 / 5 + }, + { + name: 'Hits/s', + type: 'value', + splitNumber: 5, + min: 0, + // max: 5, + // interval: 5 / 5 + } + ], + series: [ + { + name: 'Users', + color: '#0CA74A', + type: 'line', + yAxisIndex: 0 + }, + { + name: 'Hits/s', + color: '#65A2FF', + type: 'line', + yAxisIndex: 1 + }, + { + name: 'Error(s)', + color: '#E6113C', + type: 'line', + yAxisIndex: 1 + } + ] + } + this.loadOption = this.generateLoadOption(loadOption, data); + }) + this.$get("/report/content/res_chart/" + this.id, res => { + let data = res.data; + let resOption = { + title: { + text: 'Response Time', + left: 'center', + top: 20, + textStyle: { + color: '#99743C' + }, + }, + legend: { + bottom: 10, + data: ['Users', 'Response Time'] + }, + xAxis: { + type: 'category' + }, + yAxis: [{ + name: 'User', + type: 'value', + splitNumber: 5, + min: 0 + }, + { + name: 'Response Time', + type: 'value', + splitNumber: 5, + min: 0 + } + ], + series: [ + { + name: 'Users', + color: '#0CA74A', + type: 'line', + yAxisIndex: 0 + }, + { + name: 'Response Time', + color: '#99743C', + type: 'line', + yAxisIndex: 1 + } + ] + } + this.resOption = this.generateResponseOption(resOption, data); }) }, _objToStrMap(obj){ @@ -185,55 +210,10 @@ _jsonToMap(jsonStr){ return this._objToStrMap(JSON.parse(jsonStr)); }, - generateOption(data) { - let option = { - legend: { - top: 20, - data: ['Users', 'Hits/s', 'Error(s)'] - }, - xAxis: { - type: 'category', - }, - yAxis: [{ - name: 'User', - type: 'value', - min: 0, - splitNumber: 5, - // interval: 10 / 5 - }, - { - name: 'Hits/s', - type: 'value', - splitNumber: 5, - min: 0, - // max: 5, - // interval: 5 / 5 - } - ], - series: [ - { - name: 'Users', - color: '#0CA74A', - type: 'line', - yAxisIndex: 0 - }, - { - name: 'Hits/s', - color: '#65A2FF', - type: 'line', - yAxisIndex: 1 - }, - { - name: 'Error(s)', - color: '#E6113C', - type: 'line', - yAxisIndex: 1 - } - ] - } + generateLoadOption(loadOption, data) { let map = this._jsonToMap(data.serices); let xAxis = data.xAxis; - this.$set(option.xAxis, "data", xAxis.split(',')); + this.$set(loadOption.xAxis, "data", xAxis.split(',')); let user = map.get("users").slice(0); let hit = map.get("hits").slice(0); user.sort(function (a,b) { @@ -242,16 +222,38 @@ hit.sort(function (a,b) { return parseFloat(a) - parseFloat(b); }) - this.$set(option.yAxis[0], "max",user[user.length-1]); - this.$set(option.yAxis[0], "interval", user[user.length-1]/5); - this.$set(option.yAxis[1], "max", hit[hit.length-1]); - this.$set(option.yAxis[1], "interval", hit[hit.length-1]/5); + this.$set(loadOption.yAxis[0], "max",user[user.length-1]); + this.$set(loadOption.yAxis[0], "interval", user[user.length-1]/5); + this.$set(loadOption.yAxis[1], "max", hit[hit.length-1]); + this.$set(loadOption.yAxis[1], "interval", hit[hit.length-1]/5); - this.$set(option.series[0], "data", map.get("users")); - this.$set(option.series[1], "data", map.get("hits")); - this.$set(option.series[2], "data", map.get("errors")); - return option; - } + this.$set(loadOption.series[0], "data", map.get("users")); + this.$set(loadOption.series[1], "data", map.get("hits")); + this.$set(loadOption.series[2], "data", map.get("errors")); + return loadOption; + }, + generateResponseOption(resOption, data) { + let map = this._jsonToMap(data.serices); + let user = map.get("users").slice(0); + let res = map.get("resTime").slice(0); + user.sort(function (a,b) { + return parseInt(a) - parseInt(b); + }) + res.sort(function (a,b) { + return parseFloat(a) - parseFloat(b); + }) + + this.$set(resOption.yAxis[0], "max",user[user.length-1]); + this.$set(resOption.yAxis[0], "interval", user[user.length-1]/5); + this.$set(resOption.yAxis[1], "max", res[res.length-1]); + this.$set(resOption.yAxis[1], "interval", res[res.length-1]/5); + + let xAxis = data.xAxis; + this.$set(resOption.xAxis, "data", xAxis.split(',')); + this.$set(resOption.series[0], "data", map.get("users")); + this.$set(resOption.series[1], "data", map.get("resTime")); + return resOption; + }, }, watch: { status() {