Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MeterSphere
metersphere
提交
68ad0c54
M
metersphere
项目概览
MeterSphere
/
metersphere
上一次同步 3 年多
通知
25
Star
1
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
metersphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
68ad0c54
编写于
4月 21, 2020
作者:
C
chenjianxing
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev' of
https://github.com/fit2cloudrd/metersphere-server
into dev
上级
b32a6f13
fb671395
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
315 addition
and
327 deletion
+315
-327
backend/src/main/java/io/metersphere/controller/PerformanceReportController.java
...o/metersphere/controller/PerformanceReportController.java
+2
-6
backend/src/main/java/io/metersphere/controller/PerformanceTestController.java
.../io/metersphere/controller/PerformanceTestController.java
+6
-0
backend/src/main/java/io/metersphere/engine/docker/DockerTestEngine.java
...n/java/io/metersphere/engine/docker/DockerTestEngine.java
+2
-5
backend/src/main/java/io/metersphere/report/GenerateReport.java
...d/src/main/java/io/metersphere/report/GenerateReport.java
+6
-127
backend/src/main/java/io/metersphere/report/base/Statistics.java
.../src/main/java/io/metersphere/report/base/Statistics.java
+134
-0
backend/src/main/java/io/metersphere/report/base/SummaryData.java
...src/main/java/io/metersphere/report/base/SummaryData.java
+16
-0
backend/src/main/java/io/metersphere/report/dto/RequestStatisticsDTO.java
.../java/io/metersphere/report/dto/RequestStatisticsDTO.java
+0
-128
backend/src/main/java/io/metersphere/report/parse/ResultDataParse.java
...ain/java/io/metersphere/report/parse/ResultDataParse.java
+53
-4
backend/src/main/java/io/metersphere/service/PerformanceTestService.java
...n/java/io/metersphere/service/PerformanceTestService.java
+19
-0
backend/src/main/java/io/metersphere/service/ReportService.java
...d/src/main/java/io/metersphere/service/ReportService.java
+3
-9
backend/src/main/resources/i18n/messages_en_US.properties
backend/src/main/resources/i18n/messages_en_US.properties
+3
-1
backend/src/main/resources/i18n/messages_zh_CN.properties
backend/src/main/resources/i18n/messages_zh_CN.properties
+3
-1
backend/src/test/java/io/metersphere/ResultDataParseTest.java
...end/src/test/java/io/metersphere/ResultDataParseTest.java
+36
-0
frontend/src/business/components/performance/report/components/RequestStatistics.vue
...nents/performance/report/components/RequestStatistics.vue
+32
-46
未找到文件。
backend/src/main/java/io/metersphere/controller/PerformanceReportController.java
浏览文件 @
68ad0c54
...
@@ -8,12 +8,8 @@ import io.metersphere.commons.utils.PageUtils;
...
@@ -8,12 +8,8 @@ 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.ChartsData
;
import
io.metersphere.report.base.*
;
import
io.metersphere.report.base.Errors
;
import
io.metersphere.report.base.ReportTimeInfo
;
import
io.metersphere.report.base.TestOverview
;
import
io.metersphere.report.dto.ErrorsTop5DTO
;
import
io.metersphere.report.dto.ErrorsTop5DTO
;
import
io.metersphere.report.dto.RequestStatisticsDTO
;
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
;
...
@@ -59,7 +55,7 @@ public class PerformanceReportController {
...
@@ -59,7 +55,7 @@ public class PerformanceReportController {
}
}
@GetMapping
(
"/content/{reportId}"
)
@GetMapping
(
"/content/{reportId}"
)
public
RequestStatisticsDTO
getReportContent
(
@PathVariable
String
reportId
)
{
public
List
<
Statistics
>
getReportContent
(
@PathVariable
String
reportId
)
{
return
reportService
.
getReport
(
reportId
);
return
reportService
.
getReport
(
reportId
);
}
}
...
...
backend/src/main/java/io/metersphere/controller/PerformanceTestController.java
浏览文件 @
68ad0c54
...
@@ -21,6 +21,7 @@ import org.springframework.web.multipart.MultipartFile;
...
@@ -21,6 +21,7 @@ import org.springframework.web.multipart.MultipartFile;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
@RestController
@RestController
@RequestMapping
(
value
=
"performance"
)
@RequestMapping
(
value
=
"performance"
)
...
@@ -88,6 +89,11 @@ public class PerformanceTestController {
...
@@ -88,6 +89,11 @@ public class PerformanceTestController {
performanceTestService
.
run
(
request
);
performanceTestService
.
run
(
request
);
}
}
@GetMapping
(
"/log/{testId}"
)
public
Map
<
String
,
String
>
stop
(
@PathVariable
String
testId
)
{
return
performanceTestService
.
log
(
testId
);
}
@GetMapping
(
"/file/metadata/{testId}"
)
@GetMapping
(
"/file/metadata/{testId}"
)
public
List
<
FileMetadata
>
getFileMetadata
(
@PathVariable
String
testId
)
{
public
List
<
FileMetadata
>
getFileMetadata
(
@PathVariable
String
testId
)
{
return
fileService
.
getFileMetadataByTestId
(
testId
);
return
fileService
.
getFileMetadataByTestId
(
testId
);
...
...
backend/src/main/java/io/metersphere/engine/docker/DockerTestEngine.java
浏览文件 @
68ad0c54
...
@@ -10,7 +10,6 @@ import io.metersphere.dto.NodeDTO;
...
@@ -10,7 +10,6 @@ import io.metersphere.dto.NodeDTO;
import
io.metersphere.engine.AbstractEngine
;
import
io.metersphere.engine.AbstractEngine
;
import
io.metersphere.engine.EngineContext
;
import
io.metersphere.engine.EngineContext
;
import
io.metersphere.engine.EngineFactory
;
import
io.metersphere.engine.EngineFactory
;
import
io.metersphere.engine.docker.request.BaseRequest
;
import
io.metersphere.engine.docker.request.TestRequest
;
import
io.metersphere.engine.docker.request.TestRequest
;
import
io.metersphere.i18n.Translator
;
import
io.metersphere.i18n.Translator
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.client.RestTemplate
;
...
@@ -91,14 +90,13 @@ public class DockerTestEngine extends AbstractEngine {
...
@@ -91,14 +90,13 @@ public class DockerTestEngine extends AbstractEngine {
public
void
stop
()
{
public
void
stop
()
{
// TODO 停止运行测试
// TODO 停止运行测试
String
testId
=
loadTest
.
getId
();
String
testId
=
loadTest
.
getId
();
BaseRequest
request
=
new
BaseRequest
();
this
.
resourceList
.
forEach
(
r
->
{
this
.
resourceList
.
forEach
(
r
->
{
NodeDTO
node
=
JSON
.
parseObject
(
r
.
getConfiguration
(),
NodeDTO
.
class
);
NodeDTO
node
=
JSON
.
parseObject
(
r
.
getConfiguration
(),
NodeDTO
.
class
);
String
ip
=
node
.
getIp
();
String
ip
=
node
.
getIp
();
Integer
port
=
node
.
getPort
();
Integer
port
=
node
.
getPort
();
String
uri
=
String
.
format
(
BASE_URL
+
"/jmeter/container/stop/"
+
testId
,
ip
,
port
);
String
uri
=
String
.
format
(
BASE_URL
+
"/jmeter/container/stop/"
+
testId
,
ip
,
port
);
restTemplate
.
postForObject
(
uri
,
request
,
String
.
class
);
restTemplate
.
getForObject
(
uri
,
String
.
class
);
});
});
}
}
...
@@ -106,14 +104,13 @@ public class DockerTestEngine extends AbstractEngine {
...
@@ -106,14 +104,13 @@ public class DockerTestEngine extends AbstractEngine {
public
Map
<
String
,
String
>
log
()
{
public
Map
<
String
,
String
>
log
()
{
String
testId
=
loadTest
.
getId
();
String
testId
=
loadTest
.
getId
();
Map
<
String
,
String
>
logs
=
new
HashMap
<>();
Map
<
String
,
String
>
logs
=
new
HashMap
<>();
BaseRequest
request
=
new
BaseRequest
();
this
.
resourceList
.
forEach
(
r
->
{
this
.
resourceList
.
forEach
(
r
->
{
NodeDTO
node
=
JSON
.
parseObject
(
r
.
getConfiguration
(),
NodeDTO
.
class
);
NodeDTO
node
=
JSON
.
parseObject
(
r
.
getConfiguration
(),
NodeDTO
.
class
);
String
ip
=
node
.
getIp
();
String
ip
=
node
.
getIp
();
Integer
port
=
node
.
getPort
();
Integer
port
=
node
.
getPort
();
String
uri
=
String
.
format
(
BASE_URL
+
"/jmeter/container/log/"
+
testId
,
ip
,
port
);
String
uri
=
String
.
format
(
BASE_URL
+
"/jmeter/container/log/"
+
testId
,
ip
,
port
);
String
log
=
restTemplate
.
postForObject
(
uri
,
request
,
String
.
class
);
String
log
=
restTemplate
.
getForObject
(
uri
,
String
.
class
);
logs
.
put
(
node
.
getIp
(),
log
);
logs
.
put
(
node
.
getIp
(),
log
);
});
});
return
logs
;
return
logs
;
...
...
backend/src/main/java/io/metersphere/report/GenerateReport.java
浏览文件 @
68ad0c54
...
@@ -5,9 +5,9 @@ import com.opencsv.bean.CsvToBeanBuilder;
...
@@ -5,9 +5,9 @@ import com.opencsv.bean.CsvToBeanBuilder;
import
com.opencsv.bean.HeaderColumnNameMappingStrategy
;
import
com.opencsv.bean.HeaderColumnNameMappingStrategy
;
import
io.metersphere.report.base.*
;
import
io.metersphere.report.base.*
;
import
io.metersphere.report.dto.ErrorsTop5DTO
;
import
io.metersphere.report.dto.ErrorsTop5DTO
;
import
io.metersphere.report.dto.RequestStatisticsDTO
;
import
io.metersphere.report.parse.ResultDataParse
;
import
io.metersphere.report.parse.ResultDataParse
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.jmeter.report.processor.StatisticsSummaryConsumer
;
import
org.apache.jmeter.report.processor.graph.impl.ActiveThreadsGraphConsumer
;
import
org.apache.jmeter.report.processor.graph.impl.ActiveThreadsGraphConsumer
;
import
org.apache.jmeter.report.processor.graph.impl.HitsPerSecondGraphConsumer
;
import
org.apache.jmeter.report.processor.graph.impl.HitsPerSecondGraphConsumer
;
import
org.apache.jmeter.report.processor.graph.impl.ResponseTimeOverTimeGraphConsumer
;
import
org.apache.jmeter.report.processor.graph.impl.ResponseTimeOverTimeGraphConsumer
;
...
@@ -47,132 +47,6 @@ public class GenerateReport {
...
@@ -47,132 +47,6 @@ public class GenerateReport {
return
null
;
return
null
;
}
}
public
static
RequestStatisticsDTO
getRequestStatistics
(
String
jtlString
)
{
List
<
Integer
>
allElapseTimeList
=
new
ArrayList
<>();
List
<
RequestStatistics
>
requestStatisticsList
=
new
ArrayList
<>();
DecimalFormat
decimalFormat
=
new
DecimalFormat
(
"0.00"
);
List
<
Metric
>
totalMetricList
=
resolver
(
jtlString
);
Map
<
String
,
List
<
Metric
>>
jtlLabelMap
=
totalMetricList
.
stream
().
collect
(
Collectors
.
groupingBy
(
Metric:
:
getLabel
));
Iterator
<
Map
.
Entry
<
String
,
List
<
Metric
>>>
iterator
=
jtlLabelMap
.
entrySet
().
iterator
();
int
totalElapsedTime
=
0
;
float
totalBytes
=
0
f
;
while
(
iterator
.
hasNext
())
{
Map
.
Entry
<
String
,
List
<
Metric
>>
entry
=
iterator
.
next
();
String
label
=
entry
.
getKey
();
List
<
Metric
>
metricList
=
entry
.
getValue
();
List
<
Integer
>
elapsedList
=
new
ArrayList
<>();
int
jtlSamplesSize
=
0
,
oneLineElapsedTime
=
0
,
failSize
=
0
;
float
oneLineBytes
=
0
f
;
for
(
int
i
=
0
;
i
<
metricList
.
size
();
i
++)
{
try
{
Metric
row
=
metricList
.
get
(
i
);
String
elapsed
=
row
.
getElapsed
();
oneLineElapsedTime
+=
Integer
.
parseInt
(
elapsed
);
totalElapsedTime
+=
Integer
.
parseInt
(
elapsed
);
elapsedList
.
add
(
Integer
.
valueOf
(
elapsed
));
allElapseTimeList
.
add
(
Integer
.
valueOf
(
elapsed
));
String
isSuccess
=
row
.
getSuccess
();
if
(!
"true"
.
equals
(
isSuccess
))
{
failSize
++;
}
String
bytes
=
row
.
getBytes
();
oneLineBytes
+=
Float
.
parseFloat
(
bytes
);
totalBytes
+=
Float
.
parseFloat
(
bytes
);
jtlSamplesSize
++;
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"exception i:"
+
i
);
}
}
Collections
.
sort
(
elapsedList
);
int
tp90
=
elapsedList
.
size
()
*
90
/
100
;
int
tp95
=
elapsedList
.
size
()
*
95
/
100
;
int
tp99
=
elapsedList
.
size
()
*
99
/
100
;
metricList
.
sort
(
Comparator
.
comparing
(
t0
->
Long
.
valueOf
(
t0
.
getTimestamp
())));
long
time
=
Long
.
parseLong
(
metricList
.
get
(
metricList
.
size
()
-
1
).
getTimestamp
())
-
Long
.
parseLong
(
metricList
.
get
(
0
).
getTimestamp
())
+
Long
.
parseLong
(
metricList
.
get
(
metricList
.
size
()
-
1
).
getElapsed
());
RequestStatistics
requestStatistics
=
new
RequestStatistics
();
requestStatistics
.
setRequestLabel
(
label
);
requestStatistics
.
setSamples
(
jtlSamplesSize
);
String
average
=
decimalFormat
.
format
((
float
)
oneLineElapsedTime
/
jtlSamplesSize
);
requestStatistics
.
setAverage
(
average
);
/*
* TP90的计算
* 1,把一段时间内全部的请求的响应时间,从小到大排序,获得序列A
* 2,总的请求数量,乘以90%,获得90%对应的请求个数C
* 3,从序列A中找到第C个请求,它的响应时间,即为TP90的值
* 其余相似的指标还有TP95, TP99
*/
// todo tp90
requestStatistics
.
setTp90
(
elapsedList
.
get
(
tp90
)
+
""
);
requestStatistics
.
setTp95
(
elapsedList
.
get
(
tp95
)
+
""
);
requestStatistics
.
setTp99
(
elapsedList
.
get
(
tp99
)
+
""
);
double
avgHits
=
(
double
)
metricList
.
size
()
/
(
time
*
1.0
/
1000
);
requestStatistics
.
setAvgHits
(
decimalFormat
.
format
(
avgHits
));
requestStatistics
.
setMin
(
elapsedList
.
get
(
0
)
+
""
);
requestStatistics
.
setMax
(
elapsedList
.
get
(
jtlSamplesSize
-
1
)
+
""
);
requestStatistics
.
setErrors
(
decimalFormat
.
format
(
failSize
*
100.0
/
jtlSamplesSize
)
+
"%"
);
requestStatistics
.
setKo
(
failSize
);
/*
* 所有的相同请求的bytes总和 / 1024 / 请求持续运行的时间=sum(bytes)/1024/total time
* total time = 最大时间戳 - 最小时间戳 + 最后请求的响应时间
*/
requestStatistics
.
setKbPerSec
(
decimalFormat
.
format
(
oneLineBytes
*
1.0
/
1024
/
(
time
*
1.0
/
1000
)));
requestStatisticsList
.
add
(
requestStatistics
);
}
Collections
.
sort
(
allElapseTimeList
);
int
totalTP90
=
allElapseTimeList
.
size
()
*
90
/
100
;
int
totalTP95
=
allElapseTimeList
.
size
()
*
95
/
100
;
int
totalTP99
=
allElapseTimeList
.
size
()
*
99
/
100
;
Integer
min
=
allElapseTimeList
.
get
(
0
);
Integer
max
=
allElapseTimeList
.
get
(
allElapseTimeList
.
size
()
-
1
);
int
allSamples
=
requestStatisticsList
.
stream
().
mapToInt
(
RequestStatistics:
:
getSamples
).
sum
();
int
failSize
=
requestStatisticsList
.
stream
().
mapToInt
(
RequestStatistics:
:
getKo
).
sum
();
double
errors
=
(
double
)
failSize
/
allSamples
*
100
;
String
totalErrors
=
decimalFormat
.
format
(
errors
);
double
average
=
(
double
)
totalElapsedTime
/
allSamples
;
String
totalAverage
=
decimalFormat
.
format
(
average
);
RequestStatisticsDTO
statisticsDTO
=
new
RequestStatisticsDTO
();
statisticsDTO
.
setRequestStatisticsList
(
requestStatisticsList
);
statisticsDTO
.
setTotalLabel
(
"Total"
);
statisticsDTO
.
setTotalSamples
(
String
.
valueOf
(
allSamples
));
statisticsDTO
.
setTotalErrors
(
totalErrors
+
"%"
);
statisticsDTO
.
setTotalAverage
(
totalAverage
);
statisticsDTO
.
setTotalMin
(
String
.
valueOf
(
min
));
statisticsDTO
.
setTotalMax
(
String
.
valueOf
(
max
));
statisticsDTO
.
setTotalTP90
(
String
.
valueOf
(
allElapseTimeList
.
get
(
totalTP90
)));
statisticsDTO
.
setTotalTP95
(
String
.
valueOf
(
allElapseTimeList
.
get
(
totalTP95
)));
statisticsDTO
.
setTotalTP99
(
String
.
valueOf
(
allElapseTimeList
.
get
(
totalTP99
)));
totalMetricList
.
sort
(
Comparator
.
comparing
(
t0
->
Long
.
valueOf
(
t0
.
getTimestamp
())));
long
ms
=
Long
.
parseLong
(
totalMetricList
.
get
(
totalMetricList
.
size
()
-
1
).
getTimestamp
())
-
Long
.
parseLong
(
totalMetricList
.
get
(
0
).
getTimestamp
())
+
Long
.
parseLong
(
totalMetricList
.
get
(
totalMetricList
.
size
()
-
1
).
getElapsed
());
double
avgThroughput
=
(
double
)
totalMetricList
.
size
()
/
(
ms
*
1.0
/
1000
);
statisticsDTO
.
setTotalAvgHits
(
decimalFormat
.
format
(
avgThroughput
));
statisticsDTO
.
setTotalAvgBandwidth
(
decimalFormat
.
format
(
totalBytes
*
1.0
/
1024
/
(
ms
*
1.0
/
1000
)));
return
statisticsDTO
;
}
public
static
List
<
Errors
>
getErrorsList
(
String
jtlString
)
{
public
static
List
<
Errors
>
getErrorsList
(
String
jtlString
)
{
List
<
Metric
>
totalMetricList
=
resolver
(
jtlString
);
List
<
Metric
>
totalMetricList
=
resolver
(
jtlString
);
...
@@ -205,6 +79,11 @@ public class GenerateReport {
...
@@ -205,6 +79,11 @@ public class GenerateReport {
return
errorsList
;
return
errorsList
;
}
}
public
static
List
<
Statistics
>
getRequestStatistics
(
String
jtlString
)
{
Map
<
String
,
Object
>
statisticsDataMap
=
ResultDataParse
.
getSummryDataMap
(
jtlString
,
new
StatisticsSummaryConsumer
());
return
ResultDataParse
.
summaryMapParsing
(
statisticsDataMap
);
}
private
static
String
getResponseCodeAndFailureMessage
(
Metric
metric
)
{
private
static
String
getResponseCodeAndFailureMessage
(
Metric
metric
)
{
return
metric
.
getResponseCode
()
+
"/"
+
metric
.
getResponseMessage
();
return
metric
.
getResponseCode
()
+
"/"
+
metric
.
getResponseMessage
();
}
}
...
...
backend/src/main/java/io/metersphere/report/base/Statistics.java
0 → 100644
浏览文件 @
68ad0c54
package
io.metersphere.report.base
;
public
class
Statistics
{
private
String
label
;
private
String
samples
;
private
String
ko
;
private
String
error
;
private
String
average
;
private
String
min
;
private
String
max
;
private
String
tp90
;
private
String
tp95
;
private
String
tp99
;
private
String
transactions
;
private
String
received
;
private
String
sent
;
public
String
getLabel
()
{
return
label
;
}
public
void
setLabel
(
String
label
)
{
this
.
label
=
label
;
}
public
String
getSamples
()
{
return
samples
;
}
public
void
setSamples
(
String
samples
)
{
this
.
samples
=
samples
;
}
public
String
getKo
()
{
return
ko
;
}
public
void
setKo
(
String
ko
)
{
this
.
ko
=
ko
;
}
public
String
getError
()
{
return
error
;
}
public
void
setError
(
String
error
)
{
this
.
error
=
error
;
}
public
String
getAverage
()
{
return
average
;
}
public
void
setAverage
(
String
average
)
{
this
.
average
=
average
;
}
public
String
getMin
()
{
return
min
;
}
public
void
setMin
(
String
min
)
{
this
.
min
=
min
;
}
public
String
getMax
()
{
return
max
;
}
public
void
setMax
(
String
max
)
{
this
.
max
=
max
;
}
public
String
getTp90
()
{
return
tp90
;
}
public
void
setTp90
(
String
tp90
)
{
this
.
tp90
=
tp90
;
}
public
String
getTp95
()
{
return
tp95
;
}
public
void
setTp95
(
String
tp95
)
{
this
.
tp95
=
tp95
;
}
public
String
getTp99
()
{
return
tp99
;
}
public
void
setTp99
(
String
tp99
)
{
this
.
tp99
=
tp99
;
}
public
String
getTransactions
()
{
return
transactions
;
}
public
void
setTransactions
(
String
transactions
)
{
this
.
transactions
=
transactions
;
}
public
String
getSent
()
{
return
sent
;
}
public
void
setSent
(
String
sent
)
{
this
.
sent
=
sent
;
}
public
String
getReceived
()
{
return
received
;
}
public
void
setReceived
(
String
received
)
{
this
.
received
=
received
;
}
}
backend/src/main/java/io/metersphere/report/base/SummaryData.java
0 → 100644
浏览文件 @
68ad0c54
package
io.metersphere.report.base
;
import
java.util.List
;
public
class
SummaryData
{
private
List
<
Object
>
result
;
public
List
<
Object
>
getResult
()
{
return
result
;
}
public
void
setResult
(
List
<
Object
>
result
)
{
this
.
result
=
result
;
}
}
backend/src/main/java/io/metersphere/report/dto/RequestStatisticsDTO.java
已删除
100644 → 0
浏览文件 @
b32a6f13
package
io.metersphere.report.dto
;
import
io.metersphere.report.base.RequestStatistics
;
import
java.util.List
;
public
class
RequestStatisticsDTO
extends
RequestStatistics
{
private
List
<
RequestStatistics
>
requestStatisticsList
;
private
String
totalLabel
;
private
String
totalSamples
;
private
String
totalErrors
;
private
String
totalAverage
;
private
String
totalMin
;
private
String
totalMax
;
private
String
totalTP90
;
private
String
totalTP95
;
private
String
totalTP99
;
private
String
totalAvgBandwidth
;
private
String
totalAvgHits
;
public
List
<
RequestStatistics
>
getRequestStatisticsList
()
{
return
requestStatisticsList
;
}
public
void
setRequestStatisticsList
(
List
<
RequestStatistics
>
requestStatisticsList
)
{
this
.
requestStatisticsList
=
requestStatisticsList
;
}
public
String
getTotalLabel
()
{
return
totalLabel
;
}
public
void
setTotalLabel
(
String
totalLabel
)
{
this
.
totalLabel
=
totalLabel
;
}
public
String
getTotalSamples
()
{
return
totalSamples
;
}
public
void
setTotalSamples
(
String
totalSamples
)
{
this
.
totalSamples
=
totalSamples
;
}
public
String
getTotalErrors
()
{
return
totalErrors
;
}
public
void
setTotalErrors
(
String
totalErrors
)
{
this
.
totalErrors
=
totalErrors
;
}
public
String
getTotalAverage
()
{
return
totalAverage
;
}
public
void
setTotalAverage
(
String
totalAverage
)
{
this
.
totalAverage
=
totalAverage
;
}
public
String
getTotalMin
()
{
return
totalMin
;
}
public
void
setTotalMin
(
String
totalMin
)
{
this
.
totalMin
=
totalMin
;
}
public
String
getTotalMax
()
{
return
totalMax
;
}
public
void
setTotalMax
(
String
totalMax
)
{
this
.
totalMax
=
totalMax
;
}
public
String
getTotalTP90
()
{
return
totalTP90
;
}
public
void
setTotalTP90
(
String
totalTP90
)
{
this
.
totalTP90
=
totalTP90
;
}
public
String
getTotalTP95
()
{
return
totalTP95
;
}
public
void
setTotalTP95
(
String
totalTP95
)
{
this
.
totalTP95
=
totalTP95
;
}
public
String
getTotalTP99
()
{
return
totalTP99
;
}
public
void
setTotalTP99
(
String
totalTP99
)
{
this
.
totalTP99
=
totalTP99
;
}
public
String
getTotalAvgBandwidth
()
{
return
totalAvgBandwidth
;
}
public
void
setTotalAvgBandwidth
(
String
totalAvgBandwidth
)
{
this
.
totalAvgBandwidth
=
totalAvgBandwidth
;
}
public
String
getTotalAvgHits
()
{
return
totalAvgHits
;
}
public
void
setTotalAvgHits
(
String
totalAvgHits
)
{
this
.
totalAvgHits
=
totalAvgHits
;
}
}
backend/src/main/java/io/metersphere/report/parse/ResultDataParse.java
浏览文件 @
68ad0c54
package
io.metersphere.report.parse
;
package
io.metersphere.report.parse
;
import
io.metersphere.commons.utils.BeanUtils
;
import
io.metersphere.commons.utils.MsJMeterUtils
;
import
io.metersphere.commons.utils.MsJMeterUtils
;
import
io.metersphere.report.base.ChartsData
;
import
io.metersphere.report.base.ChartsData
;
import
io.metersphere.report.base.Statistics
;
import
io.metersphere.report.base.SummaryData
;
import
org.apache.jmeter.report.core.Sample
;
import
org.apache.jmeter.report.core.Sample
;
import
org.apache.jmeter.report.core.SampleMetadata
;
import
org.apache.jmeter.report.core.SampleMetadata
;
import
org.apache.jmeter.report.dashboard.JsonizerVisitor
;
import
org.apache.jmeter.report.dashboard.JsonizerVisitor
;
import
org.apache.jmeter.report.processor.*
;
import
org.apache.jmeter.report.processor.*
;
import
org.apache.jmeter.report.processor.graph.AbstractOverTimeGraphConsumer
;
import
org.apache.jmeter.report.processor.graph.AbstractOverTimeGraphConsumer
;
import
java.lang.reflect.Field
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.text.ParseException
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.text.SimpleDateFormat
;
...
@@ -14,16 +19,43 @@ import java.time.Instant;
...
@@ -14,16 +19,43 @@ import java.time.Instant;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.time.ZoneId
;
import
java.time.ZoneId
;
import
java.time.format.DateTimeFormatter
;
import
java.time.format.DateTimeFormatter
;
import
java.util.ArrayList
;
import
java.util.*
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.StringTokenizer
;
public
class
ResultDataParse
{
public
class
ResultDataParse
{
private
static
final
String
DATE_TIME_PATTERN
=
"yyyy/MM/dd HH:mm:ss"
;
private
static
final
String
DATE_TIME_PATTERN
=
"yyyy/MM/dd HH:mm:ss"
;
private
static
final
String
TIME_PATTERN
=
"HH:mm:ss"
;
private
static
final
String
TIME_PATTERN
=
"HH:mm:ss"
;
public
static
List
<
Statistics
>
summaryMapParsing
(
Map
<
String
,
Object
>
map
)
{
List
<
Statistics
>
statisticsList
=
new
ArrayList
<>();
for
(
String
key
:
map
.
keySet
())
{
MapResultData
mapResultData
=
(
MapResultData
)
map
.
get
(
key
);
ListResultData
items
=
(
ListResultData
)
mapResultData
.
getResult
(
"items"
);
if
(
items
.
getSize
()
>
0
)
{
for
(
int
i
=
0
;
i
<
items
.
getSize
();
i
++)
{
MapResultData
resultData
=
(
MapResultData
)
items
.
get
(
i
);
ListResultData
data
=
(
ListResultData
)
resultData
.
getResult
(
"data"
);
int
size
=
data
.
getSize
();
String
[]
strArray
=
new
String
[
size
];
for
(
int
j
=
0
;
j
<
size
;
j
++)
{
ValueResultData
valueResultData
=
(
ValueResultData
)
data
.
get
(
j
);
String
accept
=
valueResultData
.
accept
(
new
JsonizerVisitor
());
strArray
[
j
]
=
accept
.
replace
(
"\\"
,
""
);
}
Statistics
statistics
=
null
;
try
{
statistics
=
setParam
(
Statistics
.
class
,
strArray
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
statisticsList
.
add
(
statistics
);
}
}
}
return
statisticsList
;
}
public
static
List
<
ChartsData
>
graphMapParsing
(
Map
<
String
,
Object
>
map
,
String
seriesName
)
{
public
static
List
<
ChartsData
>
graphMapParsing
(
Map
<
String
,
Object
>
map
,
String
seriesName
)
{
List
<
ChartsData
>
list
=
new
ArrayList
<>();
List
<
ChartsData
>
list
=
new
ArrayList
<>();
// ThreadGroup
// ThreadGroup
...
@@ -136,4 +168,21 @@ public class ResultDataParse {
...
@@ -136,4 +168,21 @@ public class ResultDataParse {
SimpleDateFormat
after
=
new
SimpleDateFormat
(
TIME_PATTERN
);
SimpleDateFormat
after
=
new
SimpleDateFormat
(
TIME_PATTERN
);
return
after
.
format
(
before
.
parse
(
dateString
));
return
after
.
format
(
before
.
parse
(
dateString
));
}
}
private
static
<
T
>
T
setParam
(
Class
<
T
>
clazz
,
Object
[]
args
)
throws
Exception
{
if
(
clazz
==
null
||
args
==
null
)
{
throw
new
IllegalArgumentException
();
}
T
t
=
clazz
.
newInstance
();
Field
[]
fields
=
clazz
.
getDeclaredFields
();
if
(
fields
==
null
||
fields
.
length
>
args
.
length
)
{
throw
new
IndexOutOfBoundsException
();
}
for
(
int
i
=
0
;
i
<
fields
.
length
;
i
++)
{
fields
[
i
].
setAccessible
(
true
);
fields
[
i
].
set
(
t
,
args
[
i
]);
}
return
t
;
}
}
}
backend/src/main/java/io/metersphere/service/PerformanceTestService.java
浏览文件 @
68ad0c54
...
@@ -24,6 +24,7 @@ import org.springframework.web.multipart.MultipartFile;
...
@@ -24,6 +24,7 @@ import org.springframework.web.multipart.MultipartFile;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.Optional
;
import
java.util.UUID
;
import
java.util.UUID
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
...
@@ -229,6 +230,23 @@ public class PerformanceTestService {
...
@@ -229,6 +230,23 @@ public class PerformanceTestService {
}
}
}
}
public
Map
<
String
,
String
>
log
(
String
testId
)
{
final
LoadTestWithBLOBs
loadTest
=
loadTestMapper
.
selectByPrimaryKey
(
testId
);
if
(
loadTest
==
null
)
{
MSException
.
throwException
(
Translator
.
get
(
"test_not_found"
)
+
testId
);
}
if
(!
StringUtils
.
equals
(
loadTest
.
getStatus
(),
PerformanceTestStatus
.
Running
.
name
()))
{
MSException
.
throwException
(
Translator
.
get
(
"test_not_running"
));
}
Engine
engine
=
EngineFactory
.
createEngine
(
loadTest
);
if
(
engine
==
null
)
{
MSException
.
throwException
(
String
.
format
(
"Engine is null,test ID:%s"
,
testId
));
}
return
engine
.
log
();
}
public
List
<
LoadTestDTO
>
recentTestPlans
(
QueryTestPlanRequest
request
)
{
public
List
<
LoadTestDTO
>
recentTestPlans
(
QueryTestPlanRequest
request
)
{
// 查询最近的测试计划
// 查询最近的测试计划
request
.
setRecent
(
true
);
request
.
setRecent
(
true
);
...
@@ -260,4 +278,5 @@ public class PerformanceTestService {
...
@@ -260,4 +278,5 @@ public class PerformanceTestService {
example
.
createCriteria
().
andTestResourcePoolIdEqualTo
(
resourcePoolId
);
example
.
createCriteria
().
andTestResourcePoolIdEqualTo
(
resourcePoolId
);
return
loadTestMapper
.
selectByExampleWithBLOBs
(
example
);
return
loadTestMapper
.
selectByExampleWithBLOBs
(
example
);
}
}
}
}
backend/src/main/java/io/metersphere/service/ReportService.java
浏览文件 @
68ad0c54
...
@@ -12,16 +12,11 @@ import io.metersphere.dto.ReportDTO;
...
@@ -12,16 +12,11 @@ import io.metersphere.dto.ReportDTO;
import
io.metersphere.engine.Engine
;
import
io.metersphere.engine.Engine
;
import
io.metersphere.engine.EngineFactory
;
import
io.metersphere.engine.EngineFactory
;
import
io.metersphere.report.GenerateReport
;
import
io.metersphere.report.GenerateReport
;
import
io.metersphere.report.base.ChartsData
;
import
io.metersphere.report.base.*
;
import
io.metersphere.report.base.Errors
;
import
io.metersphere.report.base.ReportTimeInfo
;
import
io.metersphere.report.base.TestOverview
;
import
io.metersphere.report.dto.ErrorsTop5DTO
;
import
io.metersphere.report.dto.ErrorsTop5DTO
;
import
io.metersphere.report.dto.RequestStatisticsDTO
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.annotation.Resource
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
java.util.List
;
...
@@ -86,12 +81,11 @@ public class ReportService {
...
@@ -86,12 +81,11 @@ public class ReportService {
return
extLoadTestReportMapper
.
getReportTestAndProInfo
(
reportId
);
return
extLoadTestReportMapper
.
getReportTestAndProInfo
(
reportId
);
}
}
public
RequestStatisticsDTO
getReport
(
String
id
)
{
public
List
<
Statistics
>
getReport
(
String
id
)
{
checkReportStatus
(
id
);
checkReportStatus
(
id
);
LoadTestReportWithBLOBs
loadTestReport
=
loadTestReportMapper
.
selectByPrimaryKey
(
id
);
LoadTestReportWithBLOBs
loadTestReport
=
loadTestReportMapper
.
selectByPrimaryKey
(
id
);
String
content
=
loadTestReport
.
getContent
();
String
content
=
loadTestReport
.
getContent
();
RequestStatisticsDTO
requestStatistics
=
GenerateReport
.
getRequestStatistics
(
content
);
return
GenerateReport
.
getRequestStatistics
(
content
);
return
requestStatistics
;
}
}
public
List
<
Errors
>
getReportErrors
(
String
id
)
{
public
List
<
Errors
>
getReportErrors
(
String
id
)
{
...
...
backend/src/main/resources/i18n/messages_en_US.properties
浏览文件 @
68ad0c54
...
@@ -19,4 +19,6 @@ duplicate_node_ip=Duplicate IPs
...
@@ -19,4 +19,6 @@ duplicate_node_ip=Duplicate IPs
only_one_k8s
=
Only one K8s can be added
only_one_k8s
=
Only one K8s can be added
organization_id_is_null
=
Organization ID cannot be null
organization_id_is_null
=
Organization ID cannot be null
max_thread_insufficient
=
The number of concurrent users exceeds
max_thread_insufficient
=
The number of concurrent users exceeds
cannot_edit_load_test_running
=
Cannot modify the running test
cannot_edit_load_test_running
=
Cannot modify the running test
\ No newline at end of file
test_not_found
=
Test cannot be found:
test_not_running
=
Test is not running
\ No newline at end of file
backend/src/main/resources/i18n/messages_zh_CN.properties
浏览文件 @
68ad0c54
...
@@ -19,4 +19,6 @@ duplicate_node_ip=节点 IP 重复
...
@@ -19,4 +19,6 @@ duplicate_node_ip=节点 IP 重复
only_one_k8s
=
只能添加一个 K8s
only_one_k8s
=
只能添加一个 K8s
organization_id_is_null
=
组织 ID 不能为空
organization_id_is_null
=
组织 ID 不能为空
max_thread_insufficient
=
并发用户数超额
max_thread_insufficient
=
并发用户数超额
cannot_edit_load_test_running
=
不能修改正在运行的测试
cannot_edit_load_test_running
=
不能修改正在运行的测试
\ No newline at end of file
test_not_found
=
测试不存在:
test_not_running
=
测试未运行
\ No newline at end of file
backend/src/test/java/io/metersphere/ResultDataParseTest.java
0 → 100644
浏览文件 @
68ad0c54
package
io.metersphere
;
import
io.metersphere.report.base.Statistics
;
import
org.junit.Test
;
import
java.lang.reflect.Field
;
public
class
ResultDataParseTest
{
String
[]
s
=
{
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
,
"10"
,
"11"
,
"12"
,
"13"
};
public
static
<
T
>
T
setParam
(
Class
<
T
>
clazz
,
Object
[]
args
)
throws
Exception
{
if
(
clazz
==
null
||
args
==
null
)
{
throw
new
IllegalArgumentException
();
}
T
t
=
clazz
.
newInstance
();
Field
[]
fields
=
clazz
.
getDeclaredFields
();
if
(
fields
==
null
||
fields
.
length
>
args
.
length
)
{
throw
new
IndexOutOfBoundsException
();
}
for
(
int
i
=
0
;
i
<
fields
.
length
;
i
++)
{
fields
[
i
].
setAccessible
(
true
);
fields
[
i
].
set
(
t
,
args
[
i
]);
}
return
t
;
}
@Test
public
void
test
()
throws
Exception
{
Statistics
statistics
=
setParam
(
Statistics
.
class
,
s
);
System
.
out
.
println
(
statistics
.
toString
());
}
}
frontend/src/business/components/performance/report/components/RequestStatistics.vue
浏览文件 @
68ad0c54
...
@@ -6,12 +6,11 @@
...
@@ -6,12 +6,11 @@
border
border
style=
"width: 100%"
style=
"width: 100%"
show-summary
show-summary
:summary-method=
"getSummaries"
:default-sort =
"
{prop: 'samples', order: 'descending'}"
:default-sort =
"
{prop: 'samples', order: 'descending'}"
>
>
<el-table-column
label=
"Requests"
fixed
width=
"450"
align=
"center"
>
<el-table-column
label=
"Requests"
fixed
width=
"450"
align=
"center"
>
<el-table-column
<el-table-column
prop=
"
requestL
abel"
prop=
"
l
abel"
label=
"Label"
label=
"Label"
width=
"450"
/>
width=
"450"
/>
</el-table-column>
</el-table-column>
...
@@ -25,7 +24,13 @@
...
@@ -25,7 +24,13 @@
/>
/>
<el-table-column
<el-table-column
prop=
"errors"
prop=
"ko"
label=
"KO%"
align=
"center"
/>
<el-table-column
prop=
"error"
label=
"Error%"
label=
"Error%"
align=
"center"
align=
"center"
/>
/>
...
@@ -58,18 +63,29 @@
...
@@ -58,18 +63,29 @@
/>
/>
</el-table-column>
</el-table-column>
<el-table-column
<el-table-column
label=
"Throughput"
>
prop=
"avgHits"
<el-table-column
label=
"Avg Hits/s"
prop=
"transactions"
width=
"100"
label=
"Transactions"
/>
width=
"100"
/>
</el-table-column>
<el-table-column
label=
"NetWork(KB/sec)"
align=
"center"
>
<el-table-column
prop=
"received"
label=
"Received"
align=
"center"
width=
"200"
/>
<el-table-column
prop=
"sent"
label=
"Sent"
align=
"center"
width=
"200"
/>
</el-table-column>
<el-table-column
prop=
"kbPerSec"
label=
"Avg Bandwidth(KBytes/s)"
align=
"center"
width=
"200"
/>
</el-table>
</el-table>
</div>
</div>
</
template
>
</
template
>
...
@@ -79,50 +95,20 @@
...
@@ -79,50 +95,20 @@
name
:
"
RequestStatistics
"
,
name
:
"
RequestStatistics
"
,
data
()
{
data
()
{
return
{
return
{
tableData
:
[{},{},{},{},{}],
tableData
:
[{},{},{},{},{}]
totalInfo
:
{
totalLabel
:
''
,
totalSamples
:
''
,
totalErrors
:
''
,
totalAverage
:
''
,
totalMin
:
''
,
totalMax
:
''
,
totalTP90
:
''
,
totalTP95
:
''
,
totalTP99
:
''
,
totalAvgHits
:
''
,
totalAvgBandwidth
:
''
}
}
}
},
},
methods
:
{
methods
:
{
initTableData
()
{
initTableData
()
{
this
.
$get
(
"
/performance/report/content/
"
+
this
.
id
,
res
=>
{
this
.
$get
(
"
/performance/report/content/
"
+
this
.
id
,
res
=>
{
this
.
tableData
=
res
.
data
.
requestStatisticsList
;
this
.
tableData
=
res
.
data
;
this
.
totalInfo
=
res
.
data
;
})
})
},
},
getSummaries
()
{
const
sums
=
[]
sums
[
0
]
=
this
.
totalInfo
.
totalLabel
;
sums
[
1
]
=
this
.
totalInfo
.
totalSamples
;
sums
[
2
]
=
this
.
totalInfo
.
totalErrors
;
sums
[
3
]
=
this
.
totalInfo
.
totalAverage
;
sums
[
4
]
=
this
.
totalInfo
.
totalMin
;
sums
[
5
]
=
this
.
totalInfo
.
totalMax
;
sums
[
6
]
=
this
.
totalInfo
.
totalTP90
;
sums
[
7
]
=
this
.
totalInfo
.
totalTP95
;
sums
[
8
]
=
this
.
totalInfo
.
totalTP99
;
sums
[
9
]
=
this
.
totalInfo
.
totalAvgHits
;
sums
[
10
]
=
this
.
totalInfo
.
totalAvgBandwidth
;
return
sums
;
}
},
},
watch
:
{
watch
:
{
status
()
{
status
()
{
if
(
"
Completed
"
===
this
.
status
)
{
if
(
"
Completed
"
===
this
.
status
)
{
this
.
initTableData
()
this
.
initTableData
()
this
.
getSummaries
()
}
}
}
}
},
},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录