123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- import React from 'react'
- import ReactECharts from 'echarts-for-react'
- import * as echarts from 'echarts'
- import { get } from 'lodash'
- import s from './index.less'
- import { Descriptions, Divider } from 'antd'
- const Page = props => {
- const [data, setData] = React.useState({})
- React.useEffect(() => {
- const { data = {} } = props
- setData(data)
- }, [])
- const {
- // saveAsImage = {
- // icon:
- // 'image://https://cdn.weipaitang.com/static/public/20210824acf87486-499f-7486499f-1d32-40d793b1fd05.svg'
- // }
- saveAsImage = false,
- showTitle = true,
- showLine = false
- } = props
- function getOptions (title, xData = [], yData = [], {
- yFormat = '{value}',
- tooltipFormat,
- yMax,
- showAreaStyle
- } = {}) {
- return {
- tooltip: {
- trigger: 'axis',
- position: function (pt) {
- return [pt[0], '10%']
- },
- formatter: function (params) {
- let rez = `<div>${params[0].axisValue}</div>`
- params.forEach(item => {
- const strItem = `<div style="display: flex; justify-content: space-between;">
- <div style="padding-right: 10px">
- ${item.marker} ${item.seriesName}
- </div>
- <div style="color: #666;">
- ${tooltipFormat ? tooltipFormat(item.value) : item.value}
- </div>
- </div>`
- rez += strItem
- })
- return rez
- }
- },
- grid: {
- left: '60px',
- right: '28px',
- containLabel: true
- },
- title: {
- left: 'center',
- text: title,
- textStyle: {
- fontSize: 16,
- fontWeight: 'normal',
- color: '#666'
- }
- },
- toolbox: {
- feature: {
- saveAsImage: saveAsImage
- }
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: xData
- },
- yAxis: {
- type: 'value',
- boundaryGap: [0, '100%'],
- axisLabel: {
- show: true,
- interval: 'auto',
- formatter: yFormat
- },
- max: yMax
- },
- dataZoom: [
- {
- type: 'inside',
- start: 0,
- end: 100
- },
- {
- start: 0,
- end: 100
- }
- ],
- series: yData.map((yItem, index) => {
- const h = ((yData.length - index) * (255 / yData.length)) >> 0
- return {
- name: yItem.name,
- type: 'line',
- symbol: 'none',
- sampling: 'lttb',
- itemStyle: {
- color: yData.length === 1 ? 'rgb(255, 70, 131)' : `hsl(${h}, 100%, 64%)`
- },
- ...(
- showAreaStyle ? {
- areaStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- {
- offset: 0,
- color: 'rgb(255, 158, 68)'
- },
- {
- offset: 1,
- color: 'rgb(255, 70, 131)'
- }
- ])
- }
- } : {}
- ),
- data: yItem.data
- }
- })
- }
- }
- function getSeriesYData (data, format) {
- const _data = data
- return Object.keys(_data).map(key => {
- return {
- name: key,
- data: _data[key].vertical.map(item => {
- if (format) {
- return format(item)
- } else {
- return item
- }
- })
- }
- })
- }
- function getSeriesXData (data) {
- return Object.keys(data).reduce((acc, key) => {
- return data[key].cross
- }, {})
- }
- return (
- <div>
- {
- showLine && (
- <Divider />
- )
- }
- {
- showTitle && (
- <div className={s.title}>
- {data.taskName}-压测报告
- </div>
- )
- }
- <div className={s.descriptionWrap}>
- <Descriptions bordered>
- <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>
- <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="99% 延时">{get(data, 'report.latency_p99')}</Descriptions.Item>
- </Descriptions>
- </div>
- <ReactECharts
- option={getOptions('压力持续图', get(data, 'pressure_data.cross'), [
- { name: '数据', data: get(data, 'pressure_data.vertical') }
- ], { showAreaStyle: true })}
- />
- <div className={s.chartWrap}>
- <div className={s.chartItem}>
- <ReactECharts
- option={getOptions(
- 'CPU 使用率',
- getSeriesXData(get(data, 'monitor.metrics.node_cpu_seconds_total') || {}),
- getSeriesYData(get(data, 'monitor.metrics.node_cpu_seconds_total') || {}),
- {
- yFormat: function (value) {
- return value + '%'
- },
- tooltipFormat: function (value) {
- return value + '%'
- },
- yMax: 100
- }
- )}
- />
- </div>
- <div className={s.chartItem}>
- <ReactECharts
- option={getOptions(
- '内存使用率',
- getSeriesXData(get(data, 'monitor.metrics.memUsage') || {}),
- getSeriesYData(get(data, 'monitor.metrics.memUsage') || {}),
- {
- yFormat: function (value) {
- return value + '%'
- },
- tooltipFormat: function (value) {
- return value + '%'
- },
- yMax: 100
- }
- )}
- />
- </div>
- </div>
- <div className={s.chartWrap}>
- <div className={s.chartItem}>
- <ReactECharts
- option={getOptions(
- '磁盘读取',
- 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)),
- {
- yFormat: function (value) {
- return value + 'kb/s'
- },
- tooltipFormat: function (value) {
- return value + 'kb/s'
- }
- }
- )}
- />
- </div>
- <div className={s.chartItem}>
- <ReactECharts
- option={getOptions(
- '磁盘写入',
- 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)),
- {
- yFormat: function (value) {
- return value + 'kb/s'
- },
- tooltipFormat: function (value) {
- return value + 'kb/s'
- }
- }
- )}
- />
- </div>
- </div>
- <div className={s.chartWrap}>
- <div className={s.chartItem}>
- <ReactECharts
- option={getOptions(
- 'FPM',
- getSeriesXData(get(data, 'monitor.metrics.phpfpm_processes_total') || {}),
- getSeriesYData(get(data, 'monitor.metrics.phpfpm_processes_total') || {})
- )}
- />
- </div>
- </div>
- </div>
- )
- }
- export default Page
|