From b7a876aaf46c0da4752ec749d10bfd725e681168 Mon Sep 17 00:00:00 2001 From: shiyang Date: Sat, 21 Nov 2020 00:37:05 +0800 Subject: [PATCH] add gateway monitor page --- .gitignore | 3 +- web/config/router.config.js | 6 +- web/src/pages/Dashboard/ClusterMonitor.js | 48 +++++ web/src/pages/Dashboard/GatewayMonitor.js | 156 +++++++++++++++ web/src/pages/Dashboard/GatewayMonitor.less | 178 ++++++++++++++++++ .../Dashboard/{Search.js => SearchMonitor.js} | 4 +- web/src/pages/Dashboard/TaskMonitor.js | 48 +++++ 7 files changed, 437 insertions(+), 6 deletions(-) create mode 100644 web/src/pages/Dashboard/ClusterMonitor.js create mode 100644 web/src/pages/Dashboard/GatewayMonitor.js create mode 100644 web/src/pages/Dashboard/GatewayMonitor.less rename web/src/pages/Dashboard/{Search.js => SearchMonitor.js} (94%) create mode 100644 web/src/pages/Dashboard/TaskMonitor.js diff --git a/.gitignore b/.gitignore index 6fc1423b..9f043f85 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ appveyor.yml /vendor /bin *.exe -web/.github/ \ No newline at end of file +web/.github/ +web/report* \ No newline at end of file diff --git a/web/config/router.config.js b/web/config/router.config.js index b82b0695..9ae058ed 100644 --- a/web/config/router.config.js +++ b/web/config/router.config.js @@ -18,7 +18,7 @@ export default [ authority: ['admin', 'user'], routes: [ // dashboard - { path: '/', redirect: '/platform/gateway' }, + { path: '/', redirect: '/platform/cluster' }, { path: '/platform', name: 'platform', @@ -28,7 +28,7 @@ export default [ { path: '/platform/gateway', name: 'gateway', - component: './Dashboard/Analysis', + component: './Dashboard/GatewayMonitor', }, { path: '/platform/cluster', name: 'cluster', @@ -40,7 +40,7 @@ export default [ }, { path: '/platform/search', name: 'search', - component: './Dashboard/Search', + component: './Dashboard/SearchMonitor', }, ] }, diff --git a/web/src/pages/Dashboard/ClusterMonitor.js b/web/src/pages/Dashboard/ClusterMonitor.js new file mode 100644 index 00000000..2f7a05d5 --- /dev/null +++ b/web/src/pages/Dashboard/ClusterMonitor.js @@ -0,0 +1,48 @@ +import React, { PureComponent } from 'react'; +import { connect } from 'dva'; +import { formatMessage, FormattedMessage } from 'umi/locale'; +import { Row, Col, Card, Tooltip } from 'antd'; +import numeral from 'numeral'; +import { Pie, WaterWave, Gauge, TagCloud } from '@/components/Charts'; +import NumberInfo from '@/components/NumberInfo'; +import CountDown from '@/components/CountDown'; +import ActiveChart from '@/components/ActiveChart'; +import GridContent from '@/components/PageHeaderWrapper/GridContent'; + +import Authorized from '@/utils/Authorized'; +import styles from './Monitor.less'; + +const { Secured } = Authorized; + +const targetTime = new Date().getTime() + 3900000; + +// use permission as a parameter +const havePermissionAsync = new Promise(resolve => { + // Call resolve on behalf of passed + setTimeout(() => resolve(), 300); +}); + +@Secured(havePermissionAsync) +@connect(({ monitor, loading }) => ({ + monitor, + loading: loading.models.monitor, +})) +class ClusterMonitor extends PureComponent { + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'monitor/fetchTags', + }); + } + + render() { + const { monitor, loading } = this.props; + const { tags } = monitor; + + return ( +

cluster monitor

+ ); + } +} + +export default ClusterMonitor; diff --git a/web/src/pages/Dashboard/GatewayMonitor.js b/web/src/pages/Dashboard/GatewayMonitor.js new file mode 100644 index 00000000..53da2579 --- /dev/null +++ b/web/src/pages/Dashboard/GatewayMonitor.js @@ -0,0 +1,156 @@ +import React, { PureComponent } from 'react'; + +import GridContent from '@/components/PageHeaderWrapper/GridContent'; +import { + Row, + Col, + Icon, + Card, + Tabs, + Table, + Radio, + DatePicker, + Menu, + Dropdown, +} from 'antd'; +import { Chart, Geom, Axis, Tooltip, Legend, Coord } from 'bizcharts'; +import DataSet from '@antv/data-set'; +import Slider from 'bizcharts-plugin-slider'; + +import stylesGateway from "./GatewayMonitor.less"; + +const styles ={ + ...stylesGateway, + mainTitle:{ + fontSize:20, + color:"black", + textAlign:"center" + }, + subTitle:{ + fontSize:16, + color:"gray", + textAlign:"center" + } +} + +class GatewayMonitor extends PureComponent { + + //时间戳转换方法 date:时间戳数字 + formatDate(timestamp) { + var date = new Date(timestamp); + var YY = date.getFullYear(); + var MM = '-' + (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1); + var DD = '-' + (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()); + var hh = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()); + var mm = ':' + (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()); + var ss = ':' + (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()); + // return YY + MM + DD +" "+hh + mm + ss; + return hh + mm; + } + + render() { + + // 数据源 + const chartDataIndex = []; + const chartDataQuery = []; + for (let i = 0; i < 24; i += 1) { + chartDataIndex.push({ + x_time: this.formatDate(new Date().getTime() + (1000 * 60 * 60 * (i-24))), + y_value: Math.floor(Math.random() * 100) * 100, + }); + chartDataQuery.push({ + x_time: this.formatDate(new Date().getTime() + (1000 * 60 * 60 * (i-24))), + y_value: Math.floor(Math.random() * 100) * 500, + }); + } + +// 定义度量 + const cols = { + y_value: { + min: 0, + alias: '次数' + }, + x_time: { + range: [0, 1], + alias: '时间' + } + }; + + return ( + + + + + +

+ 索引QPS +

+ + + + + +
+
+ + + +
+ +

+ 查询QPS +

+ + + + + + +
+
+
+ +
+
+ ) + } +} +export default GatewayMonitor; \ No newline at end of file diff --git a/web/src/pages/Dashboard/GatewayMonitor.less b/web/src/pages/Dashboard/GatewayMonitor.less new file mode 100644 index 00000000..493aeb2f --- /dev/null +++ b/web/src/pages/Dashboard/GatewayMonitor.less @@ -0,0 +1,178 @@ +@import '~antd/lib/style/themes/default.less'; +@import '~@/utils/utils.less'; + +.iconGroup { + i { + transition: color 0.32s; + color: @text-color-secondary; + cursor: pointer; + margin-left: 16px; + &:hover { + color: @text-color; + } + } +} + +.rankingList { + margin: 25px 0 0; + padding: 0; + list-style: none; + li { + .clearfix(); + margin-top: 16px; + display: flex; + align-items: center; + span { + color: @text-color; + font-size: 14px; + line-height: 22px; + } + .rankingItemNumber { + background-color: @background-color-base; + border-radius: 20px; + display: inline-block; + font-size: 12px; + font-weight: 600; + margin-right: 16px; + height: 20px; + line-height: 20px; + width: 20px; + text-align: center; + margin-top: 1.5px; + &.active { + background-color: #314659; + color: #fff; + } + } + .rankingItemTitle { + flex: 1; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + margin-right: 8px; + } + } +} + +.salesExtra { + display: inline-block; + margin-right: 24px; + a { + color: @text-color; + margin-left: 24px; + &:hover { + color: @primary-color; + } + &.currentDate { + color: @primary-color; + } + } +} + +.salesCard { + .salesBar { + padding: 0 0 32px 32px; + } + .salesRank { + padding: 0 32px 32px 72px; + } + :global { + .ant-tabs-bar { + padding-left: 16px; + .ant-tabs-nav .ant-tabs-tab { + padding-top: 16px; + padding-bottom: 14px; + line-height: 24px; + } + } + .ant-tabs-extra-content { + padding-right: 24px; + line-height: 55px; + } + .ant-card-head { + position: relative; + } + .ant-card-head-title { + align-items: normal; + } + } +} + +.salesCardExtra { + height: 68px; +} + +.salesTypeRadio { + position: absolute; + left: 24px; + bottom: 15px; +} + +.offlineCard { + :global { + .ant-tabs-ink-bar { + bottom: auto; + } + .ant-tabs-bar { + border-bottom: none; + } + .ant-tabs-nav-container-scrolling { + padding-left: 40px; + padding-right: 40px; + } + .ant-tabs-tab-prev-icon:before { + position: relative; + left: 6px; + } + .ant-tabs-tab-next-icon:before { + position: relative; + right: 6px; + } + .ant-tabs-tab-active h4 { + color: @primary-color; + } + } +} + +.trendText { + margin-left: 8px; + color: @heading-color; +} + +@media screen and (max-width: @screen-lg) { + .salesExtra { + display: none; + } + + .rankingList { + li { + span:first-child { + margin-right: 8px; + } + } + } +} + +@media screen and (max-width: @screen-md) { + .rankingTitle { + margin-top: 16px; + } + + .salesCard .salesBar { + padding: 16px; + } +} + +@media screen and (max-width: @screen-sm) { + .salesExtraWrap { + display: none; + } + + .salesCard { + :global { + .ant-tabs-content { + padding-top: 30px; + } + } + } +} diff --git a/web/src/pages/Dashboard/Search.js b/web/src/pages/Dashboard/SearchMonitor.js similarity index 94% rename from web/src/pages/Dashboard/Search.js rename to web/src/pages/Dashboard/SearchMonitor.js index 0f9f44ac..cdc57f3f 100644 --- a/web/src/pages/Dashboard/Search.js +++ b/web/src/pages/Dashboard/SearchMonitor.js @@ -27,7 +27,7 @@ const havePermissionAsync = new Promise(resolve => { monitor, loading: loading.models.monitor, })) -class Search extends PureComponent { +class SearchMonitor extends PureComponent { componentDidMount() { const { dispatch } = this.props; dispatch({ @@ -45,4 +45,4 @@ class Search extends PureComponent { } } -export default Search; +export default SearchMonitor; diff --git a/web/src/pages/Dashboard/TaskMonitor.js b/web/src/pages/Dashboard/TaskMonitor.js new file mode 100644 index 00000000..cbda8986 --- /dev/null +++ b/web/src/pages/Dashboard/TaskMonitor.js @@ -0,0 +1,48 @@ +import React, { PureComponent } from 'react'; +import { connect } from 'dva'; +import { formatMessage, FormattedMessage } from 'umi/locale'; +import { Row, Col, Card, Tooltip } from 'antd'; +import numeral from 'numeral'; +import { Pie, WaterWave, Gauge, TagCloud } from '@/components/Charts'; +import NumberInfo from '@/components/NumberInfo'; +import CountDown from '@/components/CountDown'; +import ActiveChart from '@/components/ActiveChart'; +import GridContent from '@/components/PageHeaderWrapper/GridContent'; + +import Authorized from '@/utils/Authorized'; +import styles from './Monitor.less'; + +const { Secured } = Authorized; + +const targetTime = new Date().getTime() + 3900000; + +// use permission as a parameter +const havePermissionAsync = new Promise(resolve => { + // Call resolve on behalf of passed + setTimeout(() => resolve(), 300); +}); + +@Secured(havePermissionAsync) +@connect(({ monitor, loading }) => ({ + monitor, + loading: loading.models.monitor, +})) +class TaskMonitor extends PureComponent { + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'monitor/fetchTags', + }); + } + + render() { + const { monitor, loading } = this.props; + const { tags } = monitor; + + return ( +

task monitor

+ ); + } +} + +export default TaskMonitor;