|
@@ -6,9 +6,41 @@ import s from './index.less'
|
|
import { Descriptions, Divider } from 'antd'
|
|
import { Descriptions, Divider } from 'antd'
|
|
const Page = props => {
|
|
const Page = props => {
|
|
const [data, setData] = React.useState({})
|
|
const [data, setData] = React.useState({})
|
|
|
|
+ const [CVMQPS, setCVMQPS] = React.useState({
|
|
|
|
+ x: [],
|
|
|
|
+ y: []
|
|
|
|
+ })
|
|
|
|
|
|
React.useEffect(() => {
|
|
React.useEffect(() => {
|
|
- const { data = {} } = props
|
|
|
|
|
|
+ const { data = {}, selectedRowKeys = [], dataSourceMap, showTitle } = props
|
|
|
|
+ const CVMQPS_x = []
|
|
|
|
+ const CVMQPS_y = []
|
|
|
|
+ const CVMQPS_xy = []
|
|
|
|
+ if (selectedRowKeys.length > 1 && showTitle) {
|
|
|
|
+ selectedRowKeys.forEach(item => {
|
|
|
|
+ const {
|
|
|
|
+ connects,
|
|
|
|
+ report: { summary_req_sec }
|
|
|
|
+ } = dataSourceMap[item]
|
|
|
|
+ CVMQPS_xy.push({
|
|
|
|
+ x: connects,
|
|
|
|
+ y: summary_req_sec
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ CVMQPS_xy.sort((m, n) => {
|
|
|
|
+ var a = m.x
|
|
|
|
+ var b = n.x
|
|
|
|
+ return a - b // 升序
|
|
|
|
+ })
|
|
|
|
+ CVMQPS_xy.forEach(item => {
|
|
|
|
+ CVMQPS_x.push(item.x)
|
|
|
|
+ CVMQPS_y.push(item.y)
|
|
|
|
+ })
|
|
|
|
+ setCVMQPS({
|
|
|
|
+ x: CVMQPS_x,
|
|
|
|
+ y: CVMQPS_y
|
|
|
|
+ })
|
|
|
|
+ }
|
|
setData(data)
|
|
setData(data)
|
|
}, [])
|
|
}, [])
|
|
|
|
|
|
@@ -21,13 +53,57 @@ const Page = props => {
|
|
showTitle = true,
|
|
showTitle = true,
|
|
showLine = false
|
|
showLine = false
|
|
} = props
|
|
} = props
|
|
-
|
|
|
|
- function getOptions (title, xData = [], yData = [], {
|
|
|
|
- yFormat = '{value}',
|
|
|
|
- tooltipFormat,
|
|
|
|
- yMax,
|
|
|
|
- showAreaStyle
|
|
|
|
- } = {}) {
|
|
|
|
|
|
+ function getQPSOptions (title, xData = [], yData = []) {
|
|
|
|
+ return {
|
|
|
|
+ title: {
|
|
|
|
+ text: title
|
|
|
|
+ },
|
|
|
|
+ tooltip: {
|
|
|
|
+ trigger: 'axis',
|
|
|
|
+ axisPointer: {
|
|
|
|
+ label: {
|
|
|
|
+ show: true,
|
|
|
|
+ formatter: '链接数 {value} '
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ grid: {
|
|
|
|
+ left: '3%',
|
|
|
|
+ right: '8%',
|
|
|
|
+ bottom: '3%',
|
|
|
|
+ containLabel: true
|
|
|
|
+ },
|
|
|
|
+ toolbox: {
|
|
|
|
+ feature: {
|
|
|
|
+ saveAsImage: {}
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ xAxis: {
|
|
|
|
+ type: 'category',
|
|
|
|
+ name: '链接数',
|
|
|
|
+ boundaryGap: false,
|
|
|
|
+ data: xData
|
|
|
|
+ },
|
|
|
|
+ yAxis: {
|
|
|
|
+ type: 'value',
|
|
|
|
+ name: 'QPS'
|
|
|
|
+ },
|
|
|
|
+ series: [
|
|
|
|
+ {
|
|
|
|
+ name: 'QPS',
|
|
|
|
+ type: 'line',
|
|
|
|
+ stack: 'Total',
|
|
|
|
+ data: yData
|
|
|
|
+ }
|
|
|
|
+ ]
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ function getOptions (
|
|
|
|
+ title,
|
|
|
|
+ xData = [],
|
|
|
|
+ yData = [],
|
|
|
|
+ { yFormat = '{value}', tooltipFormat, yMax, showAreaStyle } = {}
|
|
|
|
+ ) {
|
|
return {
|
|
return {
|
|
tooltip: {
|
|
tooltip: {
|
|
trigger: 'axis',
|
|
trigger: 'axis',
|
|
@@ -105,8 +181,8 @@ const Page = props => {
|
|
itemStyle: {
|
|
itemStyle: {
|
|
color: yData.length === 1 ? 'rgb(255, 70, 131)' : `hsl(${h}, 100%, 64%)`
|
|
color: yData.length === 1 ? 'rgb(255, 70, 131)' : `hsl(${h}, 100%, 64%)`
|
|
},
|
|
},
|
|
- ...(
|
|
|
|
- showAreaStyle ? {
|
|
|
|
|
|
+ ...(showAreaStyle
|
|
|
|
+ ? {
|
|
areaStyle: {
|
|
areaStyle: {
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
{
|
|
{
|
|
@@ -119,8 +195,8 @@ const Page = props => {
|
|
}
|
|
}
|
|
])
|
|
])
|
|
}
|
|
}
|
|
- } : {}
|
|
|
|
- ),
|
|
|
|
|
|
+ }
|
|
|
|
+ : {}),
|
|
data: yItem.data
|
|
data: yItem.data
|
|
}
|
|
}
|
|
})
|
|
})
|
|
@@ -151,34 +227,39 @@ const Page = props => {
|
|
|
|
|
|
return (
|
|
return (
|
|
<div>
|
|
<div>
|
|
- {
|
|
|
|
- showLine && (
|
|
|
|
- <Divider />
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
- {
|
|
|
|
|
|
+ {showLine && <Divider />}
|
|
|
|
+ {showTitle && (
|
|
|
|
+ <div className={s.title}>
|
|
|
|
+ {data.taskName}-压测报告
|
|
|
|
+ {CVMQPS.x.length > 0 && (
|
|
|
|
+ <ReactECharts option={getQPSOptions('QPS趋势图', CVMQPS.x, CVMQPS.y)} />
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
|
|
+ )}
|
|
|
|
|
|
- showTitle && (
|
|
|
|
- <div className={s.title}>
|
|
|
|
- {data.taskName}-压测报告
|
|
|
|
- </div>
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
<div className={s.descriptionWrap}>
|
|
<div className={s.descriptionWrap}>
|
|
<Descriptions bordered>
|
|
<Descriptions bordered>
|
|
<Descriptions.Item label="压测参数" span={24}>
|
|
<Descriptions.Item label="压测参数" span={24}>
|
|
- -t {data.threads} -c {data.connects} -d {data.duration} -timeout {data.timeout}</Descriptions.Item>
|
|
|
|
- <Descriptions.Item label="服务器配置" span={8}>{get(data, 'monitor.infoResult')}</Descriptions.Item>
|
|
|
|
- <Descriptions.Item label="部署类型" span={8}>{get(data, 'monitor.deployType')}</Descriptions.Item>
|
|
|
|
|
|
+ -t {data.threads} -c {data.connects} -d {data.duration} -timeout {data.timeout}
|
|
|
|
+ </Descriptions.Item>
|
|
|
|
+ <Descriptions.Item label="服务器配置" span={8}>
|
|
|
|
+ {get(data, 'monitor.infoResult')}
|
|
|
|
+ </Descriptions.Item>
|
|
|
|
+ <Descriptions.Item label="部署类型" span={8}>
|
|
|
|
+ {get(data, 'monitor.deployType')}
|
|
|
|
+ </Descriptions.Item>
|
|
<Descriptions.Item label="QPS">{get(data, 'report.summary_req_sec')}</Descriptions.Item>
|
|
<Descriptions.Item label="QPS">{get(data, 'report.summary_req_sec')}</Descriptions.Item>
|
|
<Descriptions.Item label="平均延时">{get(data, 'report.latency_mean')}</Descriptions.Item>
|
|
<Descriptions.Item label="平均延时">{get(data, 'report.latency_mean')}</Descriptions.Item>
|
|
<Descriptions.Item label="99% 延时">{get(data, 'report.latency_p99')}</Descriptions.Item>
|
|
<Descriptions.Item label="99% 延时">{get(data, 'report.latency_p99')}</Descriptions.Item>
|
|
</Descriptions>
|
|
</Descriptions>
|
|
</div>
|
|
</div>
|
|
<ReactECharts
|
|
<ReactECharts
|
|
- option={getOptions('压力持续图', get(data, 'pressure_data.cross'), [
|
|
|
|
- { name: '数据', data: get(data, 'pressure_data.vertical') }
|
|
|
|
- ], { showAreaStyle: true })}
|
|
|
|
|
|
+ option={getOptions(
|
|
|
|
+ '压力持续图',
|
|
|
|
+ get(data, 'pressure_data.cross'),
|
|
|
|
+ [{ name: '数据', data: get(data, 'pressure_data.vertical') }],
|
|
|
|
+ { showAreaStyle: true }
|
|
|
|
+ )}
|
|
/>
|
|
/>
|
|
<div className={s.chartWrap}>
|
|
<div className={s.chartWrap}>
|
|
<div className={s.chartItem}>
|
|
<div className={s.chartItem}>
|
|
@@ -224,7 +305,9 @@ const Page = props => {
|
|
option={getOptions(
|
|
option={getOptions(
|
|
'磁盘读取',
|
|
'磁盘读取',
|
|
getSeriesXData(get(data, 'monitor.metrics.node_disk_read_bytes_total') || {}),
|
|
getSeriesXData(get(data, 'monitor.metrics.node_disk_read_bytes_total') || {}),
|
|
- getSeriesYData(get(data, 'monitor.metrics.node_disk_read_bytes_total') || {}, value => (value / 1024).toFixed(2)),
|
|
|
|
|
|
+ getSeriesYData(get(data, 'monitor.metrics.node_disk_read_bytes_total') || {}, value =>
|
|
|
|
+ (value / 1024).toFixed(2)
|
|
|
|
+ ),
|
|
{
|
|
{
|
|
yFormat: function (value) {
|
|
yFormat: function (value) {
|
|
return value + 'kb/s'
|
|
return value + 'kb/s'
|
|
@@ -241,7 +324,10 @@ const Page = props => {
|
|
option={getOptions(
|
|
option={getOptions(
|
|
'磁盘写入',
|
|
'磁盘写入',
|
|
getSeriesXData(get(data, 'monitor.metrics.node_disk_written_bytes_total') || {}),
|
|
getSeriesXData(get(data, 'monitor.metrics.node_disk_written_bytes_total') || {}),
|
|
- getSeriesYData(get(data, 'monitor.metrics.node_disk_written_bytes_total') || {}, value => (value / 1024).toFixed(2)),
|
|
|
|
|
|
+ getSeriesYData(
|
|
|
|
+ get(data, 'monitor.metrics.node_disk_written_bytes_total') || {},
|
|
|
|
+ value => (value / 1024).toFixed(2)
|
|
|
|
+ ),
|
|
{
|
|
{
|
|
yFormat: function (value) {
|
|
yFormat: function (value) {
|
|
return value + 'kb/s'
|
|
return value + 'kb/s'
|