generatePorts = generateRule.get(tempIP);
86 | if (generatePorts == null) {
87 | generatePorts = new HashSet<>();
88 | }
89 | generatePorts.add(tempPort);
90 | generateRule.put(tempIP, generatePorts);
91 | staticsResult.put(tempIP, staticsResult.get(tempIP) + 1);
92 | }
93 | }
94 | }
95 | }
96 | return generateRule;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/RCT-Dashboard/.gitignore:
--------------------------------------------------------------------------------
1 | /db/
2 |
--------------------------------------------------------------------------------
/RCT-Dashboard/db/data.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/db/data.db
--------------------------------------------------------------------------------
/RCT-Dashboard/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | #####################
2 | #version: RCT 1.0
3 | #describe rct-dashboard
4 | #truman create
5 | #
6 | FROM openjdk:8u181-jdk-alpine3.8
7 | LABEL author="Truman.p.Du"
8 | COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas
9 |
10 | ENV BASE_DIR /opt/app/rct/rct-dashboard
11 | WORKDIR ${BASE_DIR}
12 | ENV RCT_NAME RCT-Dashboard
13 | ENV VERSION 2.1.1
14 | RUN apk upgrade --update && \
15 | apk add --update curl bash
16 | RUN cd ${BASE_DIR} && \
17 | curl -fsSL -o ${RCT_NAME}-${VERSION}-release.tar.gz https://github.com/xaecbd/RCT/releases/download/v${VERSION}/${RCT_NAME}-${VERSION}-release.tar.gz && \
18 | tar xvf ${RCT_NAME}-${VERSION}-release.tar.gz && \
19 | rm -rf ${RCT_NAME}-${VERSION}-release.tar.gz
20 | ADD start.sh ${BASE_DIR}
21 | CMD ["sh","start.sh"]
22 |
--------------------------------------------------------------------------------
/RCT-Dashboard/docker/start.sh:
--------------------------------------------------------------------------------
1 | appName=`ls |grep jar|grep RCT`
2 | echo start to run $appName
3 |
4 | if [ -n "$JAVA_OPTIONS" ];then
5 | java $JAVA_OPTIONS -jar $appName $option
6 | else
7 | java -jar $appName $option
8 | fi
--------------------------------------------------------------------------------
/RCT-Dashboard/package.xml:
--------------------------------------------------------------------------------
1 |
2 | release
3 |
4 | tar.gz
5 |
6 | false
7 |
8 |
9 |
10 | ${basedir}/db
11 | db
12 |
13 | *.db
14 |
15 |
16 |
17 |
18 | ${project.basedir}/src/main/resources
19 | config
20 |
21 | application.properties
22 |
23 |
24 |
25 |
26 |
27 | ${project.build.directory}
28 |
29 |
30 | *.jar
31 |
32 |
33 |
34 |
35 | ${basedir}/template
36 | template
37 |
38 | *.xlsx
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/.eslintignore:
--------------------------------------------------------------------------------
1 | # 忽略目录
2 | build/
3 | tests/
4 | demo/
5 |
6 | # node 覆盖率文件
7 | coverage/
8 |
9 | # 忽略文件
10 | **/*-min.js
11 | **/*.min.js
12 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "parser": "babel-eslint",
4 | "extends": "eslint-config-airbnb",
5 | "parserOptions": {
6 | "ecmaVersion": 6,
7 | "ecmaFeatures": {
8 | "jsx": true,
9 | "experimentalObjectRestSpread": true
10 | }
11 | },
12 | "env": {
13 | "browser": true,
14 | "mocha": true
15 | },
16 | "plugins": ["react", "babel"],
17 | "rules": {
18 | "react/prefer-stateless-function": 0,
19 | "no-console": 0,
20 | "no-use-before-define": 0,
21 | "jsx-a11y/label-has-for": 0,
22 | "jsx-a11y/no-static-element-interactions": 0,
23 | "jsx-a11y/anchor-has-content": 0,
24 | "jsx-a11y/click-events-have-key-events": 0,
25 | "jsx-a11y/anchor-is-valid": 0,
26 | "react/no-array-index-key": 0,
27 | "func-names": 0,
28 | "arrow-body-style": 0,
29 | "react/sort-comp": 0,
30 | "react/prop-types": 0,
31 | "react/jsx-first-prop-new-line": 0,
32 | "react/jsx-filename-extension": [
33 | 1,
34 | {
35 | "extensions": [".js", ".jsx"]
36 | }
37 | ],
38 | "import/extensions": 0,
39 | "import/no-unresolved": 0,
40 | "import/no-extraneous-dependencies": 0,
41 | "prefer-destructuring": 0,
42 | "no-param-reassign": 0,
43 | "no-return-assign": 0,
44 | "max-len": 0,
45 | "consistent-return": 0,
46 | "no-redeclare": 0,
47 | "react/require-extension": 0,
48 | "react/no-danger": 0,
49 | "comma-dangle": ["error", "always-multiline"],
50 | "function-paren-newline": 0,
51 | "object-curly-newline": 0,
52 | "no-restricted-globals": 0,
53 | "global-require": 0,
54 | "no-mixed-operators": 0,
55 | "react/forbid-prop-types": 0
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # production
7 | /build
8 | /dist
9 |
10 | # misc
11 | .idea/
12 | .happypack
13 | .DS_Store
14 |
15 | npm-debug.log*
16 | yarn-debug.log*
17 | yarn-error.log*
18 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/.webpackrc.js:
--------------------------------------------------------------------------------
1 | const {
2 | resolve
3 | } = require('path');
4 |
5 | module.exports = {
6 | output: {
7 | path: resolve('../resources/static'),
8 | },
9 | module: {
10 | rules: [ {
11 | test: /\.(png|jpg|gif)$/,
12 | use: [
13 | {
14 | loader: 'file-loader',
15 | options: {
16 | name: '[name].[ext]',
17 | outputPath: 'public/images/'
18 | }
19 | }
20 | ]
21 | }]
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/README.md:
--------------------------------------------------------------------------------
1 | # RCT
2 |
3 | RCT (Redis 内存分析工具)
4 |
5 | ## 使用
6 |
7 | - 启动调试服务: `npm start`
8 | - 构建: `npm run build`
9 |
10 | ## 目录结构
11 |
12 | - react-router @4.x 默认采用 hashHistory 的单页应用
13 | - 入口文件: `src/index.js`
14 | - 导航配置: `src/menuConfig.js`
15 | - 路由配置: `src/routerConfig.js`
16 | - 路由入口: `src/router.jsx`
17 | - 布局文件: `src/layouts`
18 | - 通用组件: `src/components`
19 | - 页面文件: `src/pages`
20 |
21 | ## 配色
22 |
23 | - 主色:#5e83fb
24 | - 功能主色:#5e83fb、#f7da47、#58ca9a、#ee706d
25 | - 字体颜色:#333、#666
26 |
27 | ## 效果图
28 |
29 | 
30 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@icedesign/builder-platfrom-scaffold",
3 | "version": "1.0.0",
4 | "description": "RCT (Redis 内存分析工具)",
5 | "files": [
6 | "src/",
7 | "build/",
8 | "public/",
9 | "tests/",
10 | "_gitignore",
11 | ".editorconfig",
12 | ".eslintignore",
13 | ".eslintrc"
14 | ],
15 | "keywords": [
16 | "ice-scaffold"
17 | ],
18 | "scripts": {
19 | "start": "ice dev",
20 | "build": "ice build",
21 | "lint": "eslint . --ext '.js,.jsx' --fix"
22 | },
23 | "publishConfig": {
24 | "registry": "http://registry.npmjs.com",
25 | "access": "public"
26 | },
27 | "dependencies": {
28 | "@icedesign/base": "^0.2.0",
29 | "@icedesign/container": "^0.1.4",
30 | "@icedesign/dynamic-icon": "^0.1.6",
31 | "@icedesign/form-binder": "^0.1.4",
32 | "@icedesign/img": "^0.1.1",
33 | "@icedesign/layout": "^0.1.2",
34 | "@icedesign/menu": "^0.1.1",
35 | "@icedesign/skin": "^0.1.0",
36 | "axios": "^0.18.0"
37 | },
38 | "devDependencies": {
39 | "babel-eslint": "^8.0.3",
40 | "classnames": "^2.2.5",
41 | "eslint": "^4.13.1",
42 | "eslint-config-airbnb": "^16.1.0",
43 | "eslint-plugin-babel": "^4.1.1",
44 | "eslint-plugin-import": "^2.8.0",
45 | "eslint-plugin-jsx-a11y": "^6.0.3",
46 | "eslint-plugin-react": "^7.5.1",
47 | "file-loader": "^3.0.1",
48 | "foundation-symbol": "^0.1.3",
49 | "ice-scripts": "^1.8.7",
50 | "prop-types": "^15.5.8",
51 | "react": "^16.4.1",
52 | "react-dom": "^16.4.1",
53 | "react-highcharts": "^16.0.2",
54 | "react-router-dom": "^4.3.1"
55 | },
56 | "buildConfig": {
57 | "theme": "@icedesign/skin",
58 | "entry": "src/index.js",
59 | "localization": false,
60 | "output": {
61 | "publicPath": "./"
62 | }
63 | },
64 | "themeConfig": {
65 | "primaryColor": "#5e83fb"
66 | },
67 | "scaffoldConfig": {
68 | "builder": "ice-scripts",
69 | "name": "ice-builder-platform",
70 | "title": "云构建平台",
71 | "categories": [
72 | "行业领域"
73 | ],
74 | "screenshot": "https://img.alicdn.com/tfs/TB16CTXx7voK1RjSZFNXXcxMVXa-2872-1580.png"
75 | },
76 | "title": "frontend"
77 | }
78 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/public/favicon.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/images/chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/public/images/chart.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/images/client.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/public/images/client.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/images/fail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/public/images/fail.jpg
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/images/list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/public/images/list.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/images/statistical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/public/images/statistical.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/images/success.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/public/images/success.jpg
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/images/time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/public/images/time.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | RCT
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/axios.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | // 使用由库提供的配置的默认值来创建实例 此时超时配置的默认值是 `0`
3 |
4 | const axiosInstance = axios.create();
5 | // 覆写库的超时默认值 现在,在超时前,所有请求都会等待 2分钟
6 | axiosInstance.defaults.timeout = 120000;
7 |
8 | //axiosInstance.defaults.baseURL = 'http://localhost:8080';
9 |
10 | export default axiosInstance;
11 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/CustomBreadcrumb/CustomBreadcrumb.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types';
3 | import { Breadcrumb } from '@icedesign/base';
4 | import IceContainer from '@icedesign/container';
5 |
6 | export default class CustomBreadcrumb extends Component {
7 | static displayName = 'CustomBreadcrumb';
8 |
9 | static defaultProps = {
10 | dataSource: [],
11 | };
12 |
13 | static propTypes = {
14 | dataSource: PropTypes.array,
15 | };
16 |
17 | render() {
18 | const { dataSource } = this.props;
19 | return (
20 |
21 |
22 | {dataSource.map((item, index) => {
23 | return (
24 |
25 | {item.text}
26 |
27 | );
28 | })}
29 |
30 |
31 | );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/CustomBreadcrumb/index.js:
--------------------------------------------------------------------------------
1 | import CustomBreadcrumb from './CustomBreadcrumb';
2 |
3 | export default CustomBreadcrumb;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/CustomTable/CustomTable.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Table, Pagination } from '@icedesign/base';
3 | import PropTypes from 'prop-types';
4 | import './CustomTable.scss';
5 |
6 | export default class Home extends Component {
7 | static displayName = 'Home';
8 |
9 | static defaultProps = {
10 | isLoading: false,
11 | columns: [],
12 | dataSource: [],
13 | };
14 |
15 | static propTypes = {
16 | isLoading: PropTypes.bool,
17 | columns: PropTypes.array,
18 | dataSource: PropTypes.array,
19 | };
20 |
21 | constructor(props) {
22 | super(props);
23 | this.state = {
24 | current: 1,
25 | };
26 | }
27 |
28 | handlePagination = (current) => {
29 | this.setState(
30 | {
31 | current,
32 | },
33 | () => {
34 | this.props.onChange();
35 | }
36 | );
37 | };
38 |
39 | render() {
40 | const { isLoading, dataSource, columns } = this.props;
41 |
42 | return (
43 |
44 |
50 | {columns.map((item) => {
51 | return (
52 | value)}
58 | />
59 | );
60 | })}
61 |
62 |
67 |
68 | );
69 | }
70 | }
71 |
72 | const styles = {
73 | pagination: {
74 | margin: '20px 0',
75 | textAlign: 'center',
76 | },
77 | };
78 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/CustomTable/CustomTable.scss:
--------------------------------------------------------------------------------
1 | .custom-table {
2 | .next-table-header {
3 | table th {
4 | background: #f4f4f4;
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/CustomTable/index.js:
--------------------------------------------------------------------------------
1 | import CustomTable from './CustomTable';
2 |
3 | export default CustomTable;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/NotFound/NotFound.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Link } from 'react-router-dom';
3 | import IceContainer from '@icedesign/container';
4 | import './NotFound.scss';
5 |
6 | export default class NotFound extends Component {
7 | static displayName = 'NotFound';
8 |
9 | render() {
10 | return (
11 |
12 |
13 |
14 |
})
20 |
21 |
22 | 抱歉,你访问的页面不存在
23 |
24 |
25 | 您要找的页面没有找到,请返回首页继续浏览
26 |
27 |
28 |
29 |
30 |
31 | );
32 | }
33 | }
34 |
35 | const styles = {
36 | exceptionContent: {
37 | display: 'flex',
38 | justifyContent: 'center',
39 | alignItems: 'center',
40 | },
41 | title: {
42 | color: '#333',
43 | },
44 | description: {
45 | color: '#666',
46 | },
47 | };
48 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/NotFound/NotFound.scss:
--------------------------------------------------------------------------------
1 | @media screen and (max-width: 720px) {
2 | .exception-content {
3 | min-height: 200px;
4 | .imgException {
5 | max-width: 100px;
6 | margin-right: 10px;
7 | }
8 | .title {
9 | font-size: 14px;
10 | margin: 10px 0;
11 | }
12 | .description {
13 | font-size: 12px;
14 | }
15 | }
16 | }
17 |
18 | @media screen and (min-width: 721px) and (max-width: 1199px) {
19 | .exception-content {
20 | min-height: 300px;
21 | .imgException {
22 | max-width: 180px;
23 | margin-right: 30px;
24 | }
25 | .title {
26 | font-size: 20px;
27 | margin: 10px 0;
28 | }
29 | .description {
30 | font-size: 14px;
31 | }
32 | }
33 | }
34 |
35 | @media screen and (min-width: 1200px) {
36 | .exception-content {
37 | min-height: 500px;
38 | .imgException {
39 | max-width: 260px;
40 | margin-right: 50px;
41 | }
42 | .title {
43 | font-size: 24px;
44 | margin: 20px 0;
45 | }
46 | .description {
47 | font-size: 16px;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/NotFound/images/notFound.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/src/components/NotFound/images/notFound.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/components/NotFound/index.js:
--------------------------------------------------------------------------------
1 | import NotFound from './NotFound';
2 |
3 | export default NotFound;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/index.js:
--------------------------------------------------------------------------------
1 | import ReactDOM from 'react-dom';
2 |
3 | // 载入默认全局样式 normalize 、.clearfix 和一些 mixin 方法等
4 | import '@icedesign/base/reset.scss';
5 | import '../public/images/chart.png';
6 | import '../public/images/client.png';
7 | import '../public/images/fail.jpg';
8 | import '../public/images/statistical.png';
9 | import '../public/images/success.jpg';
10 | import '../public/images/time.png';
11 | import '../public/images/list.png';
12 |
13 | import router from './router';
14 |
15 | const ICE_CONTAINER = document.getElementById('ice-container');
16 |
17 | if (!ICE_CONTAINER) {
18 | throw new Error('当前页面不存在 节点.');
19 | }
20 |
21 | ReactDOM.render(router, ICE_CONTAINER);
22 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/MainRoutes.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Switch, Route, Redirect } from 'react-router-dom';
3 | import NotFound from '../../components/NotFound';
4 | import routerData from '../../routerConfig';
5 |
6 | class MainRoutes extends Component {
7 | /**
8 | * 渲染路由组件
9 | */
10 | renderNormalRoute = (item, index) => {
11 | if (sessionStorage.getItem('user')) {
12 | return item.component ? (
13 |
19 | ) : null;
20 | }
21 | return ;
22 | };
23 |
24 | render() {
25 | return (
26 |
27 | {/* 渲染路由表 */}
28 | {routerData.map(this.renderNormalRoute)}
29 |
30 | {/* 未匹配到的路由重定向到 NotFound */}
31 |
32 |
33 | );
34 | }
35 | }
36 |
37 | export default MainRoutes;
38 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Footer/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Logo from '../Logo';
3 |
4 | export default () => {
5 | return (
6 |
22 |
23 |
24 |
25 |
33 | EC-BigData Team
34 |
35 | © 2019 版权所有
36 |
37 |
38 | );
39 | };
40 |
41 |
42 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Footer/index.js:
--------------------------------------------------------------------------------
1 | export default from './Footer';
2 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Header/Header.scss:
--------------------------------------------------------------------------------
1 | .header-container {
2 | position: fixed;
3 | left: 0;
4 | right: 0;
5 | z-index: 999;
6 | background: #fff;
7 | min-width: 1280px;
8 | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
9 | .header-content {
10 | width: 100%;
11 | height: 62px;
12 | padding: 0 20px;
13 | display: flex;
14 | align-items: center;
15 | justify-content: space-between;
16 | }
17 |
18 | .header-navbar {
19 | display: flex;
20 | flex-direction: row;
21 | .ice-menu {
22 | background: transparent;
23 | .ice-menu-submenu-title,
24 | .ice-menu-item {
25 | font-size: 14px;
26 | a:hover {
27 | color: #5e83fb;
28 | }
29 | }
30 | }
31 | }
32 |
33 | .user-avatar {
34 | margin-right: 12px;
35 | border-radius: 4px;
36 | }
37 |
38 | .user-department {
39 | font-size: 12px;
40 | color: #333;
41 | }
42 |
43 | .ice-design-header-userpannel {
44 | margin-left: 20px;
45 | cursor: pointer;
46 | .user-profile {
47 | display: inline-block;
48 | text-align: center;
49 | margin-bottom: 2px;
50 | color: #333;
51 | }
52 | .icon-down {
53 | margin-left: 2px;
54 | color: #333;
55 | }
56 | }
57 | }
58 |
59 | .user-profile-menu {
60 | width: 130px;
61 | border-radius: 6px;
62 | padding: 0 16px;
63 | .user-profile-menu-item {
64 | height: 40px;
65 | line-height: 40px;
66 | font-size: 12px;
67 | color: #666;
68 | cursor: pointer;
69 | a:hover {
70 | color: #2077ff;
71 | }
72 | i {
73 | margin-right: 5px;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Header/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Header/images/avatar.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Header/index.js:
--------------------------------------------------------------------------------
1 | import Header from './Header';
2 |
3 | export default Header;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Logo/Logo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | export default class Logo extends Component {
4 | render() {
5 | return (
6 |
11 | );
12 | }
13 | }
14 |
15 | const styles = {
16 | container: {
17 | display: 'flex',
18 | alignItems: 'center',
19 | marginRight: '20px',
20 | },
21 | logoText: {
22 | display: 'block',
23 | maxWidth: '120px',
24 | overflow: 'hidden',
25 | textOverflow: 'ellipsis',
26 | whiteSpace: 'nowrap',
27 | marginLeft: '10px',
28 | fontSize: '22px',
29 | color: '#333',
30 | fontWeight: 'bold',
31 | },
32 | };
33 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Logo/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Logo/images/logo.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/components/Logo/index.js:
--------------------------------------------------------------------------------
1 | export default from './Logo';
2 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Layout from '@icedesign/layout';
3 | import Header from './components/Header';
4 | import Footer from './components/Footer';
5 | import MainRoutes from './MainRoutes';
6 | import './index.scss';
7 |
8 | export default class BasicLayout extends Component {
9 | render() {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
24 | const styles = {
25 | mainContent: {
26 | marginTop: '82px',
27 | padding: '0 20px',
28 | paddingBottom: '50px',
29 | },
30 | };
31 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/BasicLayout/index.scss:
--------------------------------------------------------------------------------
1 | // Global RESET
2 | .ice-layout {
3 | &.basic-layout {
4 | background: #f7f7f7;
5 | min-width: 1280px;
6 | min-height: 100vh;
7 | .next-btn {
8 | border-radius: 4px;
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/MainRoutes.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Switch, Route, Redirect } from 'react-router-dom';
3 | import NotFound from '../../components/NotFound';
4 | import routerData from '../../routerConfig';
5 |
6 | class MainRoutes extends Component {
7 | /**
8 | * 渲染路由组件
9 | */
10 | renderNormalRoute = (item, index) => {
11 | if (sessionStorage.getItem('user')) {
12 | return item.component ? (
13 |
19 | ) : null;
20 | }
21 | return ;
22 | };
23 |
24 | render() {
25 | return (
26 |
27 | {/* 渲染路由表 */}
28 | {routerData.map(this.renderNormalRoute)}
29 |
30 | {/* 根路由默认重定向到 /dashboard */}
31 |
32 |
33 | {/* 未匹配到的路由重定向到 NotFound */}
34 |
35 |
36 | );
37 | }
38 | }
39 |
40 | export default MainRoutes;
41 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Footer/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Logo from '../Logo';
3 |
4 | export default () => {
5 | return (
6 |
20 |
21 |
22 |
23 |
31 | EC-BigData Team
32 |
33 | © 2019 版权所有
34 |
35 |
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Footer/index.js:
--------------------------------------------------------------------------------
1 | export default from './Footer';
2 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Header/Header.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Link, withRouter } from 'react-router-dom';
3 | import { Balloon, Icon } from '@icedesign/base';
4 | import FoundationSymbol from 'foundation-symbol';
5 | import IceImg from '@icedesign/img';
6 | import Logo from '../Logo';
7 | import './Header.scss';
8 |
9 | const data = () => {
10 | if (JSON.parse(sessionStorage.getItem('user'))) {
11 | return JSON.parse(sessionStorage.getItem('user')).userName;
12 | }
13 | };
14 |
15 | @withRouter
16 | export default class Header extends Component {
17 | static propTypes = {};
18 |
19 | static defaultProps = {};
20 |
21 | constructor(props) {
22 | super(props);
23 | this.state = {};
24 | }
25 | backup = () =>{
26 | sessionStorage.clear();
27 | }
28 |
29 | render() {
30 | const { location = {} } = this.props;
31 | const { pathname } = location;
32 | return (
33 |
34 |
35 |
36 |
37 |
38 |
39 |
49 |
55 |
56 |
57 | {data()}
58 |
59 |
60 |
65 |
66 | }
67 | closable={false}
68 | className="user-profile-menu"
69 | >
70 |
71 | - {this.backup(e)}}>
72 |
73 |
74 | 退出
75 |
76 |
77 |
78 |
79 |
80 |
81 | );
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Header/Header.scss:
--------------------------------------------------------------------------------
1 | .header-container {
2 | position: fixed;
3 | left: 0;
4 | right: 0;
5 | z-index: 999;
6 | background: #fff;
7 | min-width: 1280px;
8 | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
9 | .header-content {
10 | width: 100%;
11 | height: 62px;
12 | padding: 0 20px;
13 | display: flex;
14 | align-items: center;
15 | justify-content: space-between;
16 | }
17 |
18 | .header-navbar {
19 | display: flex;
20 | flex-direction: row;
21 | .ice-menu {
22 | background: transparent;
23 | .ice-menu-submenu-title,
24 | .ice-menu-item {
25 | font-size: 14px;
26 | a:hover {
27 | color: #5e83fb;
28 | }
29 | }
30 | }
31 | }
32 |
33 | .user-avatar {
34 | margin-right: 12px;
35 | border-radius: 4px;
36 | }
37 |
38 | .user-department {
39 | font-size: 12px;
40 | color: #333;
41 | }
42 |
43 | .ice-design-header-userpannel {
44 | margin-left: 20px;
45 | cursor: pointer;
46 | .user-profile {
47 | display: inline-block;
48 | text-align: center;
49 | margin-bottom: 2px;
50 | color: #333;
51 | }
52 | .icon-down {
53 | margin-left: 2px;
54 | color: #333;
55 | }
56 | }
57 | }
58 |
59 | .user-profile-menu {
60 | width: 130px;
61 | border-radius: 6px;
62 | padding: 0 16px;
63 | .user-profile-menu-item {
64 | height: 40px;
65 | line-height: 40px;
66 | font-size: 12px;
67 | color: #666;
68 | cursor: pointer;
69 | a:hover {
70 | color: #2077ff;
71 | }
72 | i {
73 | margin-right: 5px;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Header/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Header/images/avatar.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Header/index.js:
--------------------------------------------------------------------------------
1 | import Header from './Header';
2 |
3 | export default Header;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Logo/Logo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | export default class Logo extends Component {
4 | render() {
5 | return (
6 |
11 | );
12 | }
13 | }
14 |
15 | const styles = {
16 | container: {
17 | display: 'flex',
18 | alignItems: 'center',
19 | marginRight: '20px',
20 | },
21 | logoText: {
22 | display: 'block',
23 | maxWidth: '120px',
24 | overflow: 'hidden',
25 | textOverflow: 'ellipsis',
26 | whiteSpace: 'nowrap',
27 | marginLeft: '10px',
28 | fontSize: '22px',
29 | color: '#333',
30 | fontWeight: 'bold',
31 | },
32 | };
33 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Logo/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xaecbd/RCT/19e97c4c2c33e0af50712fedd8c1c933e7b8044d/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Logo/images/logo.png
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/components/Logo/index.js:
--------------------------------------------------------------------------------
1 | export default from './Logo';
2 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Layout from '@icedesign/layout';
3 | import Header from './components/Header';
4 | import Footer from './components/Footer';
5 | import MainRoutes from './MainRoutes';
6 | import './index.scss';
7 |
8 | export default class BasicLayout extends Component {
9 | render() {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 | }
21 |
22 | const styles = {
23 | mainContent: {
24 | marginTop: '82px',
25 | padding: '0 20px',
26 | },
27 | };
28 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/DashLayout/index.scss:
--------------------------------------------------------------------------------
1 | // Global RESET
2 | .ice-layout {
3 | &.basic-layout {
4 | background: #f7f7f7;
5 | min-width: 1280px;
6 | min-height: 100vh;
7 | .next-btn {
8 | border-radius: 4px;
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/UserLayout/components/Footer/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default () => {
4 | return (
5 |
6 |
EC-BigData Team © 2019 版权所有
7 |
8 | );
9 | };
10 |
11 | const styles = {
12 | footer: {
13 | display: 'flex',
14 | flexDirection: 'column',
15 | alignItems: 'center',
16 | justifyContent: 'center',
17 | position: 'fixed',
18 | left: '0',
19 | right: '0',
20 | bottom: '20px',
21 | },
22 | links: {
23 | marginBottom: '8px',
24 | },
25 | link: {
26 | fontSize: '13px',
27 | marginRight: '40px',
28 | color: '#fff',
29 | },
30 | copyright: {
31 | fontSize: '13px',
32 | color: '#fff',
33 | lineHeight: 1.5,
34 | textAlign: 'right',
35 | },
36 | };
37 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/UserLayout/components/Header/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Icon } from '@icedesign/base';
3 | import { Link } from 'react-router-dom';
4 | import './index.scss';
5 |
6 | export default () => {
7 | return (
8 |
9 |
10 | LOGO
11 |
12 |
43 |
44 | );
45 | };
46 |
47 | const styles = {
48 | container: {
49 | height: '60px',
50 | borderBottom: '1px solid rgba(255, 255, 255, 0.3)',
51 | display: 'flex',
52 | justifyContent: 'space-between',
53 | },
54 | logoLink: {
55 | display: 'flex',
56 | alignItems: 'center',
57 | fontSize: '24px',
58 | fontWeight: 'bold',
59 | paddingLeft: '20px',
60 | color: '#fff',
61 | },
62 | navs: {
63 | display: 'flex',
64 | },
65 | navMenu: {
66 | position: 'relative',
67 | },
68 | navLink: {
69 | display: 'block',
70 | height: '60px',
71 | lineHeight: '60px',
72 | padding: '0 20px',
73 | fontSize: '15px',
74 | color: '#fff',
75 | textDecoration: 'none',
76 | },
77 | NavIconLink: {
78 | padding: '0 30px',
79 | },
80 | subNavs: {
81 | position: 'absolute',
82 | left: '0',
83 | width: '140px',
84 | background: '#272B2F',
85 | },
86 | subNavMenu: {
87 | height: '38px',
88 | lineHeight: '38px',
89 | },
90 | subNavLink: {
91 | paddingLeft: '12px',
92 | display: 'block',
93 | color: '#fff',
94 | fontSize: '14px',
95 | },
96 | internationalImg: {
97 | width: '16px',
98 | height: '16px',
99 | position: 'absolute',
100 | left: '10px',
101 | top: '22px',
102 | },
103 | };
104 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/UserLayout/components/Header/index.scss:
--------------------------------------------------------------------------------
1 | .nav-menu {
2 | .arrow-up-icon,
3 | .arrow-down-icon {
4 | position: absolute;
5 | right: 15px;
6 | top: 0;
7 | z-index: 1;
8 | transition: 0.3s ease;
9 | }
10 | .sub-navs,
11 | .arrow-up-icon {
12 | display: none;
13 | }
14 | &:hover {
15 | background: #272b2f;
16 | .sub-navs,
17 | .arrow-up-icon {
18 | display: block;
19 | }
20 | .arrow-down-icon {
21 | display: none;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/UserLayout/components/Intro/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const LoginIntro = () => {
4 | return (
5 |
10 | );
11 | };
12 |
13 | const styles = {
14 | container: {
15 | display: 'flex',
16 | flexDirection: 'column',
17 | alignItems: 'center',
18 | justifyContent: 'center',
19 | position: 'relative',
20 | },
21 | content: {
22 | width: '350px',
23 | color: '#fff',
24 | },
25 | title: {
26 | marginBottom: '20px',
27 | fontWeight: '700',
28 | fontSize: '48px',
29 | lineHeight: '1.5',
30 | },
31 | description: {
32 | margin: '0',
33 | fontSize: '16px',
34 | fontWeight: 'bold',
35 | color: '#fff',
36 | letterSpacing: '0.45px',
37 | lineHeight: '40px',
38 | },
39 | };
40 |
41 | export default LoginIntro;
42 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/layouts/UserLayout/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Switch, Route, Redirect } from 'react-router-dom';
3 | import { Grid } from '@icedesign/base';
4 | import Footer from './components/Footer';
5 | import Intro from './components/Intro';
6 | import routerData from '../../routerConfig';
7 |
8 | const { Row, Col } = Grid;
9 |
10 | export default class UserLayout extends Component {
11 | render() {
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | {routerData.map((item, index) => {
23 | return item.component ? (
24 |
30 | ) : null;
31 | })}
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | );
41 | }
42 | }
43 |
44 | const styles = {
45 | container: {
46 | position: 'relative',
47 | width: '100wh',
48 | minWidth: '1200px',
49 | height: '100vh',
50 | backgroundImage:
51 | 'url(https://img.alicdn.com/tfs/TB1sfq4x7voK1RjSZFNXXcxMVXa-1350-900.jpg)',
52 | backgroundSize: 'cover',
53 | display: 'flex',
54 | flexDirection: 'column',
55 | // zIndex: '9',
56 | },
57 | mask: {
58 | position: 'absolute',
59 | left: '0',
60 | right: '0',
61 | top: '0',
62 | bottom: '0',
63 | background: '#000',
64 | opacity: '0.5',
65 | zIndex: '1',
66 | },
67 | row: {
68 | zIndex: '9',
69 | display: 'flex',
70 | alignItems: 'center',
71 | justifyContent: 'center',
72 | flex: '1',
73 | },
74 | form: {
75 | display: 'flex',
76 | alignItems: 'center',
77 | justifyContent: 'center',
78 | },
79 | };
80 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/menuConfig.js:
--------------------------------------------------------------------------------
1 | // 菜单配置
2 | // headerMenuConfig:头部导航配置
3 | // asideMenuConfig:侧边导航配置
4 |
5 | const asideMenuConfig = [
6 | {
7 | name: 'Chart',
8 | path: '/dashboard',
9 | icon: 'chart',
10 | },
11 | {
12 | name: 'RDB Analyze',
13 | path: '/rdb',
14 | icon: 'content',
15 | },
16 | {
17 | name: 'Slowlog',
18 | path: '/slowlog',
19 | icon: 'ul-list',
20 | },
21 |
22 | {
23 | name: 'Client List',
24 | path: '/client',
25 | icon: 'ul-list',
26 | },
27 | ];
28 |
29 | const headerMenuConfig = asideMenuConfig;
30 |
31 | export default headerMenuConfig;
32 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/ClientList/ClientList.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import ClientMain from './components/ClientMain';
3 |
4 | export default class ClientList extends Component {
5 | static displayName = 'ClientConAnaylze';
6 |
7 | static propTypes = {};
8 |
9 | static defaultProps = {};
10 |
11 | constructor(props) {
12 | super(props);
13 | this.state = {
14 | };
15 | }
16 |
17 | render() {
18 |
19 | return (
20 |
21 |
22 |
23 | );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/ClientList/components/ClientList/index.js:
--------------------------------------------------------------------------------
1 | import ClientList from './ClientList';
2 |
3 | export default ClientList;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/ClientList/components/ClientMain/ClientMain.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { withRouter } from 'react-router-dom';
3 | import { Card } from '@icedesign/base';
4 |
5 | @withRouter
6 | export default class ClientMain extends Component {
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | clientListVisable: false,
12 | chartVisable: false,
13 | jobVisable: false,
14 | disabled: false,
15 | jobstatus: {
16 | Interval: '',
17 | endTime: null,
18 | execute: false,
19 | status: 'NO JOB',
20 | id: this.props.info,
21 | },
22 | };
23 | }
24 |
25 | onChartClose = () => {
26 | this.setState({
27 | chartVisable: false,
28 | });
29 | }
30 | onChartClick = () => {
31 | this.setState({
32 | chartVisable: true,
33 | });
34 | }
35 | onClick = () => {
36 | this.setState({
37 | clientListVisable: true,
38 | });
39 | }
40 |
41 |
42 | onClose = () => {
43 | this.setState({
44 | clientListVisable: false,
45 | chartVisable: false,
46 | });
47 | }
48 |
49 | onClickJob = () => {
50 | this.setState({
51 | jobVisable: true,
52 | });
53 | }
54 |
55 | render() {
56 | if (this.state.clientListVisable) {
57 | this.props.history.push({ pathname: '/client_list' });
58 | }
59 |
60 | if (this.state.chartVisable) {
61 | this.props.history.push({ pathname: '/client_statistics' });
62 | }
63 |
64 | if (this.state.jobVisable) {
65 | this.props.history.push({ pathname: '/client_monitors' });
66 | }
67 |
68 | return (
69 |
70 |
71 |
{ this.onClick(e); }}
76 | >
77 | Client List
78 |
83 |
84 |
{ this.onChartClick(e); }}
89 | >
90 | Statistics
91 |
95 |
96 |
{ this.onClickJob(e); }}
101 | >
102 | Monitors
103 |
107 |
108 |
109 |
110 | );
111 | }
112 | }
113 |
114 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/ClientList/components/ClientMain/index.js:
--------------------------------------------------------------------------------
1 | import ClientMain from './ClientMain';
2 |
3 | export default ClientMain;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/ClientList/components/Monitors/index.js:
--------------------------------------------------------------------------------
1 | import Monitors from './Monitors';
2 |
3 | export default Monitors;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/ClientList/components/Statistics/index.js:
--------------------------------------------------------------------------------
1 | import Statistics from './Statistics';
2 |
3 | export default Statistics;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/ClientList/index.js:
--------------------------------------------------------------------------------
1 | import ClientList from './ClientList';
2 |
3 | export default ClientList;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/CountRateLineChart/index.js:
--------------------------------------------------------------------------------
1 | import CountRateLineChart from './CountRateLineChart';
2 |
3 | export default CountRateLineChart;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/KeyCountByType/index.js:
--------------------------------------------------------------------------------
1 | import KeyCountByType from './KeyCountByType';
2 |
3 | export default KeyCountByType;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/KeyMemoryByType/index.js:
--------------------------------------------------------------------------------
1 | import KeyMemoryByType from './KeyMemoryByType';
2 |
3 | export default KeyMemoryByType;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/LineChart/index.js:
--------------------------------------------------------------------------------
1 | import LineChart from './LineChart';
2 |
3 | export default LineChart;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/MemoryRateLineChart/index.js:
--------------------------------------------------------------------------------
1 | import MemoryRateLineChart from './MemoryRateLineChart';
2 |
3 | export default MemoryRateLineChart;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/PrefixKeyTable/PrefixKeyTable.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import IceContainer from '@icedesign/container';
3 | import KeyCountTable from './KeyCountTable';
4 |
5 |
6 | export default class PrefixKeyTable extends Component {
7 | static displayName = 'ClientList';
8 |
9 | static propTypes = {};
10 |
11 | static defaultProps = {};
12 |
13 | constructor(props) {
14 | super(props);
15 | this.queryCache = {};
16 | }
17 |
18 | render() {
19 | return (
20 |
21 | Top 1000 Largest Keys By Perfix
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/PrefixKeyTable/index.js:
--------------------------------------------------------------------------------
1 | import PrefixKeyTable from './PrefixKeyTable';
2 |
3 | export default PrefixKeyTable;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/PrefixTTL.scss:
--------------------------------------------------------------------------------
1 |
2 | .colClas:hover {
3 | // width: 425px;
4 | // border: 0px solid #ddd;
5 | // overflow: hidden;
6 | // text-align: left;
7 | // text-overflow: ellipsis;
8 | // white-space: nowrap;
9 | color:#696969;
10 | // text-decoration:underline;
11 | cursor:pointer;
12 | }
13 |
14 |
15 | .colClas {
16 | width:'90%';
17 | white-space: nowrap;
18 | overflow: hidden;
19 | text-overflow: ellipsis;
20 |
21 | }
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/PrefixTTLTable/index.js:
--------------------------------------------------------------------------------
1 | import PrefixTTLTable from './PrefixTTLTable';
2 |
3 | export default PrefixTTLTable;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/TopKeyTable/TopKeyTable.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Tab } from '@icedesign/base';
3 | import IceContainer from '@icedesign/container';
4 | import HashTopKey from './HashTopKey';
5 | import ListTopKey from './ListTopKey';
6 | import SetTopKey from './SetTopKey';
7 | import StringTopKey from './StringTopKey';
8 |
9 |
10 | export default class TopKeyTable extends Component {
11 | static displayName = 'TopKeyTable';
12 |
13 | static propTypes = {};
14 |
15 | static defaultProps = {};
16 |
17 | constructor(props) {
18 | super(props);
19 | this.queryCache = {};
20 | this.state = {
21 | value: {},
22 | };
23 | }
24 |
25 | componentWillReceiveProps(nextProps) {
26 | this.setState({ value: nextProps.value }, () => {
27 |
28 | });
29 | }
30 | generateAnalyzeRet() {
31 | const panes = [{ tab: 'Hash', key: 0, content: },
32 | { tab: 'List', key: 1, content: },
33 | { tab: 'Set', key: 2, content: },
34 | { tab: 'String', key: 3, content: }];
35 | return (
36 |
37 |
38 | Top 1000 Largest Keys By Type
39 |
40 |
41 | {
42 | panes.map(pane => (
43 |
44 | {pane.content}
45 |
46 | ))
47 | }
48 |
49 |
50 |
51 |
52 | );
53 | }
54 |
55 |
56 | render() {
57 | let analyzeRet = null;
58 | analyzeRet = this.generateAnalyzeRet();
59 | return (
60 |
61 | {analyzeRet}
62 |
63 |
64 | );
65 | }
66 | }
67 |
68 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/components/TopKeyTable/index.js:
--------------------------------------------------------------------------------
1 | import TopKeyTable from './TopKeyTable';
2 |
3 | export default TopKeyTable;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Dashboard/index.js:
--------------------------------------------------------------------------------
1 | import Dashboard from './Dashboard';
2 |
3 | export default Dashboard;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RDBAnalyze/RDBAnalyze.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import RDBMain from './components/RDBMain';
3 |
4 | export default class RDBAnalyze extends Component {
5 | static displayName = 'RDBAnalyze';
6 |
7 | static propTypes = {};
8 |
9 | static defaultProps = {};
10 |
11 | constructor(props) {
12 | super(props);
13 | this.state = {};
14 | }
15 |
16 | render() {
17 | return (
18 |
19 |
20 |
21 | );
22 | }
23 | }
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RDBAnalyze/components/RDBAnalyzeList/RDBAnalyzeList.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import IceContainer from '@icedesign/container';
3 | import RDBRedisInfo from '../RDBRedisInfo';
4 |
5 | export default class RDBAnalyzeList extends Component {
6 | constructor(props) {
7 | super(props);
8 | const pid = sessionStorage.getItem('pid');
9 | this.state = {
10 | pid,
11 | };
12 | }
13 | render() {
14 | return (
15 |
16 | {/* */}
17 |
18 | );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RDBAnalyze/components/RDBAnalyzeList/index.js:
--------------------------------------------------------------------------------
1 | import RDBAnalyzeList from './RDBAnalyzeList';
2 |
3 | export default RDBAnalyzeList;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RDBAnalyze/components/RDBMain/RDBMain.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import IceContainer from '@icedesign/container';
3 | import RDBMainPage from './RDBMainPage';
4 |
5 | export default class RDBMain extends Component {
6 | constructor(props) {
7 | super(props);
8 | const pid = sessionStorage.getItem('pid');
9 | this.state = {
10 | pid,
11 | };
12 | }
13 | render() {
14 | return (
15 |
16 |
17 |
18 | );
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RDBAnalyze/components/RDBMain/StartAnalyze.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Button, Balloon } from '@icedesign/base';
3 |
4 |
5 | export default class StartAnalyze extends Component {
6 | constructor(props) {
7 | super(props);
8 | this.handleHide = this.handleHide.bind(this);
9 | this.state = {
10 | visible: false,
11 | };
12 | }
13 |
14 | handleHide = (visible, code) => {
15 | if (code === 1) {
16 | // 调用分析接口
17 | this.props.handleExec(this.props.pid);
18 | if (this.props.status) {
19 | }
20 | }
21 | this.setState({
22 | visible: false,
23 | });
24 | };
25 |
26 | handleVisible = (visible) => {
27 | this.setState({ visible });
28 | };
29 |
30 | render() {
31 | const visibleTrigger = (
32 |
35 | );
36 |
37 | const content = (
38 |
39 |
Confirm execute?
40 |
51 |
58 |
59 | );
60 |
61 | return (
62 |
68 | {content}
69 |
70 | );
71 | }
72 | }
73 |
74 | const styles = {
75 | contentText: {
76 | padding: '5px 0 15px',
77 | },
78 | };
79 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RDBAnalyze/components/RDBMain/index.js:
--------------------------------------------------------------------------------
1 | import RDBMain from './RDBMain';
2 |
3 | export default RDBMain;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RDBAnalyze/components/RDBNodeList/index.js:
--------------------------------------------------------------------------------
1 | import RDBNodeList from './RDBNodeList';
2 |
3 | export default RDBNodeList;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RDBAnalyze/index.js:
--------------------------------------------------------------------------------
1 | import RDBAnalyze from './RDBAnalyze';
2 |
3 | export default RDBAnalyze;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RedisInfo/components/rct/index.js:
--------------------------------------------------------------------------------
1 | import rctList from './rct';
2 |
3 | export default rctList;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RedisInfo/index.js:
--------------------------------------------------------------------------------
1 | import redisInfo from './redisInfo';
2 |
3 | export default redisInfo;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/RedisInfo/redisInfo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Rct from './components/rct';
3 | export default class RedisInfo extends Component {
4 | static displayName = 'RedisInfo';
5 |
6 | static propTypes = {};
7 |
8 | static defaultProps = {};
9 |
10 | constructor(props) {
11 | super(props);
12 | this.state = {};
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/Slowlog.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import SlowlogMain from './components/SlowlogMain';
3 |
4 | export default class Slowlog extends Component {
5 | static displayName = 'SlowlogAnaylzeList';
6 |
7 | static propTypes = {};
8 |
9 | static defaultProps = {};
10 |
11 | constructor(props) {
12 | super(props);
13 | this.state = {};
14 | }
15 |
16 | render() {
17 | return (
18 |
19 |
20 |
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogList/SlowlogList.scss:
--------------------------------------------------------------------------------
1 |
2 | .colClas:hover {
3 | // width: 425px;
4 | // border: 0px solid #ddd;
5 | // overflow: hidden;
6 | // text-align: left;
7 | // text-overflow: ellipsis;
8 | // white-space: nowrap;
9 | color:#696969;
10 | // text-decoration:underline;
11 | cursor:pointer;
12 | }
13 |
14 |
15 | .colClas {
16 | width:'90%';
17 | white-space: nowrap;
18 | overflow: hidden;
19 | text-overflow: ellipsis;
20 |
21 | }
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogList/index.js:
--------------------------------------------------------------------------------
1 | import SlowlogList from './SlowlogList';
2 |
3 | export default SlowlogList;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogMain/SlowlogMain.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { Card } from '@icedesign/base';
3 | import { withRouter } from 'react-router-dom';
4 |
5 | @withRouter
6 | class SlowlogMain extends Component {
7 | constructor(props) {
8 | super(props);
9 | this.state = {
10 |
11 | };
12 | }
13 |
14 | onSlowList = () => {
15 | this.props.history.push({ pathname: '/slowlog_list' });
16 | };
17 | onSlowlog = () => {
18 | this.props.history.push({ pathname: '/slowlog_statistic' });
19 | };
20 |
21 | onSlowEdit = () => {
22 | this.props.history.push({ pathname: '/slowlog_monitor' });
23 | };
24 | render() {
25 | return (
26 |
27 |
{
39 | this.onSlowList(e);
40 | }}
41 | >
42 | Slowlog List
43 |
44 |
45 |
46 |
{
58 | this.onSlowlog(e);
59 | }}
60 | >
61 | Statistics
62 |
63 |
64 |
{
75 | this.onSlowEdit(e);
76 | }}
77 | >
78 | Monitors
79 |
80 |
81 |
82 | );
83 | }
84 | }
85 | export default SlowlogMain;
86 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogMain/index.js:
--------------------------------------------------------------------------------
1 | import SlowlogMain from './SlowlogMain';
2 |
3 | export default SlowlogMain;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogMonitors/SlowlogMonitors.scss:
--------------------------------------------------------------------------------
1 |
2 | .next-switch-off {
3 | background-color: #9e9898;
4 | border-color: #c3c3c3;
5 | }
6 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogMonitors/index.js:
--------------------------------------------------------------------------------
1 | import SlowlogMonitors from './SlowlogMonitors';
2 |
3 | export default SlowlogMonitors;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogStatis/SlowlogStatis.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import IceContainer from '@icedesign/container';
3 | import { Loading } from '@icedesign/base';
4 | import axiosInstance from '../../../../axios';
5 | import './SlowlogStatis.scss';
6 |
7 | const ReactHighcharts = require('react-highcharts');
8 | const Highcharts = require('highcharts');
9 |
10 | export default class Echartes extends Component {
11 | static displayName = 'Echartes';
12 | constructor(props) {
13 | super(props);
14 | const pid = sessionStorage.getItem('pid');
15 | this.state = {
16 | loadingVisible: false,
17 | analyzeData: {},
18 | pid,
19 | };
20 | }
21 | componentDidMount() {
22 | this.handleLoading();
23 | axiosInstance
24 | .get(`/slowlog/statistics/${this.state.pid}`)
25 | .then((response) => {
26 | this.setState(
27 | { analyzeData: JSON.parse(response.data.data).commondsStatisticsObj },
28 | () => {
29 | this.handleLoading();
30 | }
31 | );
32 | })
33 | .catch((error) => {
34 | console.log(error);
35 | });
36 | }
37 |
38 | handleLoading = () => {
39 | this.setState({
40 | loadingVisible: !this.state.loadingVisible,
41 | });
42 | };
43 |
44 | generateAnalyzeRet() {
45 | const analyzeData = this.state.analyzeData;
46 | if (!analyzeData) {
47 | return null;
48 | }
49 | return (
50 |
51 |
52 |
53 |
54 |
55 | );
56 | }
57 |
58 | getOptionForPie = (data, scroll = false) => {
59 | const legendData = [];
60 | const seriesData = [];
61 | const selected = {};
62 | Object.keys(data).forEach((key, index) => {
63 | legendData.push(key);
64 | seriesData.push({
65 | name: key,
66 | y: data[key],
67 | });
68 | selected[key] = index < 6;
69 | });
70 | return {
71 | chart: {
72 | height: 300,
73 | plotBackgroundColor: null,
74 | plotBorderWidth: null,
75 | plotShadow: false,
76 | type: 'pie',
77 | },
78 | credits: {
79 | enabled: false,
80 | },
81 | title: {
82 | text: 'Commands Statistics',
83 | },
84 | tooltip: {
85 | pointFormat: '{series.name}: {point.percentage:.1f}%',
86 | },
87 | plotOptions: {
88 | pie: {
89 | allowPointSelect: true,
90 | cursor: 'pointer',
91 | dataLabels: {
92 | enabled: true,
93 | format: '{point.name}: {point.percentage:.1f} %',
94 | style: {
95 | color:
96 | (Highcharts.theme && Highcharts.theme.contrastTextColor) ||
97 | 'black',
98 | },
99 | },
100 | },
101 | },
102 | series: [
103 | {
104 | colorByPoint: true,
105 | data: seriesData,
106 | },
107 | ],
108 | };
109 | };
110 |
111 | render() {
112 | // 分析结果
113 | let analyzeRet = null;
114 | analyzeRet = this.generateAnalyzeRet();
115 | return (
116 |
117 |
122 | {analyzeRet}
123 |
124 |
125 | );
126 | }
127 | }
128 |
129 | const styles = {
130 | container: {
131 | width: '100%',
132 | },
133 | };
134 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogStatis/SlowlogStatis.scss:
--------------------------------------------------------------------------------
1 | .post-list-page {
2 | width: 100%;
3 | }
4 | select.placeholder {
5 | color: #999;
6 | }
7 | .test{
8 | float: right;
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/components/SlowlogStatis/index.js:
--------------------------------------------------------------------------------
1 | import SlowlogStatis from "./SlowlogStatis";
2 |
3 | export default SlowlogStatis;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/Slowlog/index.js:
--------------------------------------------------------------------------------
1 | import Slowlog from './Slowlog';
2 |
3 | export default Slowlog;
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/pages/UserLogin/index.js:
--------------------------------------------------------------------------------
1 | import UserLogin from './UserLogin';
2 |
3 | export default UserLogin;
4 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/router.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * 定义应用路由
3 | */
4 | import { HashRouter, Switch, Route } from 'react-router-dom';
5 | import React from 'react';
6 | import UserLayout from './layouts/UserLayout';
7 | import BasicLayout from './layouts/BasicLayout';
8 | import DashLayout from './layouts/DashLayout';
9 |
10 | // 按照 Layout 分组路由
11 | // UserLayout 对应的路由:/user/xxx
12 | // BasicLayout 对应的路由:/xxx
13 | const router = () => {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 | };
24 |
25 | export default router();
26 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/frontend/src/routerConfig.js:
--------------------------------------------------------------------------------
1 | // 以下文件格式为描述路由的协议格式
2 | // 你可以调整 routerConfig 里的内容
3 | // 变量名 routerConfig 为 iceworks 检测关键字,请不要修改名称
4 |
5 | import UserLogin from './pages/UserLogin';
6 | import Dashboard from './pages/Dashboard';
7 | import RedisInfo from './pages/RedisInfo';
8 | import ClientMain from './pages/ClientList';
9 | import RDBAnalyze from './pages/RDBAnalyze';
10 | import SlowlogMain from './pages/Slowlog';
11 | import SlowlogList from './pages/Slowlog/components/SlowlogList';
12 | import SlowlogSta from './pages/Slowlog/components/SlowlogStatis';
13 | import SlowlogMon from './pages/Slowlog/components/SlowlogMonitors';
14 | import ClientList from './pages/ClientList/components/ClientList';
15 | import ClientSta from './pages/ClientList/components/Statistics';
16 | import ClientMon from './pages/ClientList/components/Monitors';
17 | import RDBNodeList from './pages/RDBAnalyze/components/RDBNodeList';
18 |
19 | const routerConfig = [{
20 | path: '/user/login',
21 | component: UserLogin,
22 | },
23 | {
24 | path: '/dashboard',
25 | component: Dashboard,
26 | },
27 | {
28 | path: '/slowlog',
29 | component: SlowlogMain,
30 | },
31 | {
32 | path: '/rdb',
33 | component: RDBAnalyze,
34 | },
35 | {
36 | path: '/rdb_progress',
37 | component: RDBNodeList,
38 | },
39 | {
40 | path: '/client',
41 | component: ClientMain,
42 | },
43 | {
44 | path: '/rct',
45 | component: RedisInfo,
46 | },
47 | {
48 | path: '/client_list',
49 | component: ClientList,
50 | }, {
51 | path: '/client_statistics',
52 | component: ClientSta,
53 | }, {
54 | path: '/client_monitors',
55 | component: ClientMon,
56 | },
57 | {
58 | path: '/slowlog_list',
59 | component: SlowlogList,
60 | },
61 | {
62 | path: '/slowlog_monitor',
63 | component: SlowlogMon,
64 | },
65 | {
66 | path: '/slowlog_statistic',
67 | component: SlowlogSta,
68 | },
69 | ];
70 |
71 | export default routerConfig;
72 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/StartApp.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd;
2 |
3 | import org.nesc.ecbd.config.InitServer;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.springframework.beans.BeansException;
7 | import org.springframework.boot.SpringApplication;
8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
9 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
10 | import org.springframework.context.ApplicationContext;
11 | import org.springframework.context.ApplicationContextAware;
12 | import org.springframework.scheduling.annotation.EnableScheduling;
13 |
14 | /**
15 | * @author:Truman.P.Du
16 | * @createDate: 2018年3月21日 下午3:59:19
17 | * @version:1.0
18 | * @description: 程序入口
19 | */
20 | @SpringBootApplication
21 | @EnableEurekaServer
22 | @EnableScheduling
23 | public class StartApp implements ApplicationContextAware {
24 | private final static Logger LOG = LoggerFactory.getLogger(StartApp.class);
25 | private static ApplicationContext appContext = null;
26 | public static void main(String[] args) {
27 | SpringApplication.run(StartApp.class, args);
28 | InitServer initServer = (InitServer) appContext.getBean("initServer");
29 | initServer.init();
30 |
31 | LOG.info("RCT dashboard sevice start success!");
32 | }
33 |
34 | @Override
35 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
36 | if(appContext == null) {
37 | appContext = applicationContext;
38 | }
39 |
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/cache/AppCache.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.cache;
2 |
3 | import java.util.HashMap;
4 | import java.util.List;
5 | import java.util.Map;
6 | import java.util.concurrent.ConcurrentHashMap;
7 | import java.util.concurrent.ScheduledFuture;
8 |
9 | import org.nesc.ecbd.entity.AnalyzeStatus;
10 | import org.nesc.ecbd.entity.RDBAnalyze;
11 | import org.nesc.ecbd.entity.ScheduleDetail;
12 |
13 | /**
14 | * @author:Truman.P.Du
15 | * @createDate: 2018年10月19日 下午1:29:56
16 | * @version:1.0
17 | * @description: 应用静态缓存
18 | */
19 | public class AppCache {
20 | //
21 | public static Map scheduleProcess = new HashMap<>();
22 | // >
23 | public static Map> scheduleDetailMap = new ConcurrentHashMap<>();
24 | public static Map keyCountMap = new ConcurrentHashMap<>();
25 |
26 | public static Map,String>> taskList = new ConcurrentHashMap,String>>();
27 | /**
28 | * 根据rdbAnalyzeID判断当前集群分析任务是否完成
29 | *
30 | * @param rdbAnalyzeID
31 | * @return
32 | */
33 | public static boolean isAnalyzeSuccess(Long rdbAnalyzeID) {
34 | List scheduleDetails = scheduleDetailMap.get(rdbAnalyzeID);
35 | if (scheduleDetails != null && scheduleDetails.size() > 0) {
36 | boolean status = true;
37 | for (ScheduleDetail scheduleDetail : scheduleDetails) {
38 | if (!AnalyzeStatus.DONE.equals(scheduleDetail.getStatus())) {
39 | status = false;
40 | break;
41 | }
42 | }
43 | return status;
44 | }
45 | return true;
46 | }
47 |
48 | /**
49 | * 根据ID判断是否分析完成
50 | *
51 | * @param RDBAnalyze
52 | * rdbAnalyze
53 | * @return
54 | */
55 | public static boolean isAnalyzeComplete(RDBAnalyze rdbAnalyze) {
56 | List scheduleDetails = scheduleDetailMap.get(rdbAnalyze.getId());
57 | if (scheduleDetails != null && scheduleDetails.size() > 0) {
58 | boolean status = true;
59 | for (ScheduleDetail scheduleDetail : scheduleDetails) {
60 | if (!AnalyzeStatus.DONE.equals(scheduleDetail.getStatus())) {
61 | status = false;
62 | break;
63 | }
64 | }
65 | return status;
66 | }
67 | return false;
68 | }
69 |
70 | /**
71 | * 根据rdbAnalyzeID判断是否需要继续获取分析器执行状态
72 | *
73 | * @param rdbAnalyzeID
74 | * @return
75 | */
76 | public static boolean isNeedAnalyzeStastus(Long rdbAnalyzeID) {
77 | List scheduleDetails = scheduleDetailMap.get(rdbAnalyzeID);
78 | if (scheduleDetails != null && scheduleDetails.size() > 0) {
79 | boolean status = false;
80 | for (ScheduleDetail scheduleDetail : scheduleDetails) {
81 | if (!(AnalyzeStatus.DONE.equals(scheduleDetail.getStatus())
82 | || AnalyzeStatus.CANCELED.equals(scheduleDetail.getStatus()))) {
83 | status = true;
84 | break;
85 | }
86 | }
87 | return status;
88 | }
89 | return false;
90 | }
91 |
92 | public static Long getRdbAnalyzeIDByScheduleID(Long scheduleID) {
93 | for (Map.Entry entry : scheduleProcess.entrySet()) {
94 | if (entry.getValue().equals(scheduleID)) {
95 | return entry.getKey();
96 | }
97 | }
98 | return null;
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/common/BaseController.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.common;
2 |
3 | /**
4 | * @author:Truman.P.Du
5 | * @createDate: 2019年1月29日 上午10:01:18
6 | * @version:1.0
7 | * @description:
8 | */
9 | public class BaseController {
10 |
11 | public RestResponse SUCCESS() {
12 | return new RestResponse();
13 | }
14 |
15 | public RestResponse SUCCESS(String message) {
16 | return new RestResponse(200, message);
17 | }
18 |
19 | public RestResponse SUCCESS_DATA(Object data) {
20 | return new RestResponse(200, null, data);
21 | }
22 |
23 | public RestResponse SUCCESS(String message, Object data) {
24 | return new RestResponse(200, message, data);
25 | }
26 |
27 | public RestResponse ERROR(String message) {
28 | return new RestResponse(500, message);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/common/JobFactory.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.common;
2 |
3 | import org.quartz.spi.TriggerFiredBundle;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
6 | import org.springframework.scheduling.quartz.AdaptableJobFactory;
7 | import org.springframework.stereotype.Component;
8 |
9 | /**
10 | * @author:Truman.P.Du
11 | * @createDate: 2019年1月30日 下午4:26:31
12 | * @version:1.0
13 | * @description:
14 | */
15 | @Component
16 | public class JobFactory extends AdaptableJobFactory {
17 | @Autowired
18 | private AutowireCapableBeanFactory capableBeanFactory;
19 |
20 | @Override
21 | protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
22 | // 调用父类的方法
23 | Object jobInstance = super.createJobInstance(bundle);
24 | // 进行注入
25 | capableBeanFactory.autowireBean(jobInstance);
26 | return jobInstance;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/common/RestResponse.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.common;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.annotation.JsonInclude.Include;
5 |
6 | /**
7 | * @author:Truman.P.Du
8 | * @createDate: 2019年1月29日 上午10:13:45
9 | * @version:1.0
10 | * @description:统一返回对象
11 | */
12 | @JsonInclude(Include.NON_NULL)
13 | public class RestResponse {
14 |
15 | private int code;
16 | private String message;
17 | private Object data;
18 |
19 | public RestResponse() {
20 | this.code = 200;
21 | }
22 |
23 | public RestResponse(Object data) {
24 | this.code = 200;
25 | this.data = data;
26 | }
27 | public RestResponse(int code, String message) {
28 | this.code = code;
29 | this.message = message;
30 | }
31 |
32 |
33 |
34 | public RestResponse(int code, String message, Object data) {
35 | this.code = code;
36 | this.message = message;
37 | this.data = data;
38 | }
39 |
40 | public Integer getCode() {
41 | return code;
42 | }
43 |
44 | public void setCode(int code) {
45 | this.code = code;
46 | }
47 |
48 | public String getMessage() {
49 | return message;
50 | }
51 |
52 | public void setMessage(String message) {
53 | this.message = message;
54 | }
55 |
56 | public Object getData() {
57 | return data;
58 | }
59 |
60 | public void setData(Object data) {
61 | this.data = data;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/common/SuperMapper.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.common;
2 |
3 | import com.baomidou.mybatisplus.mapper.BaseMapper;
4 |
5 | /**
6 | * @author:Truman.P.Du
7 | * @createDate: 2018年3月23日 下午3:44:49
8 | * @version:1.0
9 | * @description:
10 | */
11 | public interface SuperMapper extends BaseMapper {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/config/CorsConfig.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.cors.CorsConfiguration;
6 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
7 | import org.springframework.web.filter.CorsFilter;
8 |
9 | /**
10 | * @author:Truman.P.Du
11 | * @createDate: 2018年3月24日 下午3:48:20
12 | * @version:1.0
13 | * @description:
14 | */
15 | @Configuration
16 | public class CorsConfig {
17 | private CorsConfiguration buildConfig() {
18 | CorsConfiguration corsConfiguration = new CorsConfiguration();
19 | corsConfiguration.addAllowedOrigin("*"); // 1
20 | corsConfiguration.addAllowedHeader("*"); // 2
21 | corsConfiguration.addAllowedMethod("*"); // 3
22 | return corsConfiguration;
23 | }
24 |
25 | @Bean
26 | public CorsFilter corsFilter() {
27 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
28 | source.registerCorsConfiguration("/**", buildConfig()); // 4
29 | return new CorsFilter(source);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/config/InitServer.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.config;
2 |
3 |
4 | import java.util.List;
5 |
6 | import org.nesc.ecbd.entity.RDBAnalyze;
7 | import org.nesc.ecbd.entity.SlowlogEntity;
8 | import org.nesc.ecbd.service.RDBAnalyzeService;
9 | import org.nesc.ecbd.service.RDBScheduleJob;
10 | import org.nesc.ecbd.service.ScheduleTaskService;
11 | import org.nesc.ecbd.service.SlowlogScheduleJob;
12 | import org.nesc.ecbd.service.SlowlogService;
13 | import org.nesc.ecbd.utils.ElasticSearchUtil;
14 | import org.quartz.SchedulerException;
15 | import org.slf4j.Logger;
16 | import org.slf4j.LoggerFactory;
17 | import org.springframework.beans.factory.annotation.Autowired;
18 | import org.springframework.context.annotation.Bean;
19 | import org.springframework.http.client.ClientHttpRequestFactory;
20 | import org.springframework.http.client.SimpleClientHttpRequestFactory;
21 | import org.springframework.stereotype.Component;
22 | import org.springframework.web.client.RestTemplate;
23 |
24 | /**
25 | * @author:Truman.P.Du
26 | * @createDate: 2018年4月13日 下午2:00:16
27 | * @version:1.0
28 | * @description: 1. 默认启动后台进程,主要是为了新建进程,处理分析节点上报状态,避免出现状态数据出错 2. 初始化bean
29 | */
30 | @Component
31 | public class InitServer {
32 | private static final Logger LOG = LoggerFactory.getLogger(InitServer.class);
33 |
34 | @Autowired
35 | InitConfig initConfig;
36 |
37 | @Autowired
38 | ScheduleTaskService scheduleTaskService;
39 | @Autowired
40 | SlowlogService slowlogService;
41 | @Autowired
42 | RDBAnalyzeService rdbAnalyzeService;
43 |
44 |
45 | public void init() {
46 | // 初始化ES工具类
47 | if(initConfig.isElasticsearchEnable()) {
48 | Integer requestTimeout = 10000;
49 | Integer socketTimeout = 10000;
50 | ElasticSearchUtil.init(requestTimeout, socketTimeout, initConfig.getEsUrls());
51 | }
52 |
53 | //启动定时任务
54 | initRDBJob();
55 | initSlowlogJob();
56 | }
57 |
58 | @Bean
59 | public RestTemplate buildRestTemplate() {
60 | return new RestTemplate(simpleClientHttpRequestFactory());
61 | }
62 |
63 | public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
64 | SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
65 | factory.setReadTimeout(10000);
66 | factory.setConnectTimeout(15000);
67 | return factory;
68 | }
69 |
70 | public void initSlowlogJob() {
71 | List slowlogEntities = slowlogService.getTotals();
72 | for (SlowlogEntity entity : slowlogEntities) {
73 | try {
74 | if (entity.getAutoAnalyze()) {
75 | scheduleTaskService.addTask(entity, SlowlogScheduleJob.class);
76 | }
77 | } catch (SchedulerException e) {
78 | LOG.error("schedule job run faild!message:{}", e.getMessage());
79 | }
80 | }
81 | }
82 |
83 | public void initRDBJob() {
84 | List rdbAnalyzes = rdbAnalyzeService.list();
85 | for (RDBAnalyze rdbAnalyze : rdbAnalyzes) {
86 | try {
87 | if (rdbAnalyze.getAutoAnalyze()) {
88 | scheduleTaskService.addTask(rdbAnalyze, RDBScheduleJob.class);
89 | }
90 | } catch (SchedulerException e) {
91 | LOG.error("schedule job run faild!message:{}", e.getMessage());
92 | }
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/config/MybatisPlusConfig.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.config;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | import com.baomidou.mybatisplus.mapper.ISqlInjector;
8 | import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
9 | import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
10 |
11 | /**
12 | * @author:Truman.P.Du
13 | * @createDate: 2018年3月23日 下午3:15:23
14 | * @version:1.0
15 | * @description:
16 | */
17 | @Configuration
18 | @MapperScan("org.nesc.ecbd.mapper*")
19 | public class MybatisPlusConfig {
20 |
21 | /**
22 | * mybatis-plus分页插件
23 | * 文档:http://mp.baomidou.com
24 | */
25 | @Bean
26 | public PaginationInterceptor paginationInterceptor() {
27 | return new PaginationInterceptor();
28 | }
29 |
30 |
31 | /**
32 | * 注入sql注入器
33 | */
34 | @Bean
35 | public ISqlInjector sqlInjector() {
36 | return new LogicSqlInjector();
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/config/QuartzSchedule.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.config;
2 |
3 | import java.io.IOException;
4 |
5 | import org.nesc.ecbd.common.JobFactory;
6 | import org.nesc.ecbd.service.RDBScheduleJob;
7 | import org.nesc.ecbd.service.SlowlogScheduleJob;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.Configuration;
11 | import org.springframework.scheduling.quartz.JobDetailFactoryBean;
12 | import org.springframework.scheduling.quartz.SchedulerFactoryBean;
13 |
14 | /**
15 | * @author:Truman.P.Du
16 | * @createDate: 2019年1月30日 下午4:39:12
17 | * @version:1.0
18 | * @description:
19 | */
20 |
21 | @Configuration
22 | public class QuartzSchedule {
23 |
24 | @Autowired
25 | private JobFactory jobFactory;
26 |
27 | @Bean(name = "schedulerFactoryBean")
28 | public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
29 | SchedulerFactoryBean factory = new SchedulerFactoryBean();
30 | factory.setOverwriteExistingJobs(true);
31 | // 延时启动
32 | factory.setStartupDelay(20);
33 | // 自定义Job Factory,用于Spring注入
34 | factory.setJobFactory(jobFactory);
35 | return factory;
36 | }
37 |
38 | @Bean(name = "slowlogScheduleJob")
39 | public JobDetailFactoryBean slowlogScheduleJob() {
40 | JobDetailFactoryBean jobDetail = new JobDetailFactoryBean();
41 | jobDetail.setJobClass(SlowlogScheduleJob.class);
42 | return jobDetail;
43 | }
44 |
45 | @Bean(name = "rdbScheduleJob")
46 | public JobDetailFactoryBean rdbScheduleJob() {
47 | JobDetailFactoryBean jobDetail = new JobDetailFactoryBean();
48 | jobDetail.setJobClass(RDBScheduleJob.class);
49 | return jobDetail;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/config/ResponseConfig.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.config;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import org.nesc.ecbd.common.RestResponse;
7 | import org.springframework.beans.factory.InitializingBean;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.Configuration;
11 | import org.springframework.core.MethodParameter;
12 | import org.springframework.web.context.request.NativeWebRequest;
13 | import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
14 | import org.springframework.web.method.support.ModelAndViewContainer;
15 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
16 | import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
17 |
18 | /**
19 | * @author:Truman.P.Du
20 | * @createDate: 2019年1月29日 上午10:27:09
21 | * @version:1.0
22 | * @description:
23 | */
24 |
25 | @Configuration
26 | public class ResponseConfig {
27 | @Bean
28 | public ResponseBodyWrapFactoryBean getResponseBodyWrap() {
29 | return new ResponseBodyWrapFactoryBean();
30 | }
31 |
32 | class ResponseBodyWrapFactoryBean implements InitializingBean {
33 |
34 | @Autowired
35 | private RequestMappingHandlerAdapter adapter;
36 |
37 | @SuppressWarnings({ "unchecked", "rawtypes" })
38 | @Override
39 | public void afterPropertiesSet() throws Exception {
40 |
41 | List returnValueHandlers = adapter.getReturnValueHandlers();
42 | List handlers = new ArrayList(returnValueHandlers);
43 | decorateHandlers(handlers);
44 | adapter.setReturnValueHandlers(handlers);
45 |
46 | }
47 |
48 | private void decorateHandlers(List handlers) {
49 |
50 | for (HandlerMethodReturnValueHandler handler : handlers) {
51 | if (handler instanceof RequestResponseBodyMethodProcessor) {
52 | ResponseBodyWrapHandler decorator = new ResponseBodyWrapHandler(handler);
53 | int index = handlers.indexOf(handler);
54 | handlers.set(index, decorator);
55 | break;
56 | }
57 | }
58 |
59 | }
60 |
61 | }
62 |
63 | static class ResponseBodyWrapHandler implements HandlerMethodReturnValueHandler {
64 | private final HandlerMethodReturnValueHandler delegate;
65 |
66 | public ResponseBodyWrapHandler(HandlerMethodReturnValueHandler delegate) {
67 | this.delegate = delegate;
68 | }
69 |
70 | @Override
71 | public boolean supportsReturnType(MethodParameter returnType) {
72 | return delegate.supportsReturnType(returnType);
73 | }
74 |
75 | @Override
76 | public void handleReturnValue(Object returnValue, MethodParameter returnType,
77 | ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
78 | RestResponse restResponse = null;
79 | if (returnValue instanceof RestResponse) {
80 | restResponse = (RestResponse) returnValue;
81 | } else {
82 | restResponse = new RestResponse(returnValue);
83 | }
84 | delegate.handleReturnValue(restResponse, returnType, mavContainer, webRequest);
85 | }
86 |
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/RCT-Dashboard/src/main/java/org/nesc/ecbd/controller/RedisInfoController.java:
--------------------------------------------------------------------------------
1 | package org.nesc.ecbd.controller;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Date;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.web.bind.annotation.PathVariable;
11 | import org.springframework.web.bind.annotation.RequestBody;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.bind.annotation.RequestMethod;
14 | import org.springframework.web.bind.annotation.ResponseBody;
15 | import org.springframework.web.bind.annotation.RestController;
16 |
17 | import org.nesc.ecbd.common.BaseController;
18 | import org.nesc.ecbd.common.RestResponse;
19 | import org.nesc.ecbd.entity.RedisInfo;
20 | import org.nesc.ecbd.service.RedisInfoService;
21 |
22 | /**
23 | *
24 | * @author Jacob Cao
25 | *
26 | * 2019年1月17日
27 | */
28 | @RestController
29 | @RequestMapping("/redis")
30 | public class RedisInfoController extends BaseController {
31 | @Autowired
32 | RedisInfoService redisInfoService;
33 |
34 | // query all
35 | @RequestMapping(value = { "", "/" }, method = RequestMethod.GET)
36 | @ResponseBody
37 | public RestResponse listRedisInfo() {
38 | List redisList = redisInfoService.getTotalData();
39 | return SUCCESS(null,redisList);
40 | }
41 |
42 | // query one
43 | @RequestMapping(value = "/{id}", method = RequestMethod.GET)
44 | @ResponseBody
45 | public RestResponse queryRedisInfo(@PathVariable("id") Long id) {
46 | RedisInfo redisInfo = redisInfoService.selectById(id);
47 | return SUCCESS_DATA(redisInfo);
48 | }
49 |
50 | // delete
51 | @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
52 | @ResponseBody
53 | public RestResponse deleteRedisInfo(@PathVariable("id") Long id) {
54 | if (redisInfoService.delete(id)) {
55 | return SUCCESS("delete success!");
56 | } else {
57 | return ERROR("delete fail!");
58 | }
59 | }
60 |
61 | // update
62 | @RequestMapping(value = { "", "/" }, method = RequestMethod.PUT)
63 | @ResponseBody
64 | public RestResponse updateRedisInfo(@RequestBody RedisInfo redisInfo) {
65 |
66 | try {
67 | if (redisInfoService.update(redisInfo)) {
68 | return SUCCESS("update success!");
69 | } else {
70 | return SUCCESS("update fail!");
71 | }
72 | } catch (Exception e) {
73 | return ERROR(e.getMessage());
74 | }
75 | }
76 |
77 | // add
78 | @RequestMapping(value = { "", "/" }, method = RequestMethod.POST)
79 | @ResponseBody
80 | public RestResponse addRedisInfo(@RequestBody RedisInfo redisInfo) {
81 | redisInfo.setCreateDate(new Date());
82 |
83 | try {
84 | if (redisInfoService.add(redisInfo)) {
85 | return SUCCESS("add success!");
86 | } else {
87 | return SUCCESS("add fail!");
88 | }
89 | } catch (Exception e) {
90 | return ERROR(e.getMessage());
91 | }
92 | }
93 |
94 | @RequestMapping(value = "query_nodes/{id}", method = RequestMethod.GET)
95 | @ResponseBody
96 | public RestResponse getRedisNodes(@PathVariable String id) {
97 | List