You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by ha...@apache.org on 2018/01/11 11:51:46 UTC

[incubator-skywalking-ui] branch feature/5.0.0 updated: Add application topology

This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch feature/5.0.0
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git


The following commit(s) were added to refs/heads/feature/5.0.0 by this push:
     new 35a2bae  Add application topology
35a2bae is described below

commit 35a2bae1584729bc009919b40de92657f0a9fe60
Author: gaohongtao <ha...@gmail.com>
AuthorDate: Thu Jan 11 19:51:31 2018 +0800

    Add application topology
---
 src/main/frontend/mock/dashboard.js                |  85 +++++++++++++++++++++
 src/main/frontend/public/alert.png                 | Bin 0 -> 4326 bytes
 src/main/frontend/public/app.jpg                   | Bin 0 -> 8847 bytes
 src/main/frontend/public/data.png                  | Bin 0 -> 7245 bytes
 src/main/frontend/public/img/node/DUBBO.png        | Bin 0 -> 3537 bytes
 .../frontend/public/img/node/FeignDefaultHttp.png  | Bin 0 -> 3892 bytes
 src/main/frontend/public/img/node/H2.png           | Bin 0 -> 2681 bytes
 src/main/frontend/public/img/node/HPROSE.png       | Bin 0 -> 2158 bytes
 src/main/frontend/public/img/node/HTTPCLIENT.png   | Bin 0 -> 10718 bytes
 src/main/frontend/public/img/node/JETTY.png        | Bin 0 -> 2838 bytes
 src/main/frontend/public/img/node/JETTYSERVER.png  | Bin 0 -> 9889 bytes
 src/main/frontend/public/img/node/MONGODB.png      | Bin 0 -> 4161 bytes
 src/main/frontend/public/img/node/MOTAN.png        | Bin 0 -> 17288 bytes
 src/main/frontend/public/img/node/MYSQL.png        | Bin 0 -> 4980 bytes
 src/main/frontend/public/img/node/NutzHttp.png     | Bin 0 -> 12509 bytes
 src/main/frontend/public/img/node/NutzMvc.png      | Bin 0 -> 14196 bytes
 src/main/frontend/public/img/node/OKHTTP.png       | Bin 0 -> 4070 bytes
 src/main/frontend/public/img/node/Oracle.png       | Bin 0 -> 4312 bytes
 src/main/frontend/public/img/node/REDIS.png        | Bin 0 -> 5178 bytes
 src/main/frontend/public/img/node/RESIN.png        | Bin 0 -> 15092 bytes
 src/main/frontend/public/img/node/SPRINGMVC.png    | Bin 0 -> 11226 bytes
 src/main/frontend/public/img/node/STRUTS2.png      | Bin 0 -> 11643 bytes
 src/main/frontend/public/img/node/UNDEFINED.png    | Bin 0 -> 2918 bytes
 src/main/frontend/public/img/node/USER.png         | Bin 0 -> 2444 bytes
 src/main/frontend/public/img/node/tomcat.png       | Bin 0 -> 4302 bytes
 .../src/components/Topology/AppTopology.js         |  78 +++++++++++++++++++
 src/main/frontend/src/components/Topology/Base.js  |  42 ++++++++++
 .../frontend/src/components/Topology/Topology.js   |  37 ---------
 src/main/frontend/src/components/Topology/conf.js  |   5 ++
 src/main/frontend/src/components/Topology/index.js |   5 ++
 .../frontend/src/components/Topology/index.less    |  17 +++++
 src/main/frontend/src/models/dashboard.js          |   4 +
 .../frontend/src/routes/Dashboard/Dashboard.js     |   3 +-
 33 files changed, 238 insertions(+), 38 deletions(-)

diff --git a/src/main/frontend/mock/dashboard.js b/src/main/frontend/mock/dashboard.js
index c97c655..37f2e79 100644
--- a/src/main/frontend/mock/dashboard.js
+++ b/src/main/frontend/mock/dashboard.js
@@ -20,6 +20,91 @@ export default {
           },
           'getTopNSlowService|10': [{ 'key|+1': 1, name: '@name', 'avgResponseTime|200-1000': 1 }],
           'getTopNServerThroughput|10': [{ 'key|+1': 1, name: '@name', 'tps|100-10000': 1 }],
