You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2019/02/22 16:06:13 UTC
[incubator-skywalking-ui] branch master updated: Feature: Add
serviceInstance Search Support (#233)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-ui.git
The following commit(s) were added to refs/heads/master by this push:
new 8b5e69c Feature: Add serviceInstance Search Support (#233)
8b5e69c is described below
commit 8b5e69c4513ff352dcaf6346b024dc781e2c2d8c
Author: Allen Wang <Al...@outlook.com>
AuthorDate: Sat Feb 23 00:06:09 2019 +0800
Feature: Add serviceInstance Search Support (#233)
---
.roadhogrc.mock.js | 2 +-
mock/trace.js | 7 ++++
src/models/trace.js | 27 ++++++++++++
src/routes/Trace/TraceSearch.js | 92 +++++++++++++++++++++++++++++++++++------
4 files changed, 114 insertions(+), 14 deletions(-)
diff --git a/.roadhogrc.mock.js b/.roadhogrc.mock.js
index 1de7bd0..e59d3b2 100644
--- a/.roadhogrc.mock.js
+++ b/.roadhogrc.mock.js
@@ -33,7 +33,7 @@ const schema = makeExecutableSchema({ typeDefs: [
"scalar Long",
fs.readFileSync('query-protocol/common.graphqls', 'utf8'),
fs.readFileSync('query-protocol/metadata.graphqls', 'utf8'),
- fs.readFileSync('query-protocol/database.graphqls', 'utf8'),
+ fs.readFileSync('query-protocol/top-n-records.graphqls', 'utf8'),
fs.readFileSync('query-protocol/alarm.graphqls', 'utf8'),
fs.readFileSync('query-protocol/metric.graphqls', 'utf8'),
fs.readFileSync('query-protocol/aggregation.graphqls', 'utf8'),
diff --git a/mock/trace.js b/mock/trace.js
index 93867b0..bdd79e4 100644
--- a/mock/trace.js
+++ b/mock/trace.js
@@ -19,6 +19,13 @@
import mockjs from 'mockjs';
export default {
+
+ getServiceInstances: () => {
+ const data = mockjs.mock({
+ 'instanceId|20-50': [{ 'id|+1': 3, name: function() { return `service-${this.id}`; } }], // eslint-disable-line
+ });
+ return data.instanceId;
+ },
TraceBrief: () => {
let offset = 0;
return mockjs.mock({
diff --git a/src/models/trace.js b/src/models/trace.js
index 9b2f8c4..bb2485d 100644
--- a/src/models/trace.js
+++ b/src/models/trace.js
@@ -29,6 +29,15 @@ const optionsQuery = `
}
`;
+const serviceInstanceQuery = `
+ query ServiceInstanceOption($duration: Duration!, $serviceId: ID!) {
+ instanceId: getServiceInstances(duration: $duration, serviceId: $serviceId) {
+ key: id
+ label: name
+ }
+ }
+`;
+
const dataQuery = `
query BasicTraces($condition: TraceQueryCondition) {
queryBasicTraces(condition: $condition) {
@@ -85,6 +94,7 @@ const spanQuery = `query Spans($traceId: ID!) {
export default base({
namespace: 'trace',
state: {
+ instances: [],
queryBasicTraces: {
traces: [],
total: 0,
@@ -116,6 +126,13 @@ export default base({
},
dataQuery,
effects: {
+ *fetchInstances({ payload }, { call, put }) {
+ const response = yield call(exec, { query: serviceInstanceQuery, variables: payload.variables });
+ yield put({
+ type: 'saveInstances',
+ payload: response,
+ });
+ },
*fetchSpans({ payload }, { call, put }) {
const response = yield call(exec, { query: spanQuery, variables: payload.variables });
yield put({
@@ -138,6 +155,16 @@ export default base({
},
};
},
+ saveInstances(state, { payload }) {
+ const { data } = state;
+ return {
+ ...state,
+ data: {
+ ...data,
+ instances: payload.data.instanceId,
+ },
+ };
+ },
hideTimeline(state) {
const { data } = state;
return {
diff --git a/src/routes/Trace/TraceSearch.js b/src/routes/Trace/TraceSearch.js
index 5b40633..4448304 100644
--- a/src/routes/Trace/TraceSearch.js
+++ b/src/routes/Trace/TraceSearch.js
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import React, { PureComponent } from 'react';
+import React, { Component } from 'react';
import { Form, Input, Select, Button, Card, InputNumber, Row, Col, Pagination, DatePicker,notification } from 'antd';
import { Chart, Geom, Axis, Tooltip, Legend } from 'bizcharts';
import { DataSet } from '@antv/data-set';
@@ -51,7 +51,15 @@ const initPaging = {
return result;
},
})
-export default class Trace extends PureComponent {
+export default class Trace extends Component {
+ constructor(props){
+ super(props);
+ this.state = {
+ serviceId: '',
+ serviceInstanceId: '',
+ }
+ }
+
componentDidMount() {
this.timer = false;
const {...propsData} = this.props;
@@ -118,12 +126,20 @@ export default class Trace extends PureComponent {
fetchData = (queryCondition, paging = initPaging) => {
const {...propsData} = this.props;
+ const { serviceId, serviceInstanceId } = this.state;
+ const newData = {...queryCondition, serviceId, serviceInstanceId}
+ if (!serviceId) {
+ delete newData.serviceId;
+ }
+ if (!serviceInstanceId) {
+ delete newData.serviceInstanceId;
+ }
propsData.dispatch({
type: 'trace/fetchData',
payload: {
variables: {
condition: {
- ...queryCondition,
+ ...newData,
paging,
},
},
@@ -161,6 +177,42 @@ export default class Trace extends PureComponent {
});
}
+ handleSelectInstance = (serviceInstanceId) => {
+ this.setState({ serviceInstanceId });
+ }
+
+ handleRefreshServiceInstances = () => {
+ const { dispatch } = this.props;
+ const { ...propsData } = this.props;
+ const { serviceId } = this.state;
+ propsData.form.validateFields((err, fieldsValue) => {
+ if (err || !serviceId) return;
+ const rangeTime = fieldsValue['range-time-picker'];
+ const duration = generateDuration({ from: () => rangeTime[0], to: () => rangeTime[1] }).input;
+ dispatch({
+ type: 'trace/fetchInstances',
+ payload: { variables: { duration, serviceId } },
+ });
+ });
+ return true;
+ }
+
+ handleShowServiceInstances = (serviceId) => {
+ const { dispatch } = this.props;
+ const { ...propsData } = this.props;
+ this.setState({ serviceId });
+ propsData.form.validateFields((err, fieldsValue) => {
+ if (err || !serviceId) return;
+ const rangeTime = fieldsValue['range-time-picker'];
+ const duration = generateDuration({ from: () => rangeTime[0], to: () => rangeTime[1] }).input;
+ dispatch({
+ type: 'trace/fetchInstances',
+ payload: { variables: { duration, serviceId } },
+ });
+ });
+ return true;
+ }
+
renderPointChart = (traces) => {
if (!traces) {
return null;
@@ -240,6 +292,7 @@ export default class Trace extends PureComponent {
}],
})(
<RangePicker
+ onCalendarChange={this.handleRefreshServiceInstances}
showTime
disabledDate={current => current && current.valueOf() >= Date.now()}
format="YYYY-MM-DD HH:mm"
@@ -248,16 +301,29 @@ export default class Trace extends PureComponent {
)}
</FormItem>
<FormItem label="Service">
- {getFieldDecorator('serviceId')(
- <Select placeholder="All service" style={{ width: '100%' }}>
- {options.serviceId && options.serviceId.map((service) => {
- return (
- <Option key={service.key ? service.key : -1} value={service.key}>
- {service.label}
- </Option>);
- })}
- </Select>
- )}
+ <Select placeholder="All services" onChange={this.handleShowServiceInstances} style={{ width: '100%' }}>
+ {options.serviceId && options.serviceId.map((service) => {
+ if (service.key) {
+ return (
+ <Option key={service.key ? service.key : -1} value={service.key? service.key : ''}>
+ {service.label}
+ </Option>);
+ }
+ return (
+ <Option value="">All Services</Option>
+ )})}
+ </Select>
+ </FormItem>
+ <FormItem label="ServiceInstance">
+ <Select placeholder="All Service Instances" onChange={this.handleSelectInstance} style={{ width: '100%' }}>
+ <Option value="">All Service Instances</Option>
+ {propsData.trace.data.instances && propsData.trace.data.instances.map((instance) => {
+ return (
+ <Option key={instance.key ? instance.key : -1} value={instance.key}>
+ {instance.label}
+ </Option>);
+ })}
+ </Select>
</FormItem>
<FormItem label="Trace State">
{getFieldDecorator('traceState')(