diff --git a/src/layouts/admin-menu.jsx b/src/layouts/admin-menu.jsx
index bc2b6aed..739eabe4 100644
--- a/src/layouts/admin-menu.jsx
+++ b/src/layouts/admin-menu.jsx
@@ -18,7 +18,7 @@ import {
DatabaseOutlined,
CreditCardOutlined,
GlobalOutlined,
- // ToolOutlined,
+ MonitorOutlined,
SettingOutlined,
HomeOutlined,
AppstoreOutlined,
@@ -587,6 +587,22 @@ const renderMenu = (t) => {
},
],
},
+ {
+ path: '/monitor-center',
+ name: t('Monitor Center'),
+ key: '/monitorCenterAdmin',
+ icon: ,
+ children: [
+ {
+ path: '/monitor-center/overview-admin',
+ name: t('Monitor Overview'),
+ key: 'monitorOverviewAdmin',
+ level: 1,
+ children: [],
+ hasBreadcrumb: true,
+ },
+ ],
+ },
{
path: '/configuration-admin',
name: t('Global Setting'),
diff --git a/src/pages/basic/routes/index.js b/src/pages/basic/routes/index.js
index 45bf8477..f11b2655 100644
--- a/src/pages/basic/routes/index.js
+++ b/src/pages/basic/routes/index.js
@@ -41,6 +41,9 @@ const Heat = lazy(() =>
const UserCenter = lazy(() =>
import(/* webpackChunkName: "user-center" */ 'pages/user-center/App')
);
+const MonitorCenter = lazy(() =>
+ import(/* webpackChunkName: "monitor-center" */ 'pages/monitor/App')
+);
const E404 = lazy(() =>
import(/* webpackChunkName: "E404" */ 'pages/base/containers/404')
);
@@ -77,6 +80,10 @@ export default [
path: `/heat`,
component: Heat,
},
+ {
+ path: `/monitor-center`,
+ component: MonitorCenter,
+ },
{
path: `/user`,
component: UserCenter,
diff --git a/src/pages/monitor/App.jsx b/src/pages/monitor/App.jsx
new file mode 100644
index 00000000..014bcad1
--- /dev/null
+++ b/src/pages/monitor/App.jsx
@@ -0,0 +1,21 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import renderRoutes from 'utils/RouterConfig';
+
+import routes from './routes';
+
+const App = (props) => renderRoutes(routes, props);
+
+export default App;
diff --git a/src/pages/monitor/containers/Overview/components/AlertInfo/components/AlertChart.jsx b/src/pages/monitor/containers/Overview/components/AlertInfo/components/AlertChart.jsx
new file mode 100644
index 00000000..be53526f
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/components/AlertInfo/components/AlertChart.jsx
@@ -0,0 +1,55 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import { Empty, Row } from 'antd';
+import { Chart, Line, Tooltip } from 'bizcharts';
+import { observer } from 'mobx-react';
+import styles from '../../../index.less';
+
+export default observer(({ data }) => {
+ return (
+
+
+ {t('Last week alarm trend')}
+ {t('time / 24h')}
+
+
+ {data.length === 0 ? : }
+
+
+ );
+});
+
+function Charts({ data }) {
+ return (
+
+
+
+
+ );
+}
diff --git a/src/pages/monitor/containers/Overview/components/AlertInfo/index.jsx b/src/pages/monitor/containers/Overview/components/AlertInfo/index.jsx
new file mode 100644
index 00000000..5132c5dd
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/components/AlertInfo/index.jsx
@@ -0,0 +1,112 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React, { useState, useEffect } from 'react';
+import { Col, Row, Spin } from 'antd';
+import styles from 'pages/monitor/containers/Overview/index.less';
+import FetchPrometheusStore from 'components/PrometheusChart/store/FetchPrometheusStore';
+import { handleResponse } from 'components/PrometheusChart/utils/dataHandler';
+import moment from 'moment';
+import AlertChart from './components/AlertChart';
+
+const STEP = 15;
+
+const Index = function () {
+ const store = new FetchPrometheusStore({
+ requestType: 'range',
+ metricKey: 'monitorOverview.alertInfo',
+ formatDataFn: (responses, typeKey, deviceKey, modifyKeys) => {
+ const ret = [];
+ responses.forEach((response, idx) => {
+ ret.push(handleResponse(response, typeKey, deviceKey, modifyKeys[idx]));
+ });
+ return ret;
+ },
+ modifyKeys: ['cpu', 'memory'],
+ });
+
+ const [isLoading, setIsLoading] = useState(true);
+ const [cpuCount, setCpuCount] = useState(0);
+ const [memCount, setMemCount] = useState(0);
+ const [weekData, setWeekData] = useState(build7DaysData());
+
+ useEffect(() => {
+ const end = moment();
+ const start = moment().startOf('day');
+ setIsLoading(true);
+ store
+ .fetchData({
+ interval: STEP,
+ currentRange: [start, end],
+ })
+ .then((d) => {
+ const [cpuData, memoryData] = d;
+ const newCpuCount = cpuData.reduce(
+ (pre, cur, idx) =>
+ idx > 0 && cur.x - cpuData[idx - 1].x > STEP ? pre + 1 : pre,
+ 0
+ );
+ const newMemoryCount = memoryData.reduce(
+ (pre, cur, idx) =>
+ idx > 0 && cur.x - memoryData[idx - 1].x > STEP ? pre + 1 : pre,
+ 0
+ );
+ setCpuCount(newCpuCount);
+ setMemCount(newMemoryCount);
+ weekData[6].count = newCpuCount + newMemoryCount;
+ setWeekData([...weekData]);
+ })
+ .finally(() => {
+ setIsLoading(false);
+ });
+ }, []);
+
+ return isLoading ? (
+
+ ) : (
+
+
+
+
+
+ {cpuCount}
+ {t('Today CPU usage > 80% alert')}
+
+
+ {memCount}
+ {t('Today Memory usage > 80% alert')}
+
+
+
+
+
+
+
+
+ );
+};
+
+function build7DaysData() {
+ const today = moment().startOf('day');
+ const ret = [];
+ for (let index = 6; index >= 0; index--) {
+ ret.push({
+ date: today.clone().subtract(index, 'day').format('MM-DD'),
+ count: 0,
+ });
+ }
+ return ret;
+}
+
+export default Index;
diff --git a/src/pages/monitor/containers/Overview/components/ClusterMonitor/ClusterCard.jsx b/src/pages/monitor/containers/Overview/components/ClusterMonitor/ClusterCard.jsx
new file mode 100644
index 00000000..53341c1d
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/components/ClusterMonitor/ClusterCard.jsx
@@ -0,0 +1,171 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import { Col, Progress, Row } from 'antd';
+import { handleResponses } from 'components/PrometheusChart/utils/dataHandler';
+import { get, merge } from 'lodash';
+import { getSuitableValue } from 'resources/monitoring';
+import { computePercentage } from 'utils/index';
+import BaseCard from 'components/PrometheusChart/BaseCard';
+import styles from '../../index.less';
+
+const ClusterCard = (props) => {
+ const { store: propStore } = props;
+ const baseConfig = {
+ span: 12,
+ constructorParams: {
+ requestType: 'current',
+ formatDataFn: handleResponses,
+ },
+ visibleHeight: 55,
+ renderContent: (store) => (
+ {store.data}
+ ),
+ };
+ const chartLists = [
+ {
+ title: t('Physical CPU Usage'),
+ span: 12,
+ constructorParams: {
+ metricKey: 'monitorOverview.physicalCPUUsage',
+ },
+ renderContent: (store) => {
+ const { data } = store;
+ const used = get(data[0], 'y', 0);
+ const total = get(data[1], 'y', 0);
+ return (
+
+
+
+
+ {computePercentage(used, total)}
+
+ %
+
+
+ {`${used} / ${total}`}
+
+
+
+ );
+ },
+ },
+ {
+ title: t('Total Ram'),
+ span: 12,
+ constructorParams: {
+ metricKey: 'monitorOverview.physicalMemoryUsage',
+ },
+ renderContent: (store) => {
+ const { data } = store;
+ const usedValue = get(data[0], 'y', 0);
+ const totalValue = get(data[1], 'y', 0);
+ const used = getSuitableValue(usedValue, 'memory');
+ const total = getSuitableValue(totalValue, 'memory');
+ return (
+
+
+
+
+ {computePercentage(usedValue, totalValue)}
+
+ %
+
+
+ {`${used} / ${total}`}
+
+
+
+ );
+ },
+ },
+ {
+ title: t('Physical Storage Usage'),
+ span: 24,
+ constructorParams: {
+ metricKey: 'monitorOverview.physicalStorageUsage',
+ },
+ renderContent: (store) => {
+ const { data } = store;
+ const usedValue = get(data[0], 'y', 0);
+ const totalValue = get(data[1], 'y', 0);
+
+ const used = getSuitableValue(usedValue, 'disk');
+ const total = getSuitableValue(totalValue, 'disk');
+ const progressPercentage = computePercentage(usedValue, totalValue);
+ return (
+
+
+
+
+ {`${t('Used')} ${used} / ${t('Total')} ${total}`}
+
+
+
+
+
+
+ );
+ },
+ },
+ ];
+ return (
+
+ {chartLists.map((chartProps) => {
+ const config = merge({}, baseConfig, chartProps);
+ const { span, ...rest } = config;
+ return (
+
+
+
+ );
+ })}
+
+ );
+};
+
+export default ClusterCard;
diff --git a/src/pages/monitor/containers/Overview/components/ClusterMonitor/ClusterChart.jsx b/src/pages/monitor/containers/Overview/components/ClusterMonitor/ClusterChart.jsx
new file mode 100644
index 00000000..b4c55bf5
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/components/ClusterMonitor/ClusterChart.jsx
@@ -0,0 +1,68 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import styles from 'pages/monitor/containers/Overview/index.less';
+import { observer } from 'mobx-react';
+import CircleChart from 'components/PrometheusChart/CircleWithRightLegend';
+import { get } from 'lodash';
+import BaseCard from 'components/PrometheusChart/BaseCard';
+
+const ClusterChart = observer((props) => {
+ const { store: propStore } = props;
+
+ const config = {
+ title: t('Compute Node status'),
+ constructorParams: {
+ requestType: 'current',
+ formatDataFn: (responses) => {
+ const status = [
+ {
+ type: 'up',
+ value: 0,
+ },
+ {
+ type: 'down',
+ value: 0,
+ },
+ ];
+ const result = get(responses[0], 'data.result', []);
+ result.forEach((sta) => {
+ const idx = sta.metric.services_state === 'up' ? 0 : 1;
+ status[idx].value += parseInt(sta.value[1], 10);
+ });
+ return status;
+ },
+ metricKey: 'monitorOverview.computeNodeStatus',
+ },
+ renderContent: (store) => (
+
+ ),
+ visibleHeight: 230,
+ };
+
+ return (
+
+ );
+});
+
+export default ClusterChart;
diff --git a/src/pages/monitor/containers/Overview/components/StorageClusterMonitor/StorageClusterCard.jsx b/src/pages/monitor/containers/Overview/components/StorageClusterMonitor/StorageClusterCard.jsx
new file mode 100644
index 00000000..43efe9ff
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/components/StorageClusterMonitor/StorageClusterCard.jsx
@@ -0,0 +1,155 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import { Col, Row } from 'antd';
+import { computePercentage } from 'utils/index';
+import {
+ cephStatusColorMap,
+ cephStatusMap,
+ getSuitableValue,
+} from 'resources/monitoring';
+import { handleResponses } from 'components/PrometheusChart/utils/dataHandler';
+import { get, merge } from 'lodash';
+import BaseCard from 'components/PrometheusChart/BaseCard';
+import styles from '../../index.less';
+
+const StorageClusterCard = (props) => {
+ const { store: propStore } = props;
+ const baseConfig = {
+ span: 12,
+ constructorParams: {
+ requestType: 'current',
+ formatDataFn: handleResponses,
+ },
+ visibleHeight: 65,
+ renderContent: (store) => (
+ {JSON.stringify(store.data)}
+ ),
+ };
+ const chartLists = [
+ {
+ title: t('Storage Cluster Status'),
+ span: 24,
+ constructorParams: {
+ metricKey: 'monitorOverview.cephHealthStatus',
+ },
+ renderContent: (store) => {
+ const data = get(store.data, 'y', 0);
+ return (
+
+ {cephStatusMap[data]}
+
+ );
+ },
+ },
+ {
+ title: t('Storage Cluster Usage'),
+ span: 12,
+ constructorParams: {
+ metricKey: 'monitorOverview.cephStorageUsage',
+ },
+ renderContent: (store) => {
+ const { data } = store;
+ const usedValue = get(data[0], 'y', 0);
+ const totalValue = get(data[1], 'y', 0);
+ const used = getSuitableValue(usedValue, 'disk');
+ const total = getSuitableValue(totalValue, 'disk');
+ return (
+
+
+
+
+ {computePercentage(usedValue, totalValue)}
+
+ %
+
+
+ {`${used} / ${total}`}
+
+
+
+ );
+ },
+ },
+ {
+ title: t('Disk allocation (GB)'),
+ span: 12,
+ constructorParams: {
+ metricKey: 'monitorOverview.cephStorageAllocate',
+ },
+ renderContent: (store) => {
+ const { data } = store;
+ const totalValue = parseFloat(get(data[1], 'y', 0).toFixed(2));
+ const usedValue = parseFloat(
+ (totalValue - get(data[0], 'y', 0)).toFixed(2)
+ );
+ return (
+
+
+
+
+ {computePercentage(usedValue, totalValue)}
+
+ %
+
+
+ {`${usedValue} GB / ${totalValue} GB`}
+
+
+
+ );
+ },
+ },
+ ];
+ return (
+
+ {chartLists.map((chartProps) => {
+ const config = merge({}, baseConfig, chartProps);
+ const { span, ...rest } = config;
+ return (
+
+
+
+ );
+ })}
+
+ );
+};
+
+export default StorageClusterCard;
diff --git a/src/pages/monitor/containers/Overview/components/StorageClusterMonitor/StorageClusterChart.jsx b/src/pages/monitor/containers/Overview/components/StorageClusterMonitor/StorageClusterChart.jsx
new file mode 100644
index 00000000..acb097f4
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/components/StorageClusterMonitor/StorageClusterChart.jsx
@@ -0,0 +1,57 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import { observer } from 'mobx-react';
+import ChartCard from 'components/PrometheusChart/ChartCard';
+import { handleResponses } from 'components/PrometheusChart/utils/dataHandler';
+import { ChartType } from 'components/PrometheusChart/utils/utils';
+
+const StorageClusterChart = observer((props) => {
+ const { store: propStore } = props;
+
+ const config = {
+ title: t('Storage Cluster IOPS'),
+ constructorParams: {
+ requestType: 'range',
+ metricKey: 'monitorOverview.cephStorageClusterIOPS',
+ formatDataFn: handleResponses,
+ modifyKeys: [t('read'), t('write')],
+ },
+ chartProps: {
+ chartType: ChartType.MULTILINE,
+ height: 250,
+ scale: {
+ y: {
+ nice: true,
+ },
+ },
+ },
+ visibleHeight: 230,
+ };
+
+ return (
+
+ );
+});
+
+export default StorageClusterChart;
diff --git a/src/pages/monitor/containers/Overview/components/Tops/TopCard.jsx b/src/pages/monitor/containers/Overview/components/Tops/TopCard.jsx
new file mode 100644
index 00000000..c0fca1e3
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/components/Tops/TopCard.jsx
@@ -0,0 +1,187 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import { Col, Progress, Row, Tabs } from 'antd';
+import { handleResponses } from 'components/PrometheusChart/utils/dataHandler';
+import { get, merge } from 'lodash';
+import BaseCard from 'components/PrometheusChart/BaseCard';
+import { Chart, Interval } from 'bizcharts';
+import { getSuitableValue } from 'resources/monitoring';
+import styles from '../../index.less';
+
+const renderTopProgress = (store) => {
+ const { data } = store;
+ return (
+
+ {data.map((d) => {
+ const percentage = get(d, 'y', 0);
+ const percentageColor = percentage > 80 ? '#FAAD14' : '#1890FF';
+ return (
+
+ {d.type}
+
+
+ );
+ })}
+
+ );
+};
+
+const renderTopColumnExtra = (store) => {
+ const { modifyKeys } = store;
+ return (
+ store.handleDeviceChange(key)}
+ >
+ {modifyKeys.map((k) => (
+
+ ))}
+
+ );
+};
+
+const renderTopColumnChart = (store, scale = { y: {} }) => {
+ const { data, modifyKeys } = store;
+ return (
+
+ d.type === (store.device || modifyKeys[0]))}
+ height={198}
+ scale={{
+ y: {
+ nice: true,
+ ...scale.y,
+ },
+ }}
+ >
+
+
+
+ );
+};
+
+const TopCard = (props) => {
+ const { store: propStore } = props;
+ const baseConfig = {
+ span: 12,
+ constructorParams: {
+ requestType: 'current',
+ formatDataFn: handleResponses,
+ },
+ visibleHeight: 200,
+ renderContent: (store) => (
+ {store.data}
+ ),
+ };
+ const chartLists = [
+ {
+ title: t('Host CPU Usage'),
+ span: 12,
+ constructorParams: {
+ metricKey: 'monitorOverview.topHostCPUUsage',
+ typeKey: 'instance',
+ },
+ renderContent: renderTopProgress,
+ },
+ {
+ title: t('Host Disk Average IOPS'),
+ span: 12,
+ constructorParams: {
+ metricKey: 'monitorOverview.topHostDiskIOPS',
+ formatDataFn: (reps, tk, dk, mk) => {
+ const data = [];
+ reps.forEach((ret, resIdx) => {
+ (ret.data.result || []).forEach((d) => {
+ data.push({
+ x: d.metric.instance,
+ y: parseFloat(get(d, 'value[1]', 0)),
+ type: mk[resIdx],
+ });
+ });
+ });
+ return data;
+ },
+ modifyKeys: [t('read'), t('write')],
+ },
+ extra: renderTopColumnExtra,
+ renderContent: renderTopColumnChart,
+ },
+ {
+ title: t('Host Memory Usage'),
+ span: 12,
+ constructorParams: {
+ metricKey: 'monitorOverview.topHostMemoryUsage',
+ typeKey: 'instance',
+ },
+ renderContent: renderTopProgress,
+ },
+ {
+ title: t('Host Average Network IO'),
+ span: 12,
+ constructorParams: {
+ metricKey: 'monitorOverview.topHostInterface',
+ formatDataFn: (reps, tk, dk, mk) => {
+ const data = [];
+ reps.forEach((ret, resIdx) => {
+ (ret.data.result || []).forEach((d) => {
+ data.push({
+ x: d.metric.instance,
+ y: parseFloat(get(d, 'value[1]', 0)),
+ type: mk[resIdx],
+ });
+ });
+ });
+ return data;
+ },
+ modifyKeys: [t('receive'), t('transmit')],
+ },
+ extra: renderTopColumnExtra,
+ renderContent: (store) =>
+ renderTopColumnChart(store, {
+ y: {
+ formatter: (d) => getSuitableValue(d, 'traffic', 0),
+ },
+ }),
+ },
+ ];
+ return (
+
+ {chartLists.map((chartProps) => {
+ const config = merge({}, baseConfig, chartProps);
+ const { span, title, ...rest } = config;
+ return (
+
+
+
+ );
+ })}
+
+ );
+};
+
+export default TopCard;
diff --git a/src/pages/monitor/containers/Overview/index.jsx b/src/pages/monitor/containers/Overview/index.jsx
new file mode 100644
index 00000000..5e252b29
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/index.jsx
@@ -0,0 +1,72 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import BaseContent from 'components/PrometheusChart/component/BaseContent';
+import { Col, Row } from 'antd';
+import styles from './index.less';
+import AlertInfo from './components/AlertInfo';
+import ClusterCard from './components/ClusterMonitor/ClusterCard';
+import ClusterChart from './components/ClusterMonitor/ClusterChart';
+import TopCard from './components/Tops/TopCard';
+import StorageClusterCard from './components/StorageClusterMonitor/StorageClusterCard';
+import StorageClusterChart from './components/StorageClusterMonitor/StorageClusterChart';
+
+const BaseContentConfig = {
+ renderNodeSelect: false,
+ renderTimeRangeSelect: false,
+};
+
+const Index = () => {
+ return (
+ (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+ />
+ );
+};
+
+export default Index;
diff --git a/src/pages/monitor/containers/Overview/index.less b/src/pages/monitor/containers/Overview/index.less
new file mode 100644
index 00000000..9988098c
--- /dev/null
+++ b/src/pages/monitor/containers/Overview/index.less
@@ -0,0 +1,126 @@
+.container {
+ .card {
+ padding: 16px;
+ background-color: #ffffff;
+ box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.05),
+ 0px 0px 10px 0px rgba(0, 0, 0, 0.05);
+ color: #000000;
+ height: 100%;
+
+ .tabs {
+ :global {
+ .ant-tabs-tab {
+ margin-right: 20px;
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-tabs-nav::before {
+ border-bottom: none;
+ }
+ }
+ }
+ }
+
+ .alertCardLine {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ .number {
+ font-size: 36px;
+ color: rgb(232, 104, 74);
+ }
+ }
+
+ .alertCardTitle {
+ font-size: 14px;
+ font-weight: 400;
+ color: #000000;
+ }
+
+ .alertInfo {
+ margin-top: 6px;
+
+ .alertNumber {
+ font-size: 40px;
+ font-weight: 600;
+ }
+
+ .alertLevel {
+ font-size: 16px;
+ font-weight: 400;
+ color: rgba(0, 0, 0, 0.65);
+ margin-top: 12px;
+ }
+ }
+
+ .alertCardBottom {
+ padding: 0 26px;
+
+ .buttonTitle {
+ font-size: 12px;
+ font-weight: 400;
+ color: #000000;
+ margin-bottom: 15px;
+ height: 20px;
+ line-height: 20px;
+ }
+
+ .alertLineInfo {
+ font-size: 12px;
+ font-weight: 400;
+ height: 100%;
+ color: rgba(0, 0, 0, 0.65);
+ }
+ }
+}
+
+.outer {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ font-size: 14px;
+
+ .inner {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ left: 0;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ }
+
+ .inner::-webkit-scrollbar {
+ display: none;
+ }
+}
+
+.flexColumnAround {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.topContent {
+ font-size: 24px;
+ font-weight: 500;
+ height: 100px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.tabs {
+ :global {
+ .ant-tabs-tab {
+ margin-right: 20px;
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-tabs-nav::before {
+ border-bottom: none;
+ }
+ }
+}
diff --git a/src/pages/monitor/routes/index.js b/src/pages/monitor/routes/index.js
new file mode 100644
index 00000000..f83d4b74
--- /dev/null
+++ b/src/pages/monitor/routes/index.js
@@ -0,0 +1,29 @@
+// Copyright 2021 99cloud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import BaseLayout from 'layouts/Basic';
+import E404 from 'pages/base/containers/404';
+import Overview from '../containers/Overview';
+
+const PATH = '/monitor-center';
+export default [
+ {
+ path: PATH,
+ component: BaseLayout,
+ routes: [
+ { path: `${PATH}/overview-admin`, component: Overview, exact: true },
+ { path: '*', component: E404 },
+ ],
+ },
+];