+          getClusterTopology: () => {
+            const application = mockjs.mock({
+              'nodes|5-20': [
+                {
+                  data: {
+                    'id|+1': 1,
+                    name: '@name',
+                    'type|1': ['DUBBO', 'tomcat', 'SPRINGMVC'],
+                    'calls|1000-2000': 1,
+                    'sla|1-100.1-2': 1,
+                    'apdex|0.2': 1,
+                    'numOfServer|1-100': 1,
+                    'numOfServerAlarm|1-100': 1,
+                    'numOfServiceAlarm|1-100': 1,
+                    'isIncomingNode|1': true,
+                  },
+                },
+              ],
+            });
+            const users = mockjs.mock({
+              'nodes|1-3': [
+                {
+                  data: {
+                    'id|+1': 100,
+                    name: 'User',
+                    type: 'USER',
+                  },
+                },
+              ],
+            });
+            const resources = mockjs.mock({
+              'nodes|2-5': [
+                {
+                  data: {
+                    'id|+1': 200,
+                    name: '@name',
+                    'type|1': ['Oracle', 'MYSQL', 'REDIS'],
+                  },
+                },
+              ],
+            });
+            const nodes = application.nodes.concat(users.nodes, resources.nodes);
+            const userConnectApplication = mockjs.mock({
+              'calls|1-3': [{
+                data: {
+                  'source|+1': 100,
+                  'target|+1': 1,
+                  'isAlarm|1': true,
+                  'callType|1': ['rpc', 'http', 'dubbo'],
+                  'callsPerSec|100-2000': 1,
+                  'responseTimePerSec: 500-5000': 1,
+                },
+              }],
+            });
+            const applicationConnectApplication = mockjs.mock({
+              'calls|1-3': [{
+                data: {
+                  'source|+1': 1,
+                  'target|+1': 1,
+                  'isAlarm|1': true,
+                  'callType|1': ['rpc', 'http', 'dubbo'],
+                  'callsPerSec|100-2000': 1,
+                  'responseTimePerSec: 500-5000': 1,
+                },
+              }],
+            });
+            const applicationConnectResources = mockjs.mock({
+              'calls|1-3': [{
+                data: {
+                  'source|+1': 1,
+                  'target|+1': 200,
+                  'isAlarm|1': true,
+                  'callType|1': ['rpc', 'http', 'dubbo'],
+                  'callsPerSec|100-2000': 1,
+                  'responseTimePerSec: 500-5000': 1,
+                },
+              }],
+            });
+            const calls = userConnectApplication.calls
+              .concat(applicationConnectApplication.calls, applicationConnectResources.calls);
+            return {
+              nodes,
+              calls,
+            };
+          },
         },
       }
     ));
diff --git a/src/main/frontend/public/alert.png b/src/main/frontend/public/alert.png
new file mode 100755
index 0000000..e24e202
Binary files /dev/null and b/src/main/frontend/public/alert.png differ
diff --git a/src/main/frontend/public/app.jpg b/src/main/frontend/public/app.jpg
new file mode 100755
index 0000000..8d8166d
Binary files /dev/null and b/src/main/frontend/public/app.jpg differ
diff --git a/src/main/frontend/public/data.png b/src/main/frontend/public/data.png
new file mode 100755
index 0000000..7c15d62
Binary files /dev/null and b/src/main/frontend/public/data.png differ
diff --git a/src/main/frontend/public/img/node/DUBBO.png b/src/main/frontend/public/img/node/DUBBO.png
new file mode 100644
index 0000000..c388222
Binary files /dev/null and b/src/main/frontend/public/img/node/DUBBO.png differ
diff --git a/src/main/frontend/public/img/node/FeignDefaultHttp.png b/src/main/frontend/public/img/node/FeignDefaultHttp.png
new file mode 100644
index 0000000..b727c0f
Binary files /dev/null and b/src/main/frontend/public/img/node/FeignDefaultHttp.png differ
diff --git a/src/main/frontend/public/img/node/H2.png b/src/main/frontend/public/img/node/H2.png
new file mode 100644
index 0000000..29e78b1
Binary files /dev/null and b/src/main/frontend/public/img/node/H2.png differ
diff --git a/src/main/frontend/public/img/node/HPROSE.png b/src/main/frontend/public/img/node/HPROSE.png
new file mode 100644
index 0000000..a90bd98
Binary files /dev/null and b/src/main/frontend/public/img/node/HPROSE.png differ
diff --git a/src/main/frontend/public/img/node/HTTPCLIENT.png b/src/main/frontend/public/img/node/HTTPCLIENT.png
new file mode 100644
index 0000000..00f158f
Binary files /dev/null and b/src/main/frontend/public/img/node/HTTPCLIENT.png differ
diff --git a/src/main/frontend/public/img/node/JETTY.png b/src/main/frontend/public/img/node/JETTY.png
new file mode 100644
index 0000000..85d8167
Binary files /dev/null and b/src/main/frontend/public/img/node/JETTY.png differ
diff --git a/src/main/frontend/public/img/node/JETTYSERVER.png b/src/main/frontend/public/img/node/JETTYSERVER.png
new file mode 100644
index 0000000..31cafa8
Binary files /dev/null and b/src/main/frontend/public/img/node/JETTYSERVER.png differ
diff --git a/src/main/frontend/public/img/node/MONGODB.png b/src/main/frontend/public/img/node/MONGODB.png
new file mode 100644
index 0000000..93d9a01
Binary files /dev/null and b/src/main/frontend/public/img/node/MONGODB.png differ
diff --git a/src/main/frontend/public/img/node/MOTAN.png b/src/main/frontend/public/img/node/MOTAN.png
new file mode 100644
index 0000000..ff57bf9
Binary files /dev/null and b/src/main/frontend/public/img/node/MOTAN.png differ
diff --git a/src/main/frontend/public/img/node/MYSQL.png b/src/main/frontend/public/img/node/MYSQL.png
new file mode 100644
index 0000000..34530b4
Binary files /dev/null and b/src/main/frontend/public/img/node/MYSQL.png differ
diff --git a/src/main/frontend/public/img/node/NutzHttp.png b/src/main/frontend/public/img/node/NutzHttp.png
new file mode 100644
index 0000000..506cfad
Binary files /dev/null and b/src/main/frontend/public/img/node/NutzHttp.png differ
diff --git a/src/main/frontend/public/img/node/NutzMvc.png b/src/main/frontend/public/img/node/NutzMvc.png
new file mode 100644
index 0000000..dce0725
Binary files /dev/null and b/src/main/frontend/public/img/node/NutzMvc.png differ
diff --git a/src/main/frontend/public/img/node/OKHTTP.png b/src/main/frontend/public/img/node/OKHTTP.png
new file mode 100644
index 0000000..c4c19a9
Binary files /dev/null and b/src/main/frontend/public/img/node/OKHTTP.png differ
diff --git a/src/main/frontend/public/img/node/Oracle.png b/src/main/frontend/public/img/node/Oracle.png
new file mode 100644
index 0000000..7b1cd56
Binary files /dev/null and b/src/main/frontend/public/img/node/Oracle.png differ
diff --git a/src/main/frontend/public/img/node/REDIS.png b/src/main/frontend/public/img/node/REDIS.png
new file mode 100644
index 0000000..5c6a5a4
Binary files /dev/null and b/src/main/frontend/public/img/node/REDIS.png differ
diff --git a/src/main/frontend/public/img/node/RESIN.png b/src/main/frontend/public/img/node/RESIN.png
new file mode 100644
index 0000000..aa0eed3
Binary files /dev/null and b/src/main/frontend/public/img/node/RESIN.png differ
diff --git a/src/main/frontend/public/img/node/SPRINGMVC.png b/src/main/frontend/public/img/node/SPRINGMVC.png
new file mode 100644
index 0000000..626f832
Binary files /dev/null and b/src/main/frontend/public/img/node/SPRINGMVC.png differ
diff --git a/src/main/frontend/public/img/node/STRUTS2.png b/src/main/frontend/public/img/node/STRUTS2.png
new file mode 100644
index 0000000..5f1d499
Binary files /dev/null and b/src/main/frontend/public/img/node/STRUTS2.png differ
diff --git a/src/main/frontend/public/img/node/UNDEFINED.png b/src/main/frontend/public/img/node/UNDEFINED.png
new file mode 100644
index 0000000..3e1d681
Binary files /dev/null and b/src/main/frontend/public/img/node/UNDEFINED.png differ
diff --git a/src/main/frontend/public/img/node/USER.png b/src/main/frontend/public/img/node/USER.png
new file mode 100644
index 0000000..a195d8f
Binary files /dev/null and b/src/main/frontend/public/img/node/USER.png differ
diff --git a/src/main/frontend/public/img/node/tomcat.png b/src/main/frontend/public/img/node/tomcat.png
new file mode 100644
index 0000000..5c4a1a3
Binary files /dev/null and b/src/main/frontend/public/img/node/tomcat.png differ
diff --git a/src/main/frontend/src/components/Topology/AppTopology.js b/src/main/frontend/src/components/Topology/AppTopology.js
new file mode 100644
index 0000000..0d7e59f
--- /dev/null
+++ b/src/main/frontend/src/components/Topology/AppTopology.js
@@ -0,0 +1,78 @@
+import styles from './index.less';
+import Base from './Base';
+
+export default class AppTopology extends Base {
+  getStyle = () => {
+    return [
+      {
+        selector: 'node[calls]',
+        style: {
+          width: 120,
+          height: 120,
+          'text-valign': 'bottom',
+          'text-halign': 'center',
+          'background-color': '#fff',
+          'border-width': 3,
+          'border-color': ele => (ele.data('isAlarm') ? 'red' : 'rgb(99, 160, 167)'),
+          'font-family': 'Microsoft YaHei',
+          label: 'data(name)',
+        },
+      },
+      {
+        selector: 'node[!calls]',
+        style: {
+          width: 60,
+          height: 60,
+          'text-valign': 'bottom',
+          'text-halign': 'center',
+          'background-color': '#fff',
+          'background-image': ele => `img/node/${ele.data('type') ? ele.data('type') : 'UNDEFINED'}.png`,
+          'background-width': '60%',
+          'background-height': '60%',
+          'border-width': 1,
+          'font-family': 'Microsoft YaHei',
+          label: 'data(name)',
+        },
+      },
+      {
+        selector: 'edge',
+        style: {
+          'curve-style': 'unbundled-bezier',
+          'target-arrow-shape': 'triangle',
+          'target-arrow-color': ele => (ele.data('isAlarm') ? 'red' : 'rgb(147, 198, 174)'),
+          'line-color': ele => (ele.data('isAlarm') ? 'red' : 'rgb(147, 198, 174)'),
+          width: 2,
+          label: ele => `${ele.data('callType')} \n ${ele.data('callsPerSec')} tps / ${ele.data('responseTimePerSec')} ms`,
+          'text-wrap': 'wrap',
+          color: 'rgb(110, 112, 116)',
+          'text-rotation': 'autorotate',
+        },
+      },
+    ];
+  }
+  getNodeLabel = () => {
+    return [
+      {
+        query: 'node[calls]',
+        halign: 'center',
+        valign: 'center',
+        halignBox: 'center',
+        valignBox: 'center',
+        cssClass: `${styles.node}`,
+        tpl(data) {
+          return `
+          <div class="${styles.circle}">
+            <div class="node-percentage">${data.sla}%</div>
+            <div>${data.calls} calls/s</div>
+            <div>
+              <img src="data.png" class="${styles.logo}"/>${data.numOfServer}
+              <img src="alert.png" class="${styles.logo}"/>
+              <span class="${styles.alert}">${data.numOfServerAlarm}</span>
+            </div>
+            <div>${data.apdex} Apdex</div>
+          </div>`;
+        },
+      },
+    ];
+  }
+}
diff --git a/src/main/frontend/src/components/Topology/Base.js b/src/main/frontend/src/components/Topology/Base.js
new file mode 100644
index 0000000..b934a02
--- /dev/null
+++ b/src/main/frontend/src/components/Topology/Base.js
@@ -0,0 +1,42 @@
+import React, { Component } from 'react';
+import cytoscape from 'cytoscape';
+import coseBilkent from 'cytoscape-cose-bilkent';
+import nodeHtmlLabel from 'cytoscape-node-html-label';
+import conf from './conf';
+
+cytoscape.use(coseBilkent);
+cytoscape.use(nodeHtmlLabel);
+
+const cyStyle = {
+  height: '400px',
+  display: 'block',
+};
+
+export default class Base extends Component {
+  componentDidMount() {
+    this.elements = this.props.elements;
+    const { nodes, calls } = this.props.elements;
+    this.cy = cytoscape({ ...conf, elements: { nodes, edges: calls }, style: this.getStyle() });
+    this.cy.nodeHtmlLabel(this.getNodeLabel());
+  }
+  componentWillReceiveProps(nextProps) {
+    if (nextProps.elements === this.elements) {
+      return;
+    }
+    this.elements = nextProps.elements;
+    const { nodes, calls } = this.elements;
+    this.cy.json({ elements: { nodes, edges: calls }, style: this.getStyle() });
+  }
+  shouldComponentUpdate() {
+    return false;
+  }
+  componentWillUnmount() {
+    this.cy.destroy();
+  }
+  getCy() {
+    return this.cy;
+  }
+  render() {
+    return (<div style={cyStyle} ref={(el) => { conf.container = el; }} />);
+  }
+}
diff --git a/src/main/frontend/src/components/Topology/Topology.js b/src/main/frontend/src/components/Topology/Topology.js
deleted file mode 100644
index 475603e..0000000
--- a/src/main/frontend/src/components/Topology/Topology.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import React, { Component } from 'react';
-import cytoscape from 'cytoscape';
-import coseBilkent from 'cytoscape-cose-bilkent';
-import nodeHtmlLabel from 'cytoscape-node-html-label';
-import conf from './conf';
-
-cytoscape.use(coseBilkent);
-cytoscape.use(nodeHtmlLabel);
-
-const cyStyle = {
-  height: '400px',
-  display: 'block',
-};
-
-class Topology extends Component {
-  componentDidMount() {
-    this.cy = cytoscape(conf);
-    this.cy.json({ elements: this.props.elements });
-  }
-  componentWillReceiveProps(nextProps) {
-    this.cy.json(nextProps);
-  }
-  shouldComponentUpdate() {
-    return false;
-  }
-  componentWillUnmount() {
-    this.cy.destroy();
-  }
-  getCy() {
-    return this.cy;
-  }
-  render() {
-    return <div style={cyStyle} ref={(rel) => { conf.container = rel; }} />;
-  }
-}
-
-export default Topology;
diff --git a/src/main/frontend/src/components/Topology/conf.js b/src/main/frontend/src/components/Topology/conf.js
index 70893f1..abc6614 100644
--- a/src/main/frontend/src/components/Topology/conf.js
+++ b/src/main/frontend/src/components/Topology/conf.js
@@ -1,6 +1,11 @@
 const conf = {
   boxSelectionEnabled: true,
   autounselectify: true,
+  layout: {
+    name: 'cose-bilkent',
+    animate: true,
+    idealEdgeLength: 100,
+  },
 };
 
 export default conf;
