This is an automated email from the ASF dual-hosted git repository. ywang pushed a commit to branch new in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-query-protocol.git
commit ebbeb721d95bba8ee63bc2e706e877ee3a56433e Author: Wu Sheng <wu.sh...@foxmail.com> AuthorDate: Mon Sep 3 16:19:58 2018 +0800 Init query protocol repo. --- README.md | 5 +++ aggregation.graphqls | 45 ++++++++++++++++++++ alarm.graphqls | 36 ++++++++++++++++ common.graphqls | 93 ++++++++++++++++++++++++++++++++++++++++ metadata.graphqls | 62 +++++++++++++++++++++++++++ metric.graphqls | 61 ++++++++++++++++++++++++++ topology.graphqls | 64 ++++++++++++++++++++++++++++ trace.graphqls | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 484 insertions(+) diff --git a/README.md b/README.md new file mode 100644 index 0000000..6b409ef --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Apache SkyWalking Query Protocol +The Query protocol of SkyWalking in GraphQL format. + +# License +Apache 2.0 diff --git a/aggregation.graphqls b/aggregation.graphqls new file mode 100644 index 0000000..90ade73 --- /dev/null +++ b/aggregation.graphqls @@ -0,0 +1,45 @@ +# 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. + +# Match the metric by name, order by metric value(such as: avg, percent) +input TopNCondition { + name: String! + topN: Int! + order: Order! + # When the scope is ServiceInstance or Endpoint, + # most likely you need a secondary filter. + # Such as: + # 1. Get topN service instance in a given service id + # 2. Get topN endpoint in a given serivce id. + # Backend will decide the filter id meaning by Scope. + # + # Defintely, it is not required by default. + filterScope: Scope + filterId: Int +} + +type TopNEntity { + name: String! + id: ID! + value: Int! +} + +# The aggregation query is different with the metric query. +# All aggregation queries require backend or/and storage do aggregation in query time. +extend type Query { + # TopN is an aggregation query. + getTopN(condition: TopNCondition!): [TopNEntity!]! +} \ No newline at end of file diff --git a/alarm.graphqls b/alarm.graphqls new file mode 100644 index 0000000..52d7d22 --- /dev/null +++ b/alarm.graphqls @@ -0,0 +1,36 @@ +# 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. + +# the trend alarm trigger times +type AlarmTrend { + numOfAlarm: [Int]! +} + +type AlarmMessage { + scope: Scope! + id: ID! + message: String! +} + +type Alarms { + msgs: [AlarmMessage!]! + total: Int! +} + +extend type Query { + getAlarmTrend(duration: Duration!): AlarmTrend! + getAlarm(duration: Duration!, scope: Scope, paging: Pagination!): Alarms +} \ No newline at end of file diff --git a/common.graphqls b/common.graphqls new file mode 100644 index 0000000..258e2b4 --- /dev/null +++ b/common.graphqls @@ -0,0 +1,93 @@ +# 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. + +schema { + query: Query + mutation: Mutation +} + +#Root node +type Query { + version: String +} + +type Mutation { + version: String +} + +# The Duration defines the start and end time for each query operation. +# Fields: `start` and `end` +# represents the time span. And each of them matches the step. +# ref https://www.ietf.org/rfc/rfc3339.txt +# The time formats are +# `SECOND` step: yyyy-MM-dd HHmmss +# `MINUTE` step: yyyy-MM-dd HHmm +# `HOUR` step: yyyy-MM-dd HH +# `DAY` step: yyyy-MM-dd +# `MONTH` step: yyyy-MM +# Field: `step` +# represents the accurate time point. +# e.g. +# if step==HOUR , start=2017-11-08 09, end=2017-11-08 19 +# then +# metrics from the following time points expected +# 2017-11-08 9:00 -> 2017-11-08 19:00 +# there are 11 time points (hours) in the time span. +input Duration { + start: String! + end: String! + step: Step! +} + +enum Step { + MONTH + DAY + HOUR + MINUTE + SECOND +} + +enum Order { + ASC + DES +} + +input Pagination { + # pageNum starts in 1, the default is 1. + pageNum: Int + pageSize: Int! + # default false + needTotal: Boolean +} + +enum Language { + # For not language based agent, the language is impossible to tell. + UNKNOWN + JAVA + DOTNET + NODEJS + PYTHON + RUBY +} + +enum Scope { + SERVICE + SERVICE_INSTANCE + ENDPOINT + SERVICE_RELATION + SERVICE_INSTANCE_RELATION + ENDPOINT_RELATION +} \ No newline at end of file diff --git a/metadata.graphqls b/metadata.graphqls new file mode 100644 index 0000000..d4ad3c5 --- /dev/null +++ b/metadata.graphqls @@ -0,0 +1,62 @@ +# 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. + +# Query the cluster brief based on the given duration +type ClusterBrief { + numOfService: Int! + numOfEndpoint: Int! + numOfDatabase: Int! + numOfCache: Int! + numOfMQ: Int! +} + +type Service { + id: ID! + name: String! +} + +type ServiceInstance { + id: ID! + name: String! + attributes: [Attribute!]! + language: Language! +} + +type Attribute { + name: String! + value: String! +} + +type Endpoint { + id: ID! + name: String! +} + +extend type Query { + getGlobalBrief(duration: Duration!): ClusterBrief + + # Service related meta info. + getAllServices(duration: Duration!): [Service!]! + searchServices(duration: Duration!, keyword: String!): [Service!]! + + # Service intance query + getServiceInstances(duration: Duration!, id: ID!): [ServiceInstance!]! + + # Endpoint query + # Consider there are huge numbers of endpoint, + # must use endpoint owner's service id, keyword and limit filter to do query. + searchEndpoint(keyword: String!, serviceId: ID!, limit: Int!): [Endpoint!]! +} diff --git a/metric.graphqls b/metric.graphqls new file mode 100644 index 0000000..9f27d71 --- /dev/null +++ b/metric.graphqls @@ -0,0 +1,61 @@ +# 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. + +input MetricCondition { + # Metric name, which should be defined in OAL script + # Such as: + # Endpoint_avg = from(Endpoint.latency).avg() + # Then, `Endpoint_avg` + name: String! + # Id in this metric type. + # In the above case, the id should be endpoint id. + id: ID +} + +type LinearIntValues { + values: [KVInt!]! +} + +type KVInt { + id: ID! + # This is the value, the caller must understand the Unit. + # Such as: + # 1. If ask for cpm metric, the unit and result should be count. + # 2. If ask for response time (p99 or avg), the unit should be millisecond. + value: Int! +} + +type Thermodynamic { + # Each element in nodes represents a point in Thermodynamic Diagram + # And the element includes three values: + # 1) Time Bucket based on query duration + # 2) Response time index. + # Response time = [responseTimeStep * index, responseTimeStep * (index+1)) + # The last element: [Response Time * index, MAX) + # 3) The number of calls in this response time duration. + # + # Example: + # [ [0, 0, 10], [0, 1, 43], ...] + # These ^^^ two represent the left bottom element, and another element above it. + nodes: [[Long]!]! + axisYStep: Int! +} + + +extend type Query { + getLinearIntValues(metric: MetricCondition!, duration: Duration!): LinearIntValues + getThermodynamic(metric: MetricCondition!, duration: Duration!): Thermodynamic +} \ No newline at end of file diff --git a/topology.graphqls b/topology.graphqls new file mode 100644 index 0000000..94c3052 --- /dev/null +++ b/topology.graphqls @@ -0,0 +1,64 @@ +# 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. + +# The overview topology of the whole application cluster or services, +type Topology { + nodes: [Node!]! + calls: [Call!]! +} + +# Node in Topology +type Node { + # The global id of each node, + # 1. Service id + # 2. Endpoint id + id: ID! + # The literal name of the #id. + name: String! + # The type name may be + # 1. The service provider/middleware tech, such as: Tomcat, SpringMVC + # 2. Conjectural Service, e.g. MySQL, Redis, Kafka + type: String + # It is a conjuecture node or real node, to represent a service or endpoint. + isReal: Boolean! +} + +# The Call represents a directed distributed call, +# from the `source` to the `target`. +type Call { + source: ID! + target: ID! + isAlert: Boolean + # The protocol and tech stack used in this distributed call + callType: String! + cpm: Long! + # Unit: millisecond + avgResponseTime: Long! +} + +enum NodeType { + SERVICE, + ENDPOINT, + USER +} + + +extend type Query { + # Query the global topolgoy + getGlobalTopology(duration: Duration!): Topology + # Query the topology, based on the given service + getServiceTopology(serviceId: ID!, duration: Duration!): Topology +} \ No newline at end of file diff --git a/trace.graphqls b/trace.graphqls new file mode 100644 index 0000000..72ccf98 --- /dev/null +++ b/trace.graphqls @@ -0,0 +1,118 @@ +# 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. + +# The list of traces +type TraceBrief { + traces: [BasicTrace!]! + total: Int! +} + +# Trace basic info +type BasicTrace { + segmentId: String! + operationNames: [String!]! + duration: Int! + start: String! + isError: Boolean + traceIds: [String!]! +} + +# Represent the conditions used for query TraceBrief +input TraceQueryCondition { + # The value of 0 means all application. + applicationId: Int + traceId: String + operationName: String + # The time range of traces started + queryDuration: Duration + # The mix time of trace + minTraceDuration: Int + # The max time of trace + maxTraceDuration: Int + traceState: TraceState! + queryOrder: QueryOrder! + paging: Pagination! +} + +enum TraceState { + ALL + SUCCESS + ERROR +} + +enum QueryOrder { + BY_START_TIME + BY_DURATION +} + +# The trace represents a distributed trace, includes all segments and spans. +type Trace { + spans: [Span!]! +} + +type Span { + traceId: ID! + segmentId: ID! + spanId: Int! + parentSpanId: Int! + refs: [Ref!]! + applicationCode: String! + startTime: Long! + endTime: Long! + operationName: String + # There are three span types: Local, Entry and Exit + type: String! + # Peer network id, e.g. host+port, ip+port + peer: String + component: String + isError: Boolean + # There are 5 layers: Unknown, Database, RPCFramework, Http, MQ and Cache + layer: String + tags: [KeyValue!]! + logs: [LogEntity!]! +} + +# Ref represents the link between the segment and its parents. +# The parent(ref) may not exists, which means batch process. +# The UI should display a list, representing the other trace IDs. +type Ref { + traceId: ID! + parentSegmentId: ID! + parentSpanId: Int! + # Ref type represents why did the ref happen. + # Include: 1) CrossProcess 2) CrossThread + type: RefType! +} + +enum RefType { + CROSS_PROCESS, + CROSS_THREAD +} + +type KeyValue { + key: String! + value: String +} + +type LogEntity { + time: Long! + data: [KeyValue!] +} + +extend type Query { + queryBasicTraces(condition: TraceQueryCondition): TraceBrief + queryTrace(traceId: ID!): Trace +}