This is an automated email from the ASF dual-hosted git repository.
hanahmily pushed a commit to branch 6.0.0/dev
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git
The following commit(s) were added to refs/heads/6.0.0/dev by this push:
new 3c29300 Refactor service page with v6
3c29300 is described below
commit 3c293009b56f6ef904fc442d06fe4d1f4dccb2be
Author: Gao Hongtao <[email protected]>
AuthorDate: Tue Sep 11 17:28:35 2018 +0800
Refactor service page with v6
---
.roadhogrc.mock.js | 12 +-
mock/aggregation.js | 2 +
mock/metadata.js | 31 +-
mock/topology.js | 13 +-
src/common/menu.js | 4 +-
src/common/router.js | 4 +-
.../index.js | 39 +--
src/models/application.js | 238 ---------------
src/models/service.js | 333 +++++++++++++++++++++
.../Application.js => Service/Service.js} | 125 ++++----
.../Application.less => Service/Service.less} | 0
.../Server.js => Service/ServiceInstance.js} | 53 ++--
src/utils/utils.js | 23 +-
13 files changed, 499 insertions(+), 378 deletions(-)
diff --git a/.roadhogrc.mock.js b/.roadhogrc.mock.js
index 28819b2..c415afe 100644
--- a/.roadhogrc.mock.js
+++ b/.roadhogrc.mock.js
@@ -1,13 +1,11 @@
import fs from 'fs';
import { delay } from 'roadhog-api-doc';
-import { getTopology, getGlobalTopology, getServiceTopology } from
'./mock/topology';
-import { getAllApplication, getApplication } from './mock/application';
-import { searchServer, getServer } from './mock/server';
+import { getGlobalTopology, getServiceTopology } from './mock/topology';
import { Alarms, getNoticeAlarm, AlarmTrend } from './mock/alarm';
import { TraceBrief, Trace } from './mock/trace'
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';
import { graphql } from 'graphql';
-import { ClusterBrief, getAllServices, searchEndpoint } from './mock/metadata';
+import { ClusterBrief, getServiceInstances, getAllServices, searchEndpoint }
from './mock/metadata';
import { IntValues, Thermodynamic } from './mock/metric';
import { getTopN } from './mock/aggregation';
@@ -17,6 +15,7 @@ const resolvers = {
Query: {
getTopN,
getAllServices,
+ getServiceInstances,
getGlobalTopology,
getServiceTopology,
searchEndpoint,
@@ -54,11 +53,6 @@ const proxy = {
const { query: source, variables: variableValues } = req.body;
graphql({ schema, source, variableValues }).then((result) =>
res.send(result));
},
- 'POST /api/topology': getTopology,
- 'POST /api/application/options': getAllApplication,
- 'POST /api/application': getApplication,
- 'POST /api/server/search': searchServer,
- 'POST /api/server': getServer,
'POST /api/notice': getNoticeAlarm,
'POST /api/login/account': (req, res) => {
const { password, userName } = req.body;
diff --git a/mock/aggregation.js b/mock/aggregation.js
index e03c16a..3047ce3 100644
--- a/mock/aggregation.js
+++ b/mock/aggregation.js
@@ -24,6 +24,8 @@ export default {
array = mockjs.mock({ 'array|10': [{ 'id|+1': 1, name: '@url',
'value|200-1000': 1 }]});
} else if (args.condition.filterScope === 'SERVICE') {
array = mockjs.mock({ 'array|10': [{ 'id|+1': 1, name: '@name',
'value|100-10000': 1 }]});
+ } else if (args.condition.filterScope === 'SERVICE_INSTANCE') {
+ array = mockjs.mock({ 'array|10': [{ 'id|+1': 1, name: '@name',
'value|100-10000': 1 }]});
}
return array.array;
},
diff --git a/mock/metadata.js b/mock/metadata.js
index 12fe2c3..4fdf8d4 100644
--- a/mock/metadata.js
+++ b/mock/metadata.js
@@ -24,8 +24,35 @@ export default {
'numOfDatabase|1-100': 1,
'numOfCache|1-100': 1,
'numOfMQ|1-100': 1,
- })
- ,
+ }),
+ getServiceInstances: () => {
+ const data = mockjs.mock({
+ 'id|1-10': [{
+ 'id|+1': 3,
+ name: '@natural(4, 20)',
+ attributes: [
+ {
+ name: 'os',
+ value: 'LINUX',
+ },
+ {
+ name: 'host',
+ value: 'WORKSAPCE-@name',
+ },
+ {
+ name: 'pid',
+ value: '@natural(4, 20)',
+ },
+ {
+ name: 'ipv4',
+ value: '@ip',
+ },
+ ],
+ 'language|1': ['JAVA', 'RUBY', 'DOTNET'],
+ }], // eslint-disable-line
+ });
+ return data.id;
+ },
getAllServices: () => {
const data = mockjs.mock({
'serviceId|20-50': [{ 'id|+1': 3, name: function() { return
`service-${this.id}`; } }], // eslint-disable-line
diff --git a/mock/topology.js b/mock/topology.js
index fd1fe86..7a82c64 100644
--- a/mock/topology.js
+++ b/mock/topology.js
@@ -26,15 +26,17 @@ export default {
'id|+1': 100,
name: '@url',
'type|1': ['DUBBO', 'USER', 'SPRINGMVC'],
+ isReal: true,
},
],
});
const centerNodes = mockjs.mock({
nodes: [
{
- 'id|+1': 1,
+ 'id|+1': 10,
name: '@url',
'type|1': ['DUBBO', 'tomcat', 'SPRINGMVC'],
+ isReal: true,
},
],
});
@@ -44,6 +46,7 @@ export default {
'id|+1': 200,
name: '@url',
'type|1': ['Oracle', 'MYSQL', 'REDIS'],
+ isReal: false,
},
],
});
@@ -51,18 +54,16 @@ export default {
const nodes = upNodes.nodes.concat(centerNodes.nodes, downNodes.nodes);
const calls = upNodes.nodes.map(node => (mockjs.mock({
source: node.id,
- target: 1,
- 'isAlert|1': true,
+ target: 10,
'callType|1': ['rpc', 'http', 'dubbo'],
'cpm|0-1000': 1,
}))).concat(downNodes.nodes.map(node => (mockjs.mock({
- source: 1,
+ source: 10,
target: node.id,
- 'isAlert|1': true,
'callType|1': ['rpc', 'http', 'dubbo'],
'cpm|0-2000': 1,
}))));
- calls.push({ source: '-175', target: 1, isAlert: false, callType: 'GRPC',
cpm: 0, avgResponseTime: 52 });
+ calls.push({ source: '-175', target: 10, callType: 'GRPC', cpm: 0 });
return {
nodes,
calls,
diff --git a/src/common/menu.js b/src/common/menu.js
index bc98328..eb64c7c 100644
--- a/src/common/menu.js
+++ b/src/common/menu.js
@@ -31,8 +31,8 @@ const menuData = [{
name: 'Topology',
path: 'topology',
}, {
- name: 'Application',
- path: 'application',
+ name: 'Service',
+ path: 'service',
}, {
name: 'Endpoint',
path: 'endpoint',
diff --git a/src/common/router.js b/src/common/router.js
index db30edd..6cbbf87 100644
--- a/src/common/router.js
+++ b/src/common/router.js
@@ -97,8 +97,8 @@ export const getRouterData = (app) => {
'/monitor/topology': {
component: dynamicWrapper(app, ['topology'], () =>
import('../routes/Topology/Topology')),
},
- '/monitor/application': {
- component: dynamicWrapper(app, ['application'], () =>
import('../routes/Application/Application')),
+ '/monitor/service': {
+ component: dynamicWrapper(app, ['service'], () =>
import('../routes/Service/Service')),
},
'/monitor/endpoint': {
component: dynamicWrapper(app, ['endpoint'], () =>
import('../routes/Endpoint/Endpoint')),
diff --git a/src/components/ServerLitePanel/index.js
b/src/components/ServiceInstanceLitePanel/index.js
similarity index 59%
rename from src/components/ServerLitePanel/index.js
rename to src/components/ServiceInstanceLitePanel/index.js
index a3d896c..dbe64ee 100644
--- a/src/components/ServerLitePanel/index.js
+++ b/src/components/ServiceInstanceLitePanel/index.js
@@ -22,55 +22,56 @@ import {
ChartCard, MiniArea, MiniBar,
} from "../Charts";
import DescriptionList from "../DescriptionList";
-import { axis } from '../../utils/time';
-import { avgTimeSeries, getServerId } from '../../utils/utils';
+import { axisY } from '../../utils/time';
+import { avgTS, getAttributes, getServiceInstanceId } from '../../utils/utils';
const { Option } = Select;
const { Description } = DescriptionList;
-export default class ServerLitePanel extends PureComponent {
+export default class ServiceInstanceLitePanel extends PureComponent {
bytesToMB = list => list.map(_ => parseFloat((_ / (1024 ** 2)).toFixed(2)))
render() {
- const { serverList, duration, data, onSelectServer, onMoreServer } =
this.props;
- if (serverList.length < 1) {
+ const { serviceInstanceList, duration, data, onSelectServiceInstance,
onMoreServiceInstance } = this.props;
+ if (serviceInstanceList.length < 1) {
return null;
}
- const { serverInfo, getServerResponseTimeTrend, getServerThroughputTrend }
= data;
- if (!serverInfo.key) {
- onSelectServer(serverList[0].key, serverList[0]);
+ const { serviceInstanceInfo, getServiceInstanceResponseTimeTrend,
getServiceInstanceThroughputTrend } = data;
+ if (!serviceInstanceInfo.key) {
+ onSelectServiceInstance(serviceInstanceList[0].key,
serviceInstanceList[0]);
}
+ const { attributes } = serviceInstanceInfo;
return (
<div>
<Row gutter={0}>
<Col span={24}>
<Select
size="small"
- value={serverInfo.key}
- onChange={value => onSelectServer(value, serverList.find(_ =>
_.key === value))}
+ value={serviceInstanceInfo.key}
+ onChange={value => onSelectServiceInstance(value,
serviceInstanceList.find(_ => _.key === value))}
style={{ width: '100%' }}
>
- {serverList.map(_ => <Option key={_.key}
value={_.key}>{getServerId(_)}</Option>)}
+ {serviceInstanceList.map(_ => <Option key={_.key}
value={_.key}>{getServiceInstanceId(_)}</Option>)}
</Select>
</Col>
<Col span={24}>
<Card bordered={false} bodyStyle={{ padding: 5 }}>
<DescriptionList col={1} gutter={0} size="small">
- <Description term="Host">{serverInfo.host}</Description>
- <Description term="OS">{serverInfo.osName}</Description>
+ <Description term="Host">{getAttributes(attributes,
'host')}</Description>
+ <Description term="OS">{getAttributes(attributes,
'os')}</Description>
</DescriptionList>
</Card>
</Col>
<Col span={24}>
<ChartCard
title="Avg Throughput"
- total={`${avgTimeSeries(getServerThroughputTrend.trendList)}
cpm`}
+ total={`${avgTS(getServiceInstanceThroughputTrend.values)} cpm`}
contentHeight={46}
bordered={false}
bodyStyle={{ padding: 5 }}
>
<MiniBar
- data={axis(duration, getServerThroughputTrend.trendList)}
+ data={axisY(duration,
getServiceInstanceThroughputTrend.values)}
color="#975FE4"
/>
</ChartCard>
@@ -78,22 +79,22 @@ export default class ServerLitePanel extends PureComponent {
<Col span={24}>
<ChartCard
title="Avg Response Time"
- total={`${avgTimeSeries(getServerResponseTimeTrend.trendList)}
ms`}
+ total={`${avgTS(getServiceInstanceResponseTimeTrend.values)} ms`}
contentHeight={46}
bordered={false}
bodyStyle={{ padding: 5 }}
>
- {getServerResponseTimeTrend.trendList.length > 0 ? (
+ {getServiceInstanceResponseTimeTrend.values.length > 0 ? (
<MiniArea
animate={false}
color="#87cefa"
- data={axis(duration, getServerResponseTimeTrend.trendList)}
+ data={axisY(duration,
getServiceInstanceResponseTimeTrend.values)}
/>
) : (<span style={{ display: 'none' }} />)}
</ChartCard>
</Col>
</Row>
- {serverInfo.key ? <a style={{ float: 'right' }}
onClick={onMoreServer}> More Server Details<Icon type="ellipsis" /> </a> : null}
+ {serviceInstanceInfo.key ? <a style={{ float: 'right' }}
onClick={onMoreServiceInstance}> More Server Details<Icon type="ellipsis" />
</a> : null}
</div>
);
}
diff --git a/src/models/application.js b/src/models/application.js
deleted file mode 100644
index cd40b39..0000000
--- a/src/models/application.js
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-import { generateModal } from '../utils/models';
-import { query as queryService } from '../services/graphql';
-
-const optionsQuery = `
- query ApplicationOption($duration: Duration!) {
- applicationId: getAllApplication(duration: $duration) {
- key: id
- label: name
- }
- }
-`;
-
-const dataQuery = `
- query Application($applicationId: ID!, $duration: Duration!) {
- getSlowService(applicationId: $applicationId, duration: $duration, topN:
10) {
- service {
- key: id
- label: name
- applicationId
- applicationName
- }
- value: avgResponseTime
- }
- getServerThroughput(applicationId: $applicationId, duration: $duration,
topN: 999999) {
- key: id
- osName
- host
- pid
- ipv4
- value: cpm
- }
- getApplicationTopology(applicationId: $applicationId, duration: $duration)
{
- nodes {
- id
- name
- type
- ... on ApplicationNode {
- sla
- cpm
- avgResponseTime
- apdex
- isAlarm
- numOfServer
- numOfServerAlarm
- numOfServiceAlarm
- }
- }
- calls {
- source
- target
- isAlert
- callType
- cpm
- avgResponseTime
- }
- }
- }
-`;
-
-const serverQuery = `
-query Application($serverId: ID!, $duration: Duration!) {
- getServerResponseTimeTrend(serverId: $serverId, duration: $duration) {
- trendList
- }
- getServerThroughputTrend(serverId: $serverId, duration: $duration) {
- trendList
- }
- getCPUTrend(serverId: $serverId, duration: $duration) {
- cost
- }
- getGCTrend(serverId: $serverId, duration: $duration) {
- youngGCCount
- oldGCount
- youngGCTime
- oldGCTime
- }
- getMemoryTrend(serverId: $serverId, duration: $duration) {
- heap
- maxHeap
- noheap
- maxNoheap
- }
-}
-`;
-
-export default generateModal({
- namespace: 'application',
- state: {
- allApplication: [],
- getSlowService: [],
- getServerThroughput: [],
- getApplicationTopology: {
- nodes: [],
- calls: [],
- },
- showServer: false,
- serverInfo: {},
- getServerResponseTimeTrend: {
- trendList: [],
- },
- getServerThroughputTrend: {
- trendList: [],
- },
- getCPUTrend: {
- cost: [],
- },
- getMemoryTrend: {
- heap: [],
- maxHeap: [],
- noheap: [],
- maxNoheap: [],
- },
- getGCTrend: {
- youngGCCount: [],
- oldGCount: [],
- youngGCTime: [],
- oldGCTime: [],
- },
- },
- optionsQuery,
- dataQuery,
- effects: {
- *fetchServer({ payload }, { call, put }) {
- const { variables, serverInfo } = payload;
- const response = yield call(queryService, 'server', { variables, query:
serverQuery });
- if (!response.data) {
- return;
- }
- yield put({
- type: 'saveServer',
- payload: response.data,
- serverInfo,
- });
- },
- },
- reducers: {
- saveApplication(preState, { payload }) {
- const { data } = preState;
- return {
- ...preState,
- data: {
- ...data,
- ...payload,
- serverInfo: {},
- getServerResponseTimeTrend: {
- trendList: [],
- },
- getServerThroughputTrend: {
- trendList: [],
- },
- getCPUTrend: {
- cost: [],
- },
- getMemoryTrend: {
- heap: [],
- maxHeap: [],
- noheap: [],
- maxNoheap: [],
- },
- getGCTrend: {
- youngGCCount: [],
- oldGCount: [],
- youngGCTime: [],
- oldGCTime: [],
- },
- },
- };
- },
- saveServer(preState, { payload, serverInfo }) {
- const { data } = preState;
- return {
- ...preState,
- data: {
- ...data,
- serverInfo,
- ...payload,
- },
- };
- },
- showServer(preState) {
- const { data } = preState;
- return {
- ...preState,
- data: {
- ...data,
- showServer: true,
- },
- };
- },
- hideServer(preState) {
- const { data } = preState;
- return {
- ...preState,
- data: {
- ...data,
- showServer: false,
- },
- };
- },
- },
- subscriptions: {
- setup({ history, dispatch }) {
- return history.listen(({ pathname, state }) => {
- if (pathname === '/monitor/application' && state) {
- dispatch({
- type: 'saveVariables',
- payload: {
- values: {
- applicationId: `${state.key}`,
- },
- labels: {
- applicationId: state.label,
- },
- },
- });
- }
- });
- },
- },
-});
diff --git a/src/models/service.js b/src/models/service.js
new file mode 100644
index 0000000..6cb391b
--- /dev/null
+++ b/src/models/service.js
@@ -0,0 +1,333 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import { base } from '../utils/models';
+import { exec } from '../services/graphql';
+
+const optionsQuery = `
+ query ServiceOption($duration: Duration!) {
+ serviceId: getAllServices(duration: $duration) {
+ key: id
+ label: name
+ }
+ }
+`;
+
+const dataQuery = `
+ query Service($serviceId: ID!, $duration: Duration!) {
+ getSlowEndpoint: getTopN(duration: $duration, condition: {
+ name: "slowEndpoint",
+ topN: 10,
+ order: DES,
+ filterScope: ENDPOINT,
+ filterId: $serviceId
+ }) {
+ key: id
+ label: name
+ value
+ }
+ getServiceInstanceThroughput: getTopN(duration: $duration, condition: {
+ name: "serviceInstanceThroughtput",
+ topN: 10,
+ order: DES,
+ filterScope: SERVICE_INSTANCE,
+ filterId: $serviceId
+ }) {
+ key: id
+ label: name
+ value
+ }
+ getServiceInstances(duration: $duration, id: $serviceId) {
+ key: id
+ name
+ attributes {
+ name
+ value
+ }
+ language
+ }
+ getServiceTopology(serviceId: $serviceId, duration: $duration) {
+ nodes {
+ id
+ name
+ type
+ isReal
+ }
+ calls {
+ source
+ target
+ callType
+ cpm
+ }
+ }
+ }
+`;
+
+const serviceInstanceQuery = `
+query ServiceInstance($serviceInstanceId: ID!, $duration: Duration!) {
+ getServiceInstanceResponseTimeTrend: getLinearIntValues(metric: {
+ name: "serviceInstanceResponseTimeTrend"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ getServiceInstanceThroughputTrend: getLinearIntValues(metric: {
+ name: "serviceInstanceThroughputTrend"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ getCPUTrend: getLinearIntValues(metric: {
+ name: "CPUTrend"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ youngGCCount: getLinearIntValues(metric: {
+ name: "youngGCCount"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ oldGCCount: getLinearIntValues(metric: {
+ name: "oldGCCount"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ youngGCTime: getLinearIntValues(metric: {
+ name: "youngGCTime"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ oldGCTime: getLinearIntValues(metric: {
+ name: "oldGCTime"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ heap: getLinearIntValues(metric: {
+ name: "heap"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ maxHeap: getLinearIntValues(metric: {
+ name: "maxHeap"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ noheap: getLinearIntValues(metric: {
+ name: "noheap"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+ maxNoheap: getLinearIntValues(metric: {
+ name: "maxNoheap"
+ id: $serviceInstanceId
+ }, duration: $duration) {
+ values {
+ value
+ }
+ }
+}
+`;
+
+export default base({
+ namespace: 'service',
+ state: {
+ allService: [],
+ getSlowEndpoint: [],
+ getServiceInstanceThroughput: [],
+ getServiceTopology: {
+ nodes: [],
+ calls: [],
+ },
+ getServiceInstances: [],
+ showServiceInstance: false,
+ serviceInstanceInfo: {},
+ getServiceInstanceResponseTimeTrend: {
+ values: [],
+ },
+ getServiceInstanceThroughputTrend: {
+ values: [],
+ },
+ getCPUTrend: {
+ values: [],
+ },
+ heap: {
+ values: [],
+ },
+ maxHeap: {
+ values: [],
+ },
+ noheap: {
+ values: [],
+ },
+ maxNoheap: {
+ values: [],
+ },
+ youngGCCount: {
+ values: [],
+ },
+ oldGCCount: {
+ values: [],
+ },
+ youngGCTime: {
+ values: [],
+ },
+ oldGCTime: {
+ values: [],
+ },
+ },
+ optionsQuery,
+ dataQuery,
+ effects: {
+ *fetchServiceInstance({ payload }, { call, put }) {
+ const { variables, serviceInstanceInfo } = payload;
+ const response = yield call(exec, { variables, query:
serviceInstanceQuery });
+ if (!response.data) {
+ return;
+ }
+ yield put({
+ type: 'saveServiceInstance',
+ payload: response.data,
+ serviceInstanceInfo,
+ });
+ },
+ },
+ reducers: {
+ saveService(preState, { payload }) {
+ const { data } = preState;
+ return {
+ ...preState,
+ data: {
+ ...data,
+ ...payload,
+ serviceInstanceInfo: {},
+ getServiceInstanceResponseTimeTrend: {
+ values: [],
+ },
+ getServiceInstanceThroughputTrend: {
+ values: [],
+ },
+ getCPUTrend: {
+ values: [],
+ },
+ heap: {
+ values: [],
+ },
+ maxHeap: {
+ values: [],
+ },
+ noheap: {
+ values: [],
+ },
+ maxNoheap: {
+ values: [],
+ },
+ youngGCCount: {
+ values: [],
+ },
+ oldGCCount: {
+ values: [],
+ },
+ youngGCTime: {
+ values: [],
+ },
+ oldGCTime: {
+ values: [],
+ },
+ },
+ };
+ },
+ saveServiceInstance(preState, { payload, serviceInstanceInfo }) {
+ const { data } = preState;
+ return {
+ ...preState,
+ data: {
+ ...data,
+ serviceInstanceInfo,
+ ...payload,
+ },
+ };
+ },
+ showServiceInstance(preState) {
+ const { data } = preState;
+ return {
+ ...preState,
+ data: {
+ ...data,
+ showServiceInstance: true,
+ },
+ };
+ },
+ hideServiceInstance(preState) {
+ const { data } = preState;
+ return {
+ ...preState,
+ data: {
+ ...data,
+ showServiceInstance: false,
+ },
+ };
+ },
+ },
+ subscriptions: {
+ setup({ history, dispatch }) {
+ return history.listen(({ pathname, state }) => {
+ if (pathname === '/monitor/service' && state) {
+ dispatch({
+ type: 'saveVariables',
+ payload: {
+ values: {
+ serviceId: `${state.key}`,
+ },
+ labels: {
+ serviceId: state.label,
+ },
+ },
+ });
+ }
+ });
+ },
+ },
+});
diff --git a/src/routes/Application/Application.js
b/src/routes/Service/Service.js
similarity index 60%
rename from src/routes/Application/Application.js
rename to src/routes/Service/Service.js
index 5281f54..07985b9 100644
--- a/src/routes/Application/Application.js
+++ b/src/routes/Service/Service.js
@@ -19,12 +19,12 @@
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Row, Col, Select, Card, Form, Breadcrumb } from 'antd';
-import Server from './Server';
-import { AppTopology } from '../../components/Topology';
-import { Panel } from '../../components/Page';
-import RankList from '../../components/RankList';
-import ServerLitePanel from '../../components/ServerLitePanel';
-import { getServerId, redirect } from '../../utils/utils';
+import { AppTopology } from 'components/Topology';
+import { Panel } from 'components/Page';
+import RankList from 'components/RankList';
+import ServiceInstanceLitePanel from 'components/ServiceInstanceLitePanel';
+import ServiceInstance from './ServiceInstance';
+import { getServiceInstanceId, redirect } from '../../utils/utils';
const { Option } = Select;
const { Item: FormItem } = Form;
@@ -39,24 +39,24 @@ const middleColResponsiveProps = {
};
@connect(state => ({
- application: state.application,
+ service: state.service,
duration: state.global.duration,
globalVariables: state.global.globalVariables,
}))
@Form.create({
mapPropsToFields(props) {
- const { variables: { values, labels } } = props.application;
+ const { variables: { values, labels } } = props.service;
return {
- applicationId: Form.createFormField({
- value: { key: values.applicationId ? values.applicationId : '', label:
labels.applicationId ? labels.applicationId : '' },
+ serviceId: Form.createFormField({
+ value: { key: values.serviceId ? values.serviceId : '', label:
labels.serviceId ? labels.serviceId : '' },
}),
};
},
})
-export default class Application extends PureComponent {
+export default class Service extends PureComponent {
componentDidMount() {
this.props.dispatch({
- type: 'application/initOptions',
+ type: 'service/initOptions',
payload: { variables: this.props.globalVariables },
});
}
@@ -66,71 +66,71 @@ export default class Application extends PureComponent {
return;
}
this.props.dispatch({
- type: 'application/initOptions',
+ type: 'service/initOptions',
payload: { variables: nextProps.globalVariables },
});
}
handleSelect = (selected) => {
this.props.dispatch({
- type: 'application/saveVariables',
+ type: 'service/saveVariables',
payload: {
- values: { applicationId: selected.key },
- labels: { applicationId: selected.label },
+ values: { serviceId: selected.key },
+ labels: { serviceId: selected.label },
},
});
}
handleChange = (variables) => {
- const { data: { serverInfo, showServer } } = this.props.application;
- if (showServer) {
- this.handleSelectServer(serverInfo.key, serverInfo);
+ const { data: { serviceInstanceInfo, showServiceInstance } } =
this.props.service;
+ if (showServiceInstance) {
+ this.handleSelectServiceInstance(serviceInstanceInfo.key,
serviceInstanceInfo);
} else {
this.props.dispatch({
- type: 'application/fetchData',
- payload: { variables, reducer: 'saveApplication' },
+ type: 'service/fetchData',
+ payload: { variables, reducer: 'saveService' },
});
}
}
- handleGoApplication = () => {
+ handleGoService = () => {
this.props.dispatch({
- type: 'application/hideServer',
+ type: 'service/hideServiceInstance',
});
}
- handleGoServer = () => {
+ handleGoServiceInstance = () => {
this.props.dispatch({
- type: 'application/showServer',
+ type: 'service/showServiceInstance',
});
}
- handleSelectServer = (serverId, serverInfo) => {
+ handleSelectServiceInstance = (serviceInstanceId, serviceInstanceInfo) => {
const { globalVariables: { duration } } = this.props;
this.props.dispatch({
- type: 'application/fetchServer',
- payload: { variables: { duration, serverId }, serverInfo },
+ type: 'service/fetchServiceInstance',
+ payload: { variables: { duration, serviceInstanceId },
serviceInstanceInfo },
});
}
renderApp = () => {
const { getFieldDecorator } = this.props.form;
- const { variables: { values, options }, data } = this.props.application;
+ const { variables: { values, options, labels }, data } =
this.props.service;
return (
<div>
<Form layout="inline">
<FormItem>
- {getFieldDecorator('applicationId')(
+ {getFieldDecorator('serviceId')(
<Select
showSearch
optionFilterProp="children"
style={{ width: 200 }}
- placeholder="Select a application"
+ placeholder="Select a service"
labelInValue
onSelect={this.handleSelect.bind(this)}
>
- {options.applicationId && options.applicationId.map(app =>
- <Option key={app.key} value={app.key}>{app.label}</Option>)}
+ {options.serviceId && options.serviceId.map(service =>
+ <Option key={service.key}
value={service.key}>{service.label}</Option>)}
</Select>
)}
</FormItem>
@@ -143,12 +143,12 @@ export default class Application extends PureComponent {
<Row gutter={0}>
<Col {...{ ...middleColResponsiveProps, xl: 16, lg: 12, md: 24 }}>
<Card
- title="Application Map"
+ title="Service Map"
bordered={false}
bodyStyle={{ padding: 0 }}
>
<AppTopology
- elements={data.getApplicationTopology}
+ elements={data.getServiceTopology}
height={335}
layout={{
name: 'dagre',
@@ -163,12 +163,12 @@ export default class Application extends PureComponent {
bordered={false}
bodyStyle={{ padding: '10px 10px', height: 391 }}
>
- <ServerLitePanel
+ <ServiceInstanceLitePanel
data={data}
- serverList={data.getServerThroughput}
+ serviceInstanceList={data.getServiceInstances}
duration={this.props.duration}
- onSelectServer={this.handleSelectServer}
- onMoreServer={this.handleGoServer}
+ onSelectServiceInstance={this.handleSelectServiceInstance}
+ onMoreServiceInstance={this.handleGoServiceInstance}
/>
</Card>
</Col>
@@ -176,43 +176,30 @@ export default class Application extends PureComponent {
<Row gutter={8}>
<Col {...{ ...middleColResponsiveProps, xl: 12, lg: 12, md: 24 }}>
<Card
- title="Running Server"
+ title="Running ServiceInstance"
bordered={false}
bodyStyle={{ padding: 5 }}
>
<RankList
- data={data.getServerThroughput}
- renderLabel={getServerId}
+ data={data.getServiceInstanceThroughput}
renderValue={_ => `${_.value} cpm`}
- renderBadge={_ => ([
- {
- key: 'host',
- label: 'Host',
- value: _.host,
- },
- {
- key: 'os',
- label: 'OS',
- value: _.osName,
- },
- ])}
color="#965fe466"
/>
</Card>
</Col>
<Col {...{ ...middleColResponsiveProps, xl: 12, lg: 12, md: 24 }}>
<Card
- title="Slow Service"
+ title="Slow Endpoint"
bordered={false}
bodyStyle={{ padding: '0px 10px' }}
>
<RankList
- data={data.getSlowService.map(_ => ({ ..._.service, value:
_.value }))}
+ data={data.getSlowEndpoint}
renderValue={_ => `${_.value} ms`}
- onClick={(key, item) => redirect(this.props.history,
'/monitor/service', { key,
+ onClick={(key, item) => redirect(this.props.history,
'/monitor/endpoint', { key,
label: item.label,
- applicationId: item.applicationId,
- applicationName: item.applicationName })}
+ serviceId: values.serviceId,
+ serviceName: labels.serviceId })}
/>
</Card>
</Col>
@@ -223,32 +210,32 @@ export default class Application extends PureComponent {
}
render() {
- const { application, duration } = this.props;
- const { variables, data } = application;
- const { showServer, serverInfo } = data;
+ const { service, duration } = this.props;
+ const { variables, data } = service;
+ const { showServiceInstance, serviceInstanceInfo } = data;
return (
<Row type="flex" justify="start">
- {showServer ? (
- <Col span={showServer ? 24 : 0}>
+ {showServiceInstance ? (
+ <Col span={showServiceInstance ? 24 : 0}>
<Breadcrumb>
<Breadcrumb.Item>
- Application
+ Service
</Breadcrumb.Item>
<Breadcrumb.Item>
- <a
onClick={this.handleGoApplication}>{variables.labels.applicationId}</a>
+ <a
onClick={this.handleGoService}>{variables.labels.serviceId}</a>
</Breadcrumb.Item>
- <Breadcrumb.Item>{getServerId(serverInfo)}</Breadcrumb.Item>
+
<Breadcrumb.Item>{getServiceInstanceId(serviceInstanceInfo)}</Breadcrumb.Item>
</Breadcrumb>
<Panel
variables={variables.values}
globalVariables={this.props.globalVariables}
onChange={this.handleChange}
>
- <Server data={data} duration={duration} />
+ <ServiceInstance data={data} duration={duration} />
</Panel>
</Col>
) : null}
- <Col span={showServer ? 0 : 24}>
+ <Col span={showServiceInstance ? 0 : 24}>
{this.renderApp()}
</Col>
</Row>
diff --git a/src/routes/Application/Application.less
b/src/routes/Service/Service.less
similarity index 100%
rename from src/routes/Application/Application.less
rename to src/routes/Service/Service.less
diff --git a/src/routes/Application/Server.js
b/src/routes/Service/ServiceInstance.js
similarity index 64%
rename from src/routes/Application/Server.js
rename to src/routes/Service/ServiceInstance.js
index f3945ce..fa1cdd2 100644
--- a/src/routes/Application/Server.js
+++ b/src/routes/Service/ServiceInstance.js
@@ -20,31 +20,32 @@ import React, { PureComponent } from 'react';
import { Row, Col, Card, Tag } from 'antd';
import {
ChartCard, MiniArea, MiniBar, Line, Area, StackBar,
-} from '../../components/Charts';
-import DescriptionList from '../../components/DescriptionList';
-import { axis } from '../../utils/time';
-import { avgTimeSeries } from '../../utils/utils';
+} from 'components/Charts';
+import DescriptionList from 'components/DescriptionList';
+import { axisY } from '../../utils/time';
+import { avgTS, getAttributes } from '../../utils/utils';
const { Description } = DescriptionList;
-export default class Server extends PureComponent {
- bytesToMB = list => list.map(_ => parseFloat((_ / (1024 ** 2)).toFixed(2)))
+export default class ServiceInstance extends PureComponent {
+ bytesToMB = list => list.map(_ => ({ value: parseFloat((_.value / (1024 **
2)).toFixed(2))}))
render() {
const { duration, data } = this.props;
- const { serverInfo, getServerResponseTimeTrend, getServerThroughputTrend,
- getCPUTrend, getMemoryTrend, getGCTrend } = data;
+ const { serviceInstanceInfo, getServiceInstanceResponseTimeTrend,
getServiceInstanceThroughputTrend,
+ getCPUTrend, heap, maxHeap, noheap, maxNoheap, youngGCCount, oldGCCount,
youngGCTime, oldGCTime } = data;
+ const { attributes } = serviceInstanceInfo;
return (
<div>
<Row gutter={8}>
<Col xs={24} sm={24} md={24} lg={6} xl={6} style={{ marginTop: 8 }}>
<Card style={{ marginTop: 8 }} bordered={false}>
<DescriptionList col={1} layout="vertical">
- <Description term="Host">{serverInfo.host}</Description>
- <Description term="IPv4">{serverInfo.ipv4 ?
serverInfo.ipv4.join() : ''}</Description>
- <Description term="Pid">{serverInfo.pid}</Description>
- <Description term="OS">{serverInfo.osName}</Description>
+ <Description term="Host">{getAttributes(attributes,
'host')}</Description>
+ <Description term="IPv4">{getAttributes(attributes,
'ipv4')}</Description>
+ <Description term="Pid">{getAttributes(attributes,
'pid')}</Description>
+ <Description term="OS">{getAttributes(attributes,
'os')}</Description>
</DescriptionList>
</Card>
</Col>
@@ -53,24 +54,24 @@ export default class Server extends PureComponent {
<Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop:
8 }}>
<ChartCard
title="Avg Throughput"
- total={`${avgTimeSeries(getServerThroughputTrend.trendList)}
cpm`}
+ total={`${avgTS(getServiceInstanceThroughputTrend.values)}
cpm`}
contentHeight={46}
>
<MiniBar
color="#975FE4"
- data={axis(duration, getServerThroughputTrend.trendList)}
+ data={axisY(duration,
getServiceInstanceThroughputTrend.values)}
/>
</ChartCard>
</Col>
<Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop:
8 }}>
<ChartCard
title="Avg Response Time"
-
total={`${avgTimeSeries(getServerResponseTimeTrend.trendList)} ms`}
+ total={`${avgTS(getServiceInstanceResponseTimeTrend.values)}
ms`}
contentHeight={46}
>
- {getServerResponseTimeTrend.trendList.length > 0 ? (
+ {getServiceInstanceResponseTimeTrend.values.length > 0 ? (
<MiniArea
- data={axis(duration,
getServerResponseTimeTrend.trendList)}
+ data={axisY(duration,
getServiceInstanceResponseTimeTrend.values)}
/>
) : (<span style={{ display: 'none' }} />)}
</ChartCard>
@@ -83,7 +84,7 @@ export default class Server extends PureComponent {
contentHeight={150}
>
<Line
- data={axis(duration, getCPUTrend.cost)}
+ data={axisY(duration, getCPUTrend.values)}
/>
</ChartCard>
</Col>
@@ -95,8 +96,8 @@ export default class Server extends PureComponent {
contentHeight={150}
>
<Area
- data={axis(duration, this.bytesToMB(getMemoryTrend.heap),
({ x, y }) => ({ x, y, type: 'value' }))
- .concat(axis(duration,
this.bytesToMB(getMemoryTrend.maxHeap), ({ x, y }) => ({ x, y, type: 'free'
})))}
+ data={axisY(duration, this.bytesToMB(heap.values), ({ x, y
}) => ({ x, y, type: 'value' }))
+ .concat(axisY(duration, this.bytesToMB(maxHeap.values),
({ x, y }) => ({ x, y, type: 'free' })))}
/>
</ChartCard>
</Col>
@@ -106,8 +107,8 @@ export default class Server extends PureComponent {
contentHeight={150}
>
<Area
- data={axis(duration,
this.bytesToMB(getMemoryTrend.noheap), ({ x, y }) => ({ x, y, type: 'value' }))
- .concat(axis(duration,
this.bytesToMB(getMemoryTrend.maxNoheap), ({ x, y }) => ({ x, y, type: 'free'
})))}
+ data={axisY(duration, this.bytesToMB(noheap.values), ({ x,
y }) => ({ x, y, type: 'value' }))
+ .concat(axisY(duration, this.bytesToMB(maxNoheap.values),
({ x, y }) => ({ x, y, type: 'free' })))}
/>
</ChartCard>
</Col>
@@ -122,14 +123,14 @@ export default class Server extends PureComponent {
<div style={{ marginBottom: 10 }}>
<span style={{ marginRight: 10 }}>Young GC</span>
<Tag color="#66b5ff">
- {getGCTrend.youngGCCount.reduce((sum, v) => sum + v)}
+ {youngGCCount.values.map(_ => _.value).reduce((sum,
v) => sum + v)}
</Tag>
<span>collections</span>
</div>
<div>
<span style={{ marginRight: 10 }}>Old GC</span>
<Tag color="#ffb566">
- {getGCTrend.oldGCount.reduce((sum, v) => sum + v)}
+ {oldGCCount.values.map(_ => _.value).reduce((sum, v)
=> sum + v)}
</Tag>
<span>collections</span>
</div>
@@ -137,8 +138,8 @@ export default class Server extends PureComponent {
}
>
<StackBar
- data={axis(duration, getGCTrend.youngGCTime, ({ x, y }) =>
({ x, y, type: 'youngGCTime' }))
- .concat(axis(duration, getGCTrend.oldGCTime, ({ x, y }) =>
({ x, y, type: 'oldGCTime' })))}
+ data={axisY(duration, youngGCTime.values, ({ x, y }) => ({
x, y, type: 'youngGCTime' }))
+ .concat(axisY(duration, oldGCTime.values, ({ x, y }) => ({
x, y, type: 'oldGCTime' })))}
/>
</ChartCard>
</Col>
diff --git a/src/utils/utils.js b/src/utils/utils.js
index d6c4e3b..130dd1c 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -114,12 +114,25 @@ export function isUrl(path) {
return reg.test(path);
}
-export function getServerId(serverInfo) {
- let { host } = serverInfo;
- if (serverInfo.ipv4 && serverInfo.ipv4.length > 0) {
- [host] = serverInfo.ipv4;
+export function getServiceInstanceId(serviceInstanceInfo) {
+ const { attributes } = serviceInstanceInfo;
+ if (!attributes || attributes.length < 1) {
+ return '';
}
- return `${serverInfo.pid}@${host}`;
+ let host = getAttributes(attributes, 'host');
+ const ipv4 = getAttributes(attributes, 'ipv4');
+ if (ipv4 && ipv4.length > 0) {
+ [host] = ipv4;
+ }
+ return `${getAttributes(attributes, 'pid')}@${host}`;
+}
+
+export function getAttributes(attributes, name) {
+ if (!attributes || attributes.length < 1) {
+ return '';
+ }
+ const a = attributes.find(_ => _.name === name);
+ return a ? a.value : '';
}
export function redirect(history, pathname, param) {