diff --git a/src/main/frontend/src/components/Topology/index.js b/src/main/frontend/src/components/Topology/index.js
new file mode 100644
index 0000000..554f2d5
--- /dev/null
+++ b/src/main/frontend/src/components/Topology/index.js
@@ -0,0 +1,5 @@
+import AppTopology from './AppTopology';
+
+export default {
+  AppTopology,
+};
diff --git a/src/main/frontend/src/components/Topology/index.less b/src/main/frontend/src/components/Topology/index.less
new file mode 100644
index 0000000..4dca934
--- /dev/null
+++ b/src/main/frontend/src/components/Topology/index.less
@@ -0,0 +1,17 @@
+.node {
+  text-align: center;
+}
+
+.logo {
+  height: 15px;
+  vertical-align: middle;
+  margin: -3px 2px 0px 0px;
+}
+
+.circle {
+  font-size: 16px;
+}
+
+.alert {
+  color: red;
+}
diff --git a/src/main/frontend/src/models/dashboard.js b/src/main/frontend/src/models/dashboard.js
index 0796d23..f5ba419 100644
--- a/src/main/frontend/src/models/dashboard.js
+++ b/src/main/frontend/src/models/dashboard.js
@@ -18,6 +18,10 @@ export default {
     },
     getTopNSlowService: [],
     getTopNServerThroughput: [],
