add gateway monitor page
This commit is contained in:
parent
b4622b3e83
commit
b7a876aaf4
|
@ -28,4 +28,5 @@ appveyor.yml
|
||||||
/vendor
|
/vendor
|
||||||
/bin
|
/bin
|
||||||
*.exe
|
*.exe
|
||||||
web/.github/
|
web/.github/
|
||||||
|
web/report*
|
|
@ -18,7 +18,7 @@ export default [
|
||||||
authority: ['admin', 'user'],
|
authority: ['admin', 'user'],
|
||||||
routes: [
|
routes: [
|
||||||
// dashboard
|
// dashboard
|
||||||
{ path: '/', redirect: '/platform/gateway' },
|
{ path: '/', redirect: '/platform/cluster' },
|
||||||
{
|
{
|
||||||
path: '/platform',
|
path: '/platform',
|
||||||
name: 'platform',
|
name: 'platform',
|
||||||
|
@ -28,7 +28,7 @@ export default [
|
||||||
{
|
{
|
||||||
path: '/platform/gateway',
|
path: '/platform/gateway',
|
||||||
name: 'gateway',
|
name: 'gateway',
|
||||||
component: './Dashboard/Analysis',
|
component: './Dashboard/GatewayMonitor',
|
||||||
}, {
|
}, {
|
||||||
path: '/platform/cluster',
|
path: '/platform/cluster',
|
||||||
name: 'cluster',
|
name: 'cluster',
|
||||||
|
@ -40,7 +40,7 @@ export default [
|
||||||
}, {
|
}, {
|
||||||
path: '/platform/search',
|
path: '/platform/search',
|
||||||
name: 'search',
|
name: 'search',
|
||||||
component: './Dashboard/Search',
|
component: './Dashboard/SearchMonitor',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -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 (
|
||||||
|
<h1>cluster monitor</h1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ClusterMonitor;
|
|
@ -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 (
|
||||||
|
<GridContent>
|
||||||
|
<Row gutter={24}>
|
||||||
|
<Col xl={12} lg={24} md={24} sm={24} xs={24}>
|
||||||
|
<Card
|
||||||
|
loading={false}
|
||||||
|
className={styles.offlineCard}
|
||||||
|
bordered={false}
|
||||||
|
bodyStyle={{ padding: '30px 0 10px' }}
|
||||||
|
style={{ marginTop: 32 }}
|
||||||
|
>
|
||||||
|
<Chart height={400} data={chartDataIndex} scale={cols} forceFit>
|
||||||
|
<h3 className='main-title' style={styles.mainTitle}>
|
||||||
|
索引QPS
|
||||||
|
</h3>
|
||||||
|
<Axis name="year" title/>
|
||||||
|
<Axis name="value" title/>
|
||||||
|
<Tooltip
|
||||||
|
crosshairs={{
|
||||||
|
type: "y"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Geom type="line" position="x_time*y_value" size={2} />
|
||||||
|
<Geom
|
||||||
|
type="point"
|
||||||
|
position="x_time*y_value"
|
||||||
|
size={4}
|
||||||
|
shape={"circle"}
|
||||||
|
style={{
|
||||||
|
stroke: "#fff",
|
||||||
|
lineWidth: 1
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Chart>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
<Col xl={12} lg={24} md={24} sm={24} xs={24}>
|
||||||
|
<Card
|
||||||
|
loading={false}
|
||||||
|
className={styles.offlineCard}
|
||||||
|
bordered={false}
|
||||||
|
bodyStyle={{ padding: '30px 0 10px' }}
|
||||||
|
style={{ marginTop: 32 }}
|
||||||
|
>
|
||||||
|
<div style={{ padding: '0 24px' }}>
|
||||||
|
<Chart height={400} data={chartDataQuery} scale={cols} forceFit>
|
||||||
|
<h3 className='main-title' style={styles.mainTitle}>
|
||||||
|
查询QPS
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<Axis name="year" />
|
||||||
|
<Axis name="value" />
|
||||||
|
<Tooltip
|
||||||
|
crosshairs={{
|
||||||
|
type: "y"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Geom type="line" position="x_time*y_value" size={2} />
|
||||||
|
<Geom
|
||||||
|
type="point"
|
||||||
|
position="x_time*y_value"
|
||||||
|
size={4}
|
||||||
|
shape={"circle"}
|
||||||
|
style={{
|
||||||
|
stroke: "#fff",
|
||||||
|
lineWidth: 1
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Chart>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</GridContent>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default GatewayMonitor;
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ const havePermissionAsync = new Promise(resolve => {
|
||||||
monitor,
|
monitor,
|
||||||
loading: loading.models.monitor,
|
loading: loading.models.monitor,
|
||||||
}))
|
}))
|
||||||
class Search extends PureComponent {
|
class SearchMonitor extends PureComponent {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -45,4 +45,4 @@ class Search extends PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Search;
|
export default SearchMonitor;
|
|
@ -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 (
|
||||||
|
<h1>task monitor</h1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TaskMonitor;
|
Loading…
Reference in New Issue