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/29 10:11:37 UTC
[incubator-skywalking-ui] branch feature/5.0.0 updated: Add
searching server
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 9c2d42b Add searching server
9c2d42b is described below
commit 9c2d42b04aa9ee5f977f06d0d2ff137d73d4c97b
Author: hanahmily <ha...@gmail.com>
AuthorDate: Mon Jan 29 18:10:46 2018 +0800
Add searching server
---
src/main/frontend/.roadhogrc.mock.js | 3 +-
src/main/frontend/mock/server.js | 19 +-
.../frontend/src/components/Page/Search/index.js | 68 +++++
src/main/frontend/src/components/Page/index.js | 2 +
src/main/frontend/src/models/server.js | 49 ++--
src/main/frontend/src/routes/Server/Server.js | 278 +++++++++++----------
6 files changed, 261 insertions(+), 158 deletions(-)
diff --git a/src/main/frontend/.roadhogrc.mock.js b/src/main/frontend/.roadhogrc.mock.js
index ac3c99b..cda4953 100644
--- a/src/main/frontend/.roadhogrc.mock.js
+++ b/src/main/frontend/.roadhogrc.mock.js
@@ -6,7 +6,7 @@ import { delay } from 'roadhog-api-doc';
import { getDashboard } from './mock/dashboard';
import { getTopology } from './mock/topology';
import { getAllApplication, getApplication } from './mock/application';
-import { getServer } from './mock/server';
+import { searchServer, getServer } from './mock/server';
import { getService } from './mock/service';
import { getAlarm } from './mock/alarm';
import { getTrace, getSpans } from './mock/trace'
@@ -21,6 +21,7 @@ const proxy = {
'POST /api/topology': getTopology,
'POST /api/application/all': getAllApplication,
'POST /api/application': getApplication,
+ 'POST /api/server/search': searchServer,
'POST /api/server': getServer,
'POST /api/service': getService,
'POST /api/alert': getAlarm,
diff --git a/src/main/frontend/mock/server.js b/src/main/frontend/mock/server.js
index fab3ec6..cb85394 100644
--- a/src/main/frontend/mock/server.js
+++ b/src/main/frontend/mock/server.js
@@ -1,11 +1,28 @@
import mockjs from 'mockjs';
export default {
+ searchServer(req, res) {
+ res.json(mockjs.mock(
+ {
+ data: {
+ 'searchServer|5': [
+ {
+ 'key|+1': 3,
+ label: function() { return `server-${this.key}`; },
+ os: 'Mac-@name',
+ host: 'WORKSAPCE-@name',
+ pid: '@natural',
+ ipv4: '@ip',
+ },
+ ],
+ },
+ }
+ ));
+ },
getServer(req, res) {
res.json(mockjs.mock(
{
data: {
- 'searchServer|5': [{}],
getServerResponseTimeTrend: {
'trendList|60': ['@natural(100, 1000)'],
},
diff --git a/src/main/frontend/src/components/Page/Search/index.js b/src/main/frontend/src/components/Page/Search/index.js
new file mode 100644
index 0000000..391dc47
--- /dev/null
+++ b/src/main/frontend/src/components/Page/Search/index.js
@@ -0,0 +1,68 @@
+import React, { PureComponent } from 'react';
+import { Select, Spin } from 'antd';
+import debounce from 'lodash.debounce';
+import request from '../../../utils/request';
+
+const { Option } = Select;
+
+export default class Search extends PureComponent {
+ constructor(props) {
+ super(props);
+ this.lastFetchId = 0;
+ this.fetchServer = debounce(this.fetchServer, 800);
+ }
+ state = {
+ data: [],
+ fetching: false,
+ }
+ fetchServer = (value) => {
+ if (!value || value.length < 1) {
+ return;
+ }
+ const { url, query } = this.props;
+ this.lastFetchId += 1;
+ const fetchId = this.lastFetchId;
+ this.setState({ data: [], fetching: true });
+ request(`/api${url}`, {
+ method: 'POST',
+ body: {
+ variables: {
+ keyword: value,
+ },
+ query,
+ },
+ })
+ .then()
+ .then((body) => {
+ if (fetchId !== this.lastFetchId) { // for fetch callback order
+ return;
+ }
+ this.setState({ data: body.data.searchServer, fetching: false });
+ });
+ }
+ handleSelect = (value) => {
+ const { onSelect } = this.props;
+ const selected = this.state.data.find(_ => _.key === value.key);
+ onSelect(selected);
+ }
+ render() {
+ const { placeholder, value } = this.props;
+ return (
+ <Select
+ showSearch
+ style={{ width: 400 }}
+ placeholder={placeholder}
+ notFoundContent={this.state.fetching ? <Spin size="small" /> : null}
+ filterOption={false}
+ labelInValue
+ onSelect={this.handleSelect.bind(this)}
+ onSearch={this.fetchServer}
+ value={value}
+ >
+ {this.state.data.map((_) => {
+ return (<Option value={_.key}>{_.label}</Option>);
+ })}
+ </Select>
+ );
+ }
+}
diff --git a/src/main/frontend/src/components/Page/index.js b/src/main/frontend/src/components/Page/index.js
index 9d40e75..b0c81f5 100644
--- a/src/main/frontend/src/components/Page/index.js
+++ b/src/main/frontend/src/components/Page/index.js
@@ -1,5 +1,7 @@
import Panel from './Panel';
+import Search from './Search';
export default {
Panel,
+ Search,
};
diff --git a/src/main/frontend/src/models/server.js b/src/main/frontend/src/models/server.js
index 8f13809..415fc51 100644
--- a/src/main/frontend/src/models/server.js
+++ b/src/main/frontend/src/models/server.js
@@ -1,6 +1,30 @@
-import { query } from '../services/graphql';
+import { generateModal } from '../utils/utils';
-export default {
+const dataQuery = `
+ query Application($serverId: ID!, $duration: Duration!) {
+ getServerResponseTimeTrend(serverId: $serverId, duration: $duration) {
+ trendList
+ }
+ getServerTPSTrend(serverId: $serverId, duration: $duration) {
+ trendList
+ }
+ getCPUTrend(serverId: $serverId, duration: $duration) {
+ cost
+ }
+ getGCTrend(serverId: $serverId, duration: $duration) {
+ youngGC
+ oldGC
+ }
+ getMemoryTrend(serverId: $serverId, duration: $duration) {
+ heap
+ maxHeap
+ noheap
+ maxNoheap
+ }
+ }
+`;
+
+export default generateModal({
namespace: 'server',
state: {
searchServer: [],
@@ -24,22 +48,5 @@ export default {
oldGC: [],
},
},
- effects: {
- *fetch({ payload }, { call, put }) {
- const response = yield call(query, 'server', payload);
- yield put({
- type: 'save',
- payload: response,
- });
- },
- },
-
- reducers: {
- save(state, action) {
- return {
- ...state,
- ...action.payload.data,
- };
- },
- },
-};
+ dataQuery,
+});
diff --git a/src/main/frontend/src/routes/Server/Server.js b/src/main/frontend/src/routes/Server/Server.js
index 4cb2f58..e741607 100644
--- a/src/main/frontend/src/routes/Server/Server.js
+++ b/src/main/frontend/src/routes/Server/Server.js
@@ -1,179 +1,187 @@
-import React, { Component } from 'react';
+import React, { PureComponent } from 'react';
import { connect } from 'dva';
-import { Row, Col, Select, Card, Form } from 'antd';
+import { Row, Col, Card, Form } from 'antd';
import {
ChartCard, MiniArea, MiniBar, Line, Area, StackBar,
} from '../../components/Charts';
import DescriptionList from '../../components/DescriptionList';
import { timeRange } from '../../utils/utils';
+import { Panel, Search } from '../../components/Page';
const { Description } = DescriptionList;
-const { Option } = Select;
const { Item: FormItem } = Form;
@connect(state => ({
server: state.server,
duration: state.global.duration,
+ globalVariables: state.global.globalVariables,
}))
@Form.create({
- mapPropsToFields() {
+ mapPropsToFields(props) {
+ const { variables: { values, labels: { serverId = {} } } } = props.server;
return {
serverId: Form.createFormField({
- value: 'Server1',
+ value: { key: values.serverId, label: serverId.label },
}),
};
},
})
-export default class Server extends Component {
- componentDidMount() {
- this.props.form.validateFields((err, values) => {
- if (!err) {
- this.handleChange(values.serverId);
- }
+export default class Server extends PureComponent {
+ handleSelect = (selected) => {
+ this.props.dispatch({
+ type: 'server/saveVariables',
+ payload: {
+ values: { serverId: selected.key },
+ labels: { serverId: selected },
+ },
});
}
- shouldComponentUpdate(nextProps) {
- if (this.props.duration !== nextProps.duration) {
- this.props.dispatch({
- type: 'server/fetch',
- payload: {},
- });
- }
- return this.props.server !== nextProps.server;
- }
- handleChange(serverId) {
+ handleChange = (variables) => {
this.props.dispatch({
- type: 'server/fetch',
- payload: { serverId },
+ type: 'server/fetchData',
+ payload: { variables },
});
}
avg = list => (list.length > 0 ?
(list.reduce((acc, curr) => acc + curr) / list.length).toFixed(2) : 0)
render() {
const { getFieldDecorator } = this.props.form;
+ const { variables: { values, labels: { serverId = {} } }, data } = this.props.server;
const { getServerResponseTimeTrend, getServerTPSTrend,
- getCPUTrend, getMemoryTrend, getGCTrend } = this.props.server;
+ getCPUTrend, getMemoryTrend, getGCTrend } = data;
const timeRangeArray = timeRange(this.props.duration);
return (
<div>
<Form layout="inline">
<FormItem>
{getFieldDecorator('serverId')(
- <Select
- showSearch
- style={{ width: 200 }}
+ <Search
placeholder="Select a server"
- optionFilterProp="children"
- onChange={this.handleChange.bind(this)}
- >
- <Option value="Server1">Server1</Option>
- <Option value="Server2">Server2</Option>
- <Option value="Server3">Server3</Option>
- </Select>
+ onSelect={this.handleSelect.bind(this)}
+ url="/server/search"
+ query={`
+ query SearchServer($keyword: String!, $duration: Duration!) {
+ searchServer(keyword: $keyword, duration: $duration) {
+ key: id
+ label: name
+ os
+ host
+ pid
+ ipv4
+ }
+ }
+ `}
+ />
)}
</FormItem>
</Form>
- <Card title="Info" style={{ marginTop: 24 }} bordered={false}>
- <DescriptionList>
- <Description term="OS Name">Mac OS X</Description>
- <Description term="Host Name">hanahmily</Description>
- <Description term="Process Id">21144</Description>
- <Description term="IPv4">192.168.1.4</Description>
- </DescriptionList>
- </Card>
- <Row gutter={24}>
- <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
- <ChartCard
- title="Avg Response Time"
- total={`${this.avg(getServerResponseTimeTrend.trendList)} ms`}
- >
- <MiniArea
- animate={false}
- color="#975FE4"
- height={46}
- data={getServerResponseTimeTrend.trendList
- .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
- />
- </ChartCard>
- </Col>
- <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
- <ChartCard
- title="Avg TPS"
- total={`${this.avg(getServerTPSTrend.trendList)} ms`}
- >
- <MiniBar
- animate={false}
- height={46}
- data={getServerTPSTrend.trendList
- .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
- />
- </ChartCard>
- </Col>
- </Row>
- <Row gutter={24}>
- <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
- <Card
- title="CPU"
- bordered={false}
- bodyStyle={{ padding: 0 }}
- >
- <Line
- height={250}
- data={getCPUTrend.cost
- .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
- />
- </Card>
- </Col>
- </Row>
- <Row gutter={24}>
- <Col xs={24} sm={24} md={12} lg={12} xl={12} style={{ marginTop: 24 }}>
- <Card
- title="Heap"
- bordered={false}
- bodyStyle={{ padding: 0 }}
- >
- <Area
- height={250}
- data={getMemoryTrend.heap
- .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'value' }))
- .concat(getMemoryTrend.maxHeap
- .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'limit ' })))}
- />
- </Card>
- </Col>
- <Col xs={24} sm={24} md={12} lg={12} xl={12} style={{ marginTop: 24 }}>
- <Card
- title="No-Heap"
- bordered={false}
- bodyStyle={{ padding: 0 }}
- >
- <Area
- height={250}
- data={getMemoryTrend.noheap
- .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'value' }))
- .concat(getMemoryTrend.maxNoheap
- .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'limit ' })))}
- />
- </Card>
- </Col>
- </Row>
- <Row gutter={24}>
- <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
- <Card
- title="GC"
- bordered={false}
- bodyStyle={{ padding: 0 }}
- >
- <StackBar
- height={250}
- data={getGCTrend.oldGC
- .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'oldGC' }))
- .concat(getGCTrend.youngGC
- .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'youngGC' })))}
- />
- </Card>
- </Col>
- </Row>
+ <Panel
+ variables={values}
+ globalVariables={this.props.globalVariables}
+ onChange={this.handleChange}
+ >
+ <Card title="Info" style={{ marginTop: 24 }} bordered={false}>
+ <DescriptionList>
+ <Description term="OS Name">{serverId.os}</Description>
+ <Description term="Host Name">{serverId.host}</Description>
+ <Description term="Process Id">{serverId.pid}</Description>
+ <Description term="IPv4">{serverId.ipv4}</Description>
+ </DescriptionList>
+ </Card>
+ <Row gutter={24}>
+ <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
+ <ChartCard
+ title="Avg Response Time"
+ total={`${this.avg(getServerResponseTimeTrend.trendList)} ms`}
+ >
+ <MiniArea
+ animate={false}
+ color="#975FE4"
+ height={46}
+ data={getServerResponseTimeTrend.trendList
+ .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
+ />
+ </ChartCard>
+ </Col>
+ <Col xs={24} sm={24} md={24} lg={12} xl={12} style={{ marginTop: 24 }}>
+ <ChartCard
+ title="Avg TPS"
+ total={`${this.avg(getServerTPSTrend.trendList)} ms`}
+ >
+ <MiniBar
+ animate={false}
+ height={46}
+ data={getServerTPSTrend.trendList
+ .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
+ />
+ </ChartCard>
+ </Col>
+ </Row>
+ <Row gutter={24}>
+ <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
+ <Card
+ title="CPU"
+ bordered={false}
+ bodyStyle={{ padding: 0 }}
+ >
+ <Line
+ height={250}
+ data={getCPUTrend.cost
+ .map((v, i) => { return { x: timeRangeArray[i], y: v }; })}
+ />
+ </Card>
+ </Col>
+ </Row>
+ <Row gutter={24}>
+ <Col xs={24} sm={24} md={12} lg={12} xl={12} style={{ marginTop: 24 }}>
+ <Card
+ title="Heap"
+ bordered={false}
+ bodyStyle={{ padding: 0 }}
+ >
+ <Area
+ height={250}
+ data={getMemoryTrend.heap
+ .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'value' }))
+ .concat(getMemoryTrend.maxHeap
+ .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'limit ' })))}
+ />
+ </Card>
+ </Col>
+ <Col xs={24} sm={24} md={12} lg={12} xl={12} style={{ marginTop: 24 }}>
+ <Card
+ title="No-Heap"
+ bordered={false}
+ bodyStyle={{ padding: 0 }}
+ >
+ <Area
+ height={250}
+ data={getMemoryTrend.noheap
+ .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'value' }))
+ .concat(getMemoryTrend.maxNoheap
+ .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'limit ' })))}
+ />
+ </Card>
+ </Col>
+ </Row>
+ <Row gutter={24}>
+ <Col xs={24} sm={24} md={24} lg={24} xl={24} style={{ marginTop: 24 }}>
+ <Card
+ title="GC"
+ bordered={false}
+ bodyStyle={{ padding: 0 }}
+ >
+ <StackBar
+ height={250}
+ data={getGCTrend.oldGC
+ .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'oldGC' }))
+ .concat(getGCTrend.youngGC
+ .map((v, i) => ({ x: timeRangeArray[i], y: v, type: 'youngGC' })))}
+ />
+ </Card>
+ </Col>
+ </Row>
+ </Panel>
</div>
);
}
--
To stop receiving notification emails like this one, please contact
hanahmily@apache.org.