+    getClusterTopology: {
+      nodes: [],
+      calls: [],
+    },
   },
   effects: {
     *fetch({ payload }, { call, put }) {
diff --git a/src/main/frontend/src/routes/Dashboard/Dashboard.js b/src/main/frontend/src/routes/Dashboard/Dashboard.js
index 3400e24..888d8e8 100644
--- a/src/main/frontend/src/routes/Dashboard/Dashboard.js
+++ b/src/main/frontend/src/routes/Dashboard/Dashboard.js
@@ -5,6 +5,7 @@ import {
   ChartCard, Pie, MiniArea, Field,
 } from '../../components/Charts';
 import { timeRange } from '../../utils/utils';
+import { AppTopology } from '../../components/Topology';
 
 @connect(state => ({
   dashboard: state.dashboard,
@@ -96,7 +97,7 @@ export default class Dashboard extends Component {
           bordered={false}
           bodyStyle={{ padding: 0, marginTop: 24 }}
         >
-          <div style={{ height: 480 }}>Topoloy</div>
+          <AppTopology elements={this.props.dashboard.getClusterTopology} />
         </Card>
         <Row gutter={24}>
           <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>

-- 
To stop receiving notification emails like this one, please contact
['"commits@skywalking.apache.org" <co...@skywalking.apache.org>'].