This is an automated email from the ASF dual-hosted git repository.
wankai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 98ef399410 Support tracing topology query for debugging (#12413)
98ef399410 is described below
commit 98ef399410437b097c417930ea9b4f02c2af8acf
Author: Wan Kai <[email protected]>
AuthorDate: Thu Jul 4 15:09:53 2024 +0800
Support tracing topology query for debugging (#12413)
---
docs/en/api/query-protocol.md | 13 +-
docs/en/changes/changes.md | 1 +
docs/en/debugging/query-tracing.md | 403 ++++++++++++++++++---
.../server/core/query/EndpointTopologyBuilder.java | 87 +++++
.../server/core/query/ProcessTopologyBuilder.java | 18 +
.../core/query/ServiceInstanceTopologyBuilder.java | 18 +
.../server/core/query/ServiceTopologyBuilder.java | 18 +
.../server/core/query/TopologyQueryService.java | 149 +++++---
.../server/core/query/type/EndpointTopology.java | 4 +
.../server/core/query/type/ProcessTopology.java | 6 +-
.../core/query/type/ServiceInstanceTopology.java | 4 +
.../oap/server/core/query/type/Topology.java | 4 +
.../core/storage/query/ITopologyQueryDAO.java | 155 ++++++++
.../oap/query/debug/DebuggingHTTPHandler.java | 111 ++++++
.../debug/DebuggingQueryExceptionHandler.java | 45 +++
.../DebuggingQueryEndpointTopologyRsp.java} | 16 +-
.../DebuggingQueryInstanceTopologyRsp.java} | 17 +-
.../DebuggingQueryProcessTopologyRsp.java} | 21 +-
.../DebuggingQueryServiceTopologyRsp.java} | 16 +-
.../oap/query/graphql/resolver/TopologyQuery.java | 133 ++++++-
.../src/main/resources/query-protocol | 2 +-
.../banyandb/measure/BanyanDBTopologyQueryDAO.java | 10 +-
.../storage/plugin/elasticsearch/base/EsDAO.java | 4 +
.../elasticsearch/query/RecordsQueryEsDAO.java | 2 +-
.../elasticsearch/query/TopologyQueryEsDAO.java | 8 +-
25 files changed, 1086 insertions(+), 179 deletions(-)
diff --git a/docs/en/api/query-protocol.md b/docs/en/api/query-protocol.md
index 346cb839b7..8f5936ea2b 100644
--- a/docs/en/api/query-protocol.md
+++ b/docs/en/api/query-protocol.md
@@ -55,23 +55,24 @@ extend type Query {
The topology and dependency graphs among services, instances and endpoints.
Includes direct relationships or global maps.
```graphql
+# Param, if debug is true will enable the query tracing and return
DebuggingTrace in the result.
extend type Query {
# Query the global topology
# When layer is specified, the topology of this layer would be queried
- getGlobalTopology(duration: Duration!, layer: String): Topology
+ getGlobalTopology(duration: Duration!, layer: String, debug: Boolean):
Topology
# Query the topology, based on the given service
- getServiceTopology(serviceId: ID!, duration: Duration!): Topology
+ getServiceTopology(serviceId: ID!, duration: Duration!, debug: Boolean):
Topology
# Query the topology, based on the given services.
# `#getServiceTopology` could be replaced by this.
- getServicesTopology(serviceIds: [ID!]!, duration: Duration!): Topology
+ getServicesTopology(serviceIds: [ID!]!, duration: Duration!, debug:
Boolean): Topology
# Query the instance topology, based on the given clientServiceId and
serverServiceId
- getServiceInstanceTopology(clientServiceId: ID!, serverServiceId: ID!,
duration: Duration!): ServiceInstanceTopology
+ getServiceInstanceTopology(clientServiceId: ID!, serverServiceId: ID!,
duration: Duration!, debug: Boolean): ServiceInstanceTopology
# Query the topology, based on the given endpoint
getEndpointTopology(endpointId: ID!, duration: Duration!): Topology
# v2 of getEndpointTopology
- getEndpointDependencies(endpointId: ID!, duration: Duration!):
EndpointTopology
+ getEndpointDependencies(endpointId: ID!, duration: Duration!, debug:
Boolean): EndpointTopology
# Query the topology, based on the given instance
- getProcessTopology(serviceInstanceId: ID!, duration: Duration!):
ProcessTopology
+ getProcessTopology(serviceInstanceId: ID!, duration: Duration!, debug:
Boolean): ProcessTopology
}
```
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index dd5f0275d9..82222b25ee 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -27,6 +27,7 @@
* Support BanyanDB internal metrics query execution tracing.
* BanyanDB client config: rise the default `maxBulkSize` to 10000, add
`flushTimeout` and set default to 10s.
* Polish BanyanDB group and schema creation logic to fix the schema creation
failure issue in distributed race conditions.
+* Support tracing topology query for debugging.
#### UI
* Highlight search log keywords.
diff --git a/docs/en/debugging/query-tracing.md
b/docs/en/debugging/query-tracing.md
index 55668a9f0a..065ec02853 100644
--- a/docs/en/debugging/query-tracing.md
+++ b/docs/en/debugging/query-tracing.md
@@ -15,16 +15,16 @@ SkyWalking OAP provides the metrics/trace/log/topology
query tracing to help use
- Span
-| Field | Description
|
-|--------------|------------------------------------------------------------------------------------------------------------------|
-| spanId | The unique ID of the span
|
-| parentSpanId | The parent span ID of the span
|
-| operation | The operation name of the span
|
-| startTime | The start time of the span. In nanoseconds
|
-| endTime | The end time of the span. In nanoseconds
|
-| duration | The duration of the span. In nanoseconds
|
-| msg | The message of the span, could include additional info such
as request condition and response from the Database |
-| error | The error message of the span, if the span has an error.
|
+| Field | Description
|
+|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| spanId | The unique ID of the span
|
+| parentSpanId | The parent span ID of the span
|
+| operation | The operation name of the span
|
+| startTime | The start time of the span. In nanoseconds, this is a
relative time based on different env and implementation
|
+| endTime | The end time of the span. In nanoseconds, this is a relative
time based on different env and implementation
|
+| duration | The duration of the span. In nanoseconds
|
+| msg | The message of the span, could include additional info such
as request condition and response from the Database or Tags from BanyanDB
internal trace |
+| error | The error message of the span, if the span has an error.
|
## Debugging through HTTP APIs
@@ -57,10 +57,10 @@ The time and step parameters are follow the
[Duration](../api/query-protocol.md#
- Example
-Tracing an avg query with the MQE query expression `avg(service_sla)` from
2024-06-18 11 to 2024-06-18 12 with the step HOUR for the service
`mock_a_service` and the service layer `GENERAL`.
+Tracing an avg query with the MQE query expression `avg(service_sla)` from
2024-07-03 to 2024-07-03 with the step DAY for the service `mock_a_service` and
the service layer `GENERAL`.
```shell
-curl -X GET
'http://127.0.0.1:12800/debugging/query/mqe?dumpDBRsp=true&expression=avg(service_sla)&startTime=2024-06-18%2011&endTime=2024-06-18%2012&step=HOUR&service=mock_a_service&serviceLayer=GENERAL'
+curl -X GET
'http://127.0.0.1:12800/debugging/query/mqe?dumpDBRsp=true&expression=avg(service_sla)&startTime=2024-07-03&endTime=2024-07-03&step=DAY&service=mock_a_service&serviceLayer=GENERAL'
```
Response will include query result and the debuggingTrace information:
@@ -78,55 +78,103 @@ results:
emptyValue: false
error: null
debuggingTrace:
- traceId: "a50910fe-c966-4249-87f9-e471e55cf92f"
+ traceId: "4f972417-c543-4f7d-a3f1-f5e694cfeb2b"
condition: "Expression: avg(service_sla), Entity: Entity(scope=null,
serviceName=mock_a_service,\
\ normal=true, serviceInstanceName=null, endpointName=null,
processName=null,\
\ destServiceName=null, destNormal=null, destServiceInstanceName=null,
destEndpointName=null,\
- \ destProcessName=null), Duration: Duration(start=2024-06-18 11,
end=2024-06-18\
- \ 12, step=HOUR)"
- startTime: 61636369350002
- endTime: 61636374541189
- duration: 5191187
+ \ destProcessName=null), Duration: Duration(start=2024-07-03,
end=2024-07-03,\
+ \ step=DAY)"
+ startTime: 115828803080350
+ endTime: 115828877400237
+ duration: 74319887
rootSpan:
spanId: 0
parentSpanId: -1
operation: "MQE query"
- startTime: 61636369352761
- endTime: 61636374539893
- duration: 5187132
+ startTime: 115828803110686
+ endTime: 115828877396756
+ duration: 74286070
msg: null
error: null
childSpans:
- spanId: 1
parentSpanId: 0
operation: "MQE syntax analysis"
- startTime: 61636369357437
- endTime: 61636369443631
- duration: 86194
+ startTime: 115828803699331
+ endTime: 115828805015745
+ duration: 1316414
msg: null
error: null
childSpans: []
- spanId: 2
parentSpanId: 0
operation: "MQE Aggregation OP: avg(service_sla)"
- startTime: 61636369458018
- endTime: 61636374440560
- duration: 4982542
+ startTime: 115828805052267
+ endTime: 115828876877134
+ duration: 71824867
msg: null
error: null
childSpans:
- spanId: 3
parentSpanId: 2
operation: "MQE Metric OP: service_sla"
- startTime: 61636369468839
- endTime: 61636374373771
- duration: 4904932
+ startTime: 115828805209453
+ endTime: 115828875634953
+ duration: 70425500
msg: null
error: null
childSpans:
...
```
+**Note:** if using the SkyWalking native storage
[BanyanDB](../setup/backend/storages/banyandb.md),
+the debuggingTrace will include the BanyanDB internal execution trace info,
such as:
+```yaml
+...
+childSpans:
+ - spanId: 7
+ parentSpanId: 6
+ operation: "BanyanDB: measure-grpc"
+ startTime: 1720059017222584700
+ endTime: 1720059017223492400
+ duration: 907700
+ msg: "[Tag(key=request, value={\"groups\":[\"measure-default\"], \"\
+ name\":\"service_sla_day\",
\"timeRange\":{\"begin\":\"2024-07-02T16:00:00Z\"\
+ , \"end\":\"2024-07-03T16:00:00Z\"},
\"criteria\":{\"condition\"\
+ :{\"name\":\"entity_id\", \"op\":\"BINARY_OP_EQ\",
\"value\":{\"\
+ str\":{\"value\":\"bW9ja19hX3NlcnZpY2U=.1\"}}}},
\"tagProjection\"\
+ :{\"tagFamilies\":[{\"name\":\"storage-only\",
\"tags\":[\"entity_id\"\
+ ]}]}, \"fieldProjection\":{\"names\":[\"percentage\"]},
\"trace\"\
+ :true})]"
+ error: null
+ childSpans:
+ - spanId: 8
+ parentSpanId: 7
+ operation: "BanyanDB: data-0ebf3a27de83:17912"
+ startTime: 1720059017222821600
+ endTime: 1720059017223473500
+ duration: 651900
+ msg: "[Tag(key=plan, value=IndexScan:
startTime=1719936000,endTime=1720022400,Metadata{group=measure-default,name=service_sla_day},conditions=%!s(<nil>);\
+ \ projection=#storage-only:entity_id<TAG_TYPE_STRING>;
order=OrderBy:\
+ \ [], sort=SORT_UNSPECIFIED; limit=100 Limit: 0, 100)]"
+ error: null
+ childSpans:
+ - spanId: 9
+ parentSpanId: 8
+ operation: "BanyanDB: indexScan-group:\"measure-default\" name:\"\
+ service_sla_day\""
+ startTime: 1720059017222879200
+ endTime: 1720059017223293300
+ duration: 414100
+ msg: "[Tag(key=orderBy, value=time SORT_UNSPECIFIED),
Tag(key=details,\
+ \ value=IndexScan:
startTime=1719936000,endTime=1720022400,Metadata{group=measure-default,name=service_sla_day},conditions=%!s(<nil>);\
+ \ projection=#storage-only:entity_id<TAG_TYPE_STRING>;
order=OrderBy:\
+ \ [], sort=SORT_UNSPECIFIED; limit=100)]"
+ error: null
+ childSpans:
+...
+```
+
### Tracing SkyWalking Trace Query
#### Tracing SkyWalking API queryBasicTraces
@@ -245,6 +293,153 @@ debuggingTrace:
...
```
+### Tracing Topology Query
+
+#### Tracing SkyWalking API getGlobalTopology
+- URL: HTTP GET `http://{core restHost}:{core
restPort}/debugging/query/topology/getGlobalTopology?{parameters}`.
+- Parameters
+
+ | Field | Description
| Required |
+
|-------------------|---------------------------------------------------------------|----------|
+ | startTime | The start time of the query
| Yes |
+ | endTime | The end time of the query
| Yes |
+ | step | The query step
| Yes |
+ | serviceLayer | The service layer name
| No |
+
+- Example
+```shell
+curl -X GET
'http://127.0.0.1:12800/debugging/query/topology/getGlobalTopology?startTime=2024-07-03&endTime=2024-07-03&step=DAY&serviceLayer=GENERAL'
+```
+
+Response will include query result and the debuggingTrace information, the
debuggingTrace information is the same as the MQE query tracing:
+
+```yaml
+nodes:
+...
+calls:
+...
+debuggingTrace:
+...
+```
+
+#### Tracing SkyWalking API getServicesTopology
+- URL: HTTP GET `http://{core restHost}:{core
restPort}/debugging/query/topology/getServicesTopology?{parameters}`.
+- Parameters
+
+ | Field | Description
| Required |
+
|--------------|-----------------------------------------------------------------------------|----------|
+ | startTime | The start time of the query
| Yes |
+ | endTime | The end time of the query
| Yes |
+ | step | The query step
| Yes |
+ | serviceLayer | The service layer name
| Yes |
+ | services | The services names list, separate by comma `mock_a_service,
mock_b_service` | Yes |
+
+- Example
+```shell
+curl -X GET
'http://127.0.0.1:12800/debugging/query/topology/getServicesTopology?startTime=2024-07-03&endTime=2024-07-03&step=DAY&serviceLayer=GENERAL&services=mock_a_service%2Cmock_b_service'
+```
+
+Response will include query result and the debuggingTrace information, the
debuggingTrace information is the same as the MQE query tracing:
+
+```yaml
+nodes:
+...
+calls:
+...
+debuggingTrace:
+...
+```
+
+#### Tracing SkyWalking API getServiceInstanceTopology
+- URL: HTTP GET `http://{core restHost}:{core
restPort}/debugging/query/topology/getServiceInstanceTopology?{parameters}`.
+- Parameters
+
+ | Field | Description | Required |
+ |--------------------|------------------------------------|----------|
+ | startTime | The start time of the query | Yes |
+ | endTime | The end time of the query | Yes |
+ | step | The query step | Yes |
+ | clientService | The client side service name | Yes |
+ | serverService | The server side service name | Yes |
+ | clientServiceLayer | The client side service layer name | Yes |
+ | serverServiceLayer | The server side service layer name | Yes |
+
+- Example
+```shell
+curl -X GET
'http://127.0.0.1:12800/debugging/query/topology/getServiceInstanceTopology?startTime=2024-07-03&endTime=2024-07-03&step=DAY&clientService=mock_a_service&serverService=mock_b_service&clientServiceLayer=GENERAL&serverServiceLayer=GENERAL'
+```
+
+Response will include query result and the debuggingTrace information, the
debuggingTrace information is the same as the MQE query tracing:
+
+```yaml
+nodes:
+...
+calls:
+...
+debuggingTrace:
+...
+```
+
+#### Tracing SkyWalking API getEndpointDependencies
+- URL: HTTP GET `http://{core restHost}:{core
restPort}/debugging/query/topology/getEndpointDependencies?{parameters}`.
+- Parameters
+
+ | Field | Description
| Required |
+
|--------------|-----------------------------------------------------------------------------|----------|
+ | startTime | The start time of the query
| Yes |
+ | endTime | The end time of the query
| Yes |
+ | step | The query step
| Yes |
+ | service | The service name
| Yes |
+ | serviceLayer | The service layer name
| Yes |
+ | endpoint | The endpoint name
| Yes |
+
+- Example
+- Example
+```shell
+curl -X GET
'http://127.0.0.1:12800/debugging/query/topology/getEndpointDependencies?startTime=2024-07-03&endTime=2024-07-03&step=DAY&service=mock_a_service&serviceLayer=GENERAL&endpoint=%2Fdubbox-case%2Fcase%2Fdubbox-rest%2F404-test'
+```
+
+Response will include query result and the debuggingTrace information, the
debuggingTrace information is the same as the MQE query tracing:
+
+```yaml
+nodes:
+...
+calls:
+...
+debuggingTrace:
+...
+```
+
+#### Tracing SkyWalking API getProcessTopology
+- URL: HTTP GET `http://{core restHost}:{core
restPort}/debugging/query/topology/getProcessTopology?{parameters}`.
+- Parameters
+
+ | Field | Description
| Required |
+
|---------------|-----------------------------------------------------------------------------|----------|
+ | startTime | The start time of the query
| Yes |
+ | endTime | The end time of the query
| Yes |
+ | step | The query step
| Yes |
+ | service | The service name
| Yes |
+ | serviceLayer | The service layer name
| Yes |
+ | instance | The instance name
| Yes |
+
+- Example
+```shell
+
+curl -X GET
'http://127.0.0.1:12800/debugging/query/topology/getProcessTopology?startTime=2024-07-03&endTime=2024-07-03&step=DAY&service=mock_a_service&serviceLayer=GENERAL&instance=mock_a_service_instance'
+```
+
+Response will include query result and the debuggingTrace information, the
debuggingTrace information is the same as the MQE query tracing:
+
+```yaml
+nodes:
+...
+calls:
+...
+debuggingTrace:
+...
+```
+
## Debugging with GraphQL bundled
When querying the metrics though the [GraphQL APIs](../api/query-protocol.md),
the query tracing service is also provided within the GraphQL bundled.
@@ -277,7 +472,7 @@ http://127.0.0.1:12800/graphql
```graphql
{
- execExpression(expression: "avg(service_sla)", entity: {serviceName:
"mock_a_service", normal: true}, duration: {start: "2024-06-18 11", end:
"2024-06-18 12", step: HOUR}, debug: true, dumpDBRsp: true) {
+ execExpression(expression: "avg(service_sla)", entity: {serviceName:
"mock_a_service", normal: true}, duration: {start: "2024-07-03", end:
"2024-07-03", step: DAY}, debug: true, dumpDBRsp: true) {
type
error
results {
@@ -338,19 +533,19 @@ Response will include query result and the execTrace
information:
}
],
"debuggingTrace": {
- "traceId": "7caa6529-9a72-4878-ab82-7a9ca032a97b",
- "condition": "Expression: avg(service_sla), Entity: Entity(scope=null,
serviceName=mock_a_service, normal=true, serviceInstanceName=null,
endpointName=null, processName=null, destServiceName=null, destNormal=null,
destServiceInstanceName=null, destEndpointName=null, destProcessName=null),
Duration: Duration(start=2024-06-18 11, end=2024-06-18 12, step=HOUR)",
- "startTime": 73040673584523,
- "endTime": 73040678525541,
- "duration": 4941018,
+ "traceId": "3116ffe3-ee9c-4047-9f22-c135c237aad5",
+ "condition": "Expression: avg(service_sla), Entity: Entity(scope=null,
serviceName=mock_a_service, normal=true, serviceInstanceName=null,
endpointName=null, processName=null, destServiceName=null, destNormal=null,
destServiceInstanceName=null, destEndpointName=null, destProcessName=null),
Duration: Duration(start=2024-07-03, end=2024-07-03, step=DAY)",
+ "startTime": 117259274324665,
+ "endTime": 117259279847720,
+ "duration": 5523055,
"spans": [
{
"spanId": 0,
"parentSpanId": -1,
"operation": "MQE query",
- "startTime": 73040673586770,
- "endTime": 73040678523624,
- "duration": 4936854,
+ "startTime": 117259274328719,
+ "endTime": 117259279846559,
+ "duration": 5517840,
"msg": null,
"error": null
},
@@ -358,9 +553,9 @@ Response will include query result and the execTrace
information:
"spanId": 1,
"parentSpanId": 0,
"operation": "MQE syntax analysis",
- "startTime": 73040673591566,
- "endTime": 73040673677579,
- "duration": 86013,
+ "startTime": 117259274333084,
+ "endTime": 117259274420159,
+ "duration": 87075,
"msg": null,
"error": null
},
@@ -368,9 +563,9 @@ Response will include query result and the execTrace
information:
"spanId": 2,
"parentSpanId": 0,
"operation": "MQE Aggregation OP: avg(service_sla)",
- "startTime": 73040673691700,
- "endTime": 73040678270159,
- "duration": 4578459,
+ "startTime": 117259274433533,
+ "endTime": 117259279812549,
+ "duration": 5379016,
"msg": null,
"error": null
},
@@ -381,6 +576,53 @@ Response will include query result and the execTrace
information:
}
}
```
+**Note:** if using the SkyWalking native storage
[BanyanDB](../setup/backend/storages/banyandb.md),
+the debuggingTrace will include the BanyanDB internal execution trace info,
such as:
+```json
+...
+{
+ "spanId": 7,
+ "parentSpanId": 6,
+ "operation": "BanyanDB: measure-grpc",
+ "startTime": 1720060447687765300,
+ "endTime": 1720060447688830200,
+ "duration": 1064900,
+ "msg": "[Tag(key=request, value={\"groups\":[\"measure-default\"],
\"name\":\"service_sla_day\",
\"timeRange\":{\"begin\":\"2024-07-02T16:00:00Z\",
\"end\":\"2024-07-03T16:00:00Z\"},
\"criteria\":{\"condition\":{\"name\":\"entity_id\", \"op\":\"BINARY_OP_EQ\",
\"value\":{\"str\":{\"value\":\"bW9ja19hX3NlcnZpY2U=.1\"}}}},
\"tagProjection\":{\"tagFamilies\":[{\"name\":\"storage-only\",
\"tags\":[\"entity_id\"]}]}, \"fieldProjection\":{\"names\":[\"percentage\"]},
\"trace\":true})]",
+ "error": null
+},
+{
+"spanId": 8,
+"parentSpanId": 7,
+"operation": "BanyanDB: data-0ebf3a27de83:17912",
+"startTime": 1720060447687956700,
+"endTime": 1720060447688810000,
+"duration": 853300,
+"msg": "[Tag(key=plan, value=IndexScan:
startTime=1719936000,endTime=1720022400,Metadata{group=measure-default,name=service_sla_day},conditions=%!s(<nil>);
projection=#storage-only:entity_id<TAG_TYPE_STRING>; order=OrderBy: [],
sort=SORT_UNSPECIFIED; limit=100 Limit: 0, 100)]",
+"error": null
+},
+{
+"spanId": 9,
+"parentSpanId": 8,
+"operation": "BanyanDB: indexScan-group:\"measure-default\"
name:\"service_sla_day\"",
+"startTime": 1720060447687997400,
+"endTime": 1720060447688664700,
+"duration": 667300,
+"msg": "[Tag(key=orderBy, value=time SORT_UNSPECIFIED), Tag(key=details,
value=IndexScan:
startTime=1719936000,endTime=1720022400,Metadata{group=measure-default,name=service_sla_day},conditions=%!s(<nil>);
projection=#storage-only:entity_id<TAG_TYPE_STRING>; order=OrderBy: [],
sort=SORT_UNSPECIFIED; limit=100)]",
+"error": null
+},
+{
+"spanId": 10,
+"parentSpanId": 9,
+"operation": "BanyanDB: seriesIndex.Search",
+"startTime": 1720060447688023800,
+"endTime": 1720060447688101800,
+"duration": 78000,
+"msg": "[]",
+"error": null
+},
+...
+```
+
### Tracing SkyWalking Trace Query
#### Tracing SkyWalking API queryBasicTraces
@@ -389,8 +631,10 @@ Response will include query result and the execTrace
information:
```graphql
# Param, if debug is true will enable the query tracing and return
DebuggingTrace in the result.
extend type Query {
- # Search segment list with given conditions
- queryBasicTraces(condition: TraceQueryCondition, debug: Boolean):
TraceBrief
+ # Search segment list with given conditions
+ queryBasicTraces(condition: TraceQueryCondition, debug: Boolean): TraceBrief
+ # Read the specific trace ID with given trace ID
+ queryTrace(traceId: ID!, debug: Boolean): Trace
...
}
```
@@ -402,35 +646,74 @@ type TraceBrief {
#For OAP internal query debugging
debuggingTrace: DebuggingTrace
}
+
+# The trace represents a distributed trace, includes all segments and spans.
+type Trace {
+...
+ #For OAP internal query debugging
+ debuggingTrace: DebuggingTrace
+}
```
- Example
-Same as the MQE query tracing, follow the GraphQL protocol and grammar to
query the result and get debuggingTrace information,
+Same as the MQE query tracing, follow the GraphQL protocol and grammar to
query the result and get debuggingTrace information,
just enable the debug parameter to true.
-#### Tracing SkyWalking API queryTrace
-- Bundle API: [Trace](../api/query-protocol.md#trace)
+### Tracing Topology Query
+- Bundle API: [Topology](../api/query-protocol.md#topology)
-```graphql
+```graphql
# Param, if debug is true will enable the query tracing and return
DebuggingTrace in the result.
extend type Query {
- # Read the specific trace ID with given trace ID
- queryTrace(traceId: ID!, debug: Boolean): Trace
- ...
+ # Query the global topology
+ # When layer is specified, the topology of this layer would be queried
+ getGlobalTopology(duration: Duration!, layer: String, debug: Boolean):
Topology
+ # Query the topology, based on the given service
+ getServiceTopology(serviceId: ID!, duration: Duration!, debug: Boolean):
Topology
+ # Query the topology, based on the given services.
+ # `#getServiceTopology` could be replaced by this.
+ getServicesTopology(serviceIds: [ID!]!, duration: Duration!, debug:
Boolean): Topology
+ # Query the instance topology, based on the given clientServiceId and
serverServiceId
+ getServiceInstanceTopology(clientServiceId: ID!, serverServiceId: ID!,
duration: Duration!, debug: Boolean): ServiceInstanceTopology
+...
+ # v2 of getEndpointTopology
+ getEndpointDependencies(endpointId: ID!, duration: Duration!, debug:
Boolean): EndpointTopology
+ # Query the topology, based on the given instance
+ getProcessTopology(serviceInstanceId: ID!, duration: Duration!, debug:
Boolean): ProcessTopology
}
```
```graphql
-# The trace represents a distributed trace, includes all segments and spans.
-type Trace {
-...
- #For OAP internal query debugging
- debuggingTrace: DebuggingTrace
+# The overview topology of the whole application cluster or services,
+type Topology {
+ nodes: [Node!]!
+ calls: [Call!]!
+ debuggingTrace: DebuggingTrace
+}
+
+# The instance topology based on the given serviceIds
+type ServiceInstanceTopology {
+ nodes: [ServiceInstanceNode!]!
+ calls: [Call!]!
+ debuggingTrace: DebuggingTrace
+}
+
+# The endpoint topology
+type EndpointTopology {
+ nodes: [EndpointNode!]!
+ calls: [Call!]!
+ debuggingTrace: DebuggingTrace
+}
+
+# The process topology
+type ProcessTopology {
+ nodes: [ProcessNode!]!
+ calls: [Call!]!
+ debuggingTrace: DebuggingTrace
}
```
- Example
-
Same as the MQE query tracing, follow the GraphQL protocol and grammar to
query the result and get debuggingTrace information,
just enable the debug parameter to true.
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/EndpointTopologyBuilder.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/EndpointTopologyBuilder.java
new file mode 100644
index 0000000000..dc391ca023
--- /dev/null
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/EndpointTopologyBuilder.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.skywalking.oap.server.core.query;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.query.type.Call;
+import org.apache.skywalking.oap.server.core.query.type.EndpointNode;
+import org.apache.skywalking.oap.server.core.query.type.EndpointTopology;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingSpan;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext;
+import org.apache.skywalking.oap.server.core.source.DetectPoint;
+
+public class EndpointTopologyBuilder {
+
+ EndpointTopology buildDebuggable(List<Call.CallDetail> serverSideCalls) {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Build endpoint topology");
+ }
+ return build(serverSideCalls);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ EndpointTopology build(List<Call.CallDetail> serverSideCalls) {
+ EndpointTopology topology = new EndpointTopology();
+ serverSideCalls.forEach(callDetail -> {
+ Call call = new Call();
+ call.setId(callDetail.getId());
+ call.setSource(callDetail.getSource());
+ call.setTarget(callDetail.getTarget());
+ call.addDetectPoint(DetectPoint.SERVER);
+ topology.getCalls().add(call);
+ });
+
+ Set<String> nodeIds = new HashSet<>();
+ serverSideCalls.forEach(call -> {
+ if (!nodeIds.contains(call.getSource())) {
+
topology.getNodes().add(buildEndpointDependencyNode(call.getSource()));
+ nodeIds.add(call.getSource());
+ }
+ if (!nodeIds.contains(call.getTarget())) {
+
topology.getNodes().add(buildEndpointDependencyNode(call.getTarget()));
+ nodeIds.add(call.getTarget());
+ }
+ });
+ return topology;
+ }
+
+ private EndpointNode buildEndpointDependencyNode(String endpointId) {
+ final IDManager.EndpointID.EndpointIDDefinition endpointIDDefinition =
IDManager.EndpointID.analysisId(
+ endpointId);
+ EndpointNode instanceNode = new EndpointNode();
+ instanceNode.setId(endpointId);
+ instanceNode.setName(endpointIDDefinition.getEndpointName());
+ instanceNode.setServiceId(endpointIDDefinition.getServiceId());
+ final IDManager.ServiceID.ServiceIDDefinition serviceIDDefinition =
IDManager.ServiceID.analysisId(
+ endpointIDDefinition.getServiceId());
+ instanceNode.setServiceName(serviceIDDefinition.getName());
+ instanceNode.setReal(serviceIDDefinition.isReal());
+ return instanceNode;
+ }
+}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ProcessTopologyBuilder.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ProcessTopologyBuilder.java
index 1b79dcd24a..8cdf6e0cdc 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ProcessTopologyBuilder.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ProcessTopologyBuilder.java
@@ -27,6 +27,8 @@ import
org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogServ
import org.apache.skywalking.oap.server.core.query.type.Call;
import org.apache.skywalking.oap.server.core.query.type.ProcessNode;
import org.apache.skywalking.oap.server.core.query.type.ProcessTopology;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingSpan;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext;
import org.apache.skywalking.oap.server.core.source.DetectPoint;
import org.apache.skywalking.oap.server.core.storage.IMetricsDAO;
import org.apache.skywalking.oap.server.core.storage.StorageDAO;
@@ -68,6 +70,22 @@ public class ProcessTopologyBuilder {
.getService(IComponentLibraryCatalogService.class);
}
+ ProcessTopology buildDebuggable(List<Call.CallDetail> clientCalls,
+ List<Call.CallDetail> serverCalls) throws
Exception {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Build process topology");
+ }
+ return build(clientCalls, serverCalls);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
ProcessTopology build(List<Call.CallDetail> clientCalls,
List<Call.CallDetail> serverCalls) throws Exception {
log.debug("building process topology, total found client calls: {},
total found server calls: {}",
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceInstanceTopologyBuilder.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceInstanceTopologyBuilder.java
index bf8ae8f6c3..3466c7d327 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceInstanceTopologyBuilder.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceInstanceTopologyBuilder.java
@@ -28,6 +28,8 @@ import
org.apache.skywalking.oap.server.core.analysis.IDManager;
import org.apache.skywalking.oap.server.core.query.type.Call;
import org.apache.skywalking.oap.server.core.query.type.ServiceInstanceNode;
import
org.apache.skywalking.oap.server.core.query.type.ServiceInstanceTopology;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingSpan;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext;
import org.apache.skywalking.oap.server.core.source.DetectPoint;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
@@ -37,6 +39,22 @@ public class ServiceInstanceTopologyBuilder {
public ServiceInstanceTopologyBuilder(ModuleManager moduleManager) {
}
+ ServiceInstanceTopology buildDebuggable(List<Call.CallDetail>
serviceInstanceRelationClientCalls,
+ List<Call.CallDetail>
serviceInstanceRelationServerCalls) {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Build service instance
topology");
+ }
+ return build(serviceInstanceRelationClientCalls,
serviceInstanceRelationServerCalls);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
ServiceInstanceTopology build(List<Call.CallDetail>
serviceInstanceRelationClientCalls,
List<Call.CallDetail>
serviceInstanceRelationServerCalls) {
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilder.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilder.java
index ba48400f74..e953d7c6c3 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilder.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilder.java
@@ -35,6 +35,8 @@ import org.apache.skywalking.oap.server.core.query.type.Call;
import org.apache.skywalking.oap.server.core.query.type.Node;
import org.apache.skywalking.oap.server.core.query.type.Service;
import org.apache.skywalking.oap.server.core.query.type.Topology;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingSpan;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext;
import org.apache.skywalking.oap.server.core.source.DetectPoint;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
import org.apache.skywalking.oap.server.library.util.StringUtil;
@@ -67,6 +69,22 @@ class ServiceTopologyBuilder {
return metadataQueryService;
}
+ Topology buildDebuggable(List<Call.CallDetail> serviceRelationClientCalls,
+ List<Call.CallDetail> serviceRelationServerCalls)
{
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Build service topology");
+ }
+ return build(serviceRelationClientCalls,
serviceRelationServerCalls);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
Topology build(List<Call.CallDetail> serviceRelationClientCalls,
List<Call.CallDetail> serviceRelationServerCalls) {
Map<String, Node> nodes = new HashMap<>();
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TopologyQueryService.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TopologyQueryService.java
index 449428f434..f4a37f5177 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TopologyQueryService.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TopologyQueryService.java
@@ -26,12 +26,13 @@ import
org.apache.skywalking.oap.server.core.analysis.IDManager;
import
org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
import org.apache.skywalking.oap.server.core.query.input.Duration;
import org.apache.skywalking.oap.server.core.query.type.Call;
-import org.apache.skywalking.oap.server.core.query.type.EndpointNode;
import org.apache.skywalking.oap.server.core.query.type.EndpointTopology;
import org.apache.skywalking.oap.server.core.query.type.Node;
import org.apache.skywalking.oap.server.core.query.type.ProcessTopology;
import
org.apache.skywalking.oap.server.core.query.type.ServiceInstanceTopology;
import org.apache.skywalking.oap.server.core.query.type.Topology;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingSpan;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext;
import org.apache.skywalking.oap.server.core.source.DetectPoint;
import org.apache.skywalking.oap.server.core.storage.StorageModule;
import org.apache.skywalking.oap.server.core.storage.model.StorageModels;
@@ -50,6 +51,8 @@ import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
+import static
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext.TRACE_CONTEXT;
+
@Slf4j
public class TopologyQueryService implements Service {
private final ModuleManager moduleManager;
@@ -87,30 +90,63 @@ public class TopologyQueryService implements Service {
}
public Topology getGlobalTopology(final Duration duration, final String
layer) throws IOException {
+ DebuggingTraceContext traceContext = TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Service:
getGlobalTopology");
+ span.setMsg("Duration: " + duration + ", Layer: " + layer);
+ }
+ return invokeGetGlobalTopology(duration, layer);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ private Topology invokeGetGlobalTopology(final Duration duration, final
String layer) throws IOException {
if (StringUtil.isNotEmpty(layer)) {
final List<String> serviceIdList =
Optional.ofNullable(getMetadataQueryService().listServices(layer, null))
.map(list -> list.stream().map(s ->
s.getId()).collect(Collectors.toList()))
.orElse(Collections.emptyList());
return getServiceTopology(duration, serviceIdList);
}
- List<Call.CallDetail> serviceRelationServerCalls =
getTopologyQueryDAO().loadServiceRelationsDetectedAtServerSide(
+ List<Call.CallDetail> serviceRelationServerCalls =
getTopologyQueryDAO().loadServiceRelationsDetectedAtServerSideDebuggable(
duration);
- List<Call.CallDetail> serviceRelationClientCalls =
getTopologyQueryDAO().loadServiceRelationDetectedAtClientSide(
+ List<Call.CallDetail> serviceRelationClientCalls =
getTopologyQueryDAO().loadServiceRelationDetectedAtClientSideDebuggable(
duration);
ServiceTopologyBuilder builder = new
ServiceTopologyBuilder(moduleManager);
- return builder.build(serviceRelationClientCalls,
serviceRelationServerCalls);
+ return builder.buildDebuggable(serviceRelationClientCalls,
serviceRelationServerCalls);
}
public Topology getServiceTopology(final Duration duration,
+ final List<String> serviceIds)
throws IOException {
+ DebuggingTraceContext traceContext = TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Service:
getServiceTopology");
+ span.setMsg("Duration: " + duration + ", ServiceIds: " +
serviceIds);
+ }
+ return invokeGetServiceTopology(duration, serviceIds);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ private Topology invokeGetServiceTopology(final Duration duration,
final List<String> serviceIds) throws
IOException {
- List<Call.CallDetail> serviceRelationClientCalls =
getTopologyQueryDAO().loadServiceRelationDetectedAtClientSide(
+ List<Call.CallDetail> serviceRelationClientCalls =
getTopologyQueryDAO().loadServiceRelationDetectedAtClientSideDebuggable(
duration, serviceIds);
- List<Call.CallDetail> serviceRelationServerCalls =
getTopologyQueryDAO().loadServiceRelationsDetectedAtServerSide(
+ List<Call.CallDetail> serviceRelationServerCalls =
getTopologyQueryDAO().loadServiceRelationsDetectedAtServerSideDebuggable(
duration, serviceIds);
ServiceTopologyBuilder builder = new
ServiceTopologyBuilder(moduleManager);
- Topology topology = builder.build(serviceRelationClientCalls,
serviceRelationServerCalls);
+ Topology topology =
builder.buildDebuggable(serviceRelationClientCalls, serviceRelationServerCalls);
/**
* The topology built above is complete.
@@ -127,7 +163,7 @@ public class TopologyQueryService implements Service {
});
if (CollectionUtils.isNotEmpty(outScopeSourceServiceIds)) {
// If exist, query them as the server side to get the target's
component.
- List<Call.CallDetail> sourceCalls =
getTopologyQueryDAO().loadServiceRelationsDetectedAtServerSide(
+ List<Call.CallDetail> sourceCalls =
getTopologyQueryDAO().loadServiceRelationsDetectedAtServerSideDebuggable(
duration, outScopeSourceServiceIds);
topology.getNodes().forEach(node -> {
if (Strings.isNullOrEmpty(node.getType())) {
@@ -147,9 +183,27 @@ public class TopologyQueryService implements Service {
public ServiceInstanceTopology getServiceInstanceTopology(final String
clientServiceId,
final String
serverServiceId,
final Duration
duration) throws IOException {
- List<Call.CallDetail> serviceInstanceRelationClientCalls =
getTopologyQueryDAO().loadInstanceRelationDetectedAtClientSide(
+ DebuggingTraceContext traceContext = TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Service:
getServiceInstanceTopology");
+ span.setMsg("ClientServiceId: " + clientServiceId + ",
ServerServiceId: " + serverServiceId + ", Duration: " + duration);
+ }
+ return invokeGetServiceInstanceTopology(clientServiceId,
serverServiceId, duration);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ private ServiceInstanceTopology invokeGetServiceInstanceTopology(final
String clientServiceId,
+ final String
serverServiceId,
+ final Duration
duration) throws IOException {
+ List<Call.CallDetail> serviceInstanceRelationClientCalls =
getTopologyQueryDAO().loadInstanceRelationDetectedAtClientSideDebuggable(
clientServiceId, serverServiceId, duration);
- List<Call.CallDetail> serviceInstanceRelationServerCalls =
getTopologyQueryDAO().loadInstanceRelationDetectedAtServerSide(
+ List<Call.CallDetail> serviceInstanceRelationServerCalls =
getTopologyQueryDAO().loadInstanceRelationDetectedAtServerSideDebuggable(
clientServiceId, serverServiceId, duration);
ServiceInstanceTopologyBuilder builder = new
ServiceInstanceTopologyBuilder(moduleManager);
@@ -189,37 +243,48 @@ public class TopologyQueryService implements Service {
public EndpointTopology getEndpointDependencies(final Duration duration,
final String endpointId)
throws IOException {
- List<Call.CallDetail> serverSideCalls =
getTopologyQueryDAO().loadEndpointRelation(
- duration, endpointId);
-
- EndpointTopology topology = new EndpointTopology();
- serverSideCalls.forEach(callDetail -> {
- Call call = new Call();
- call.setId(callDetail.getId());
- call.setSource(callDetail.getSource());
- call.setTarget(callDetail.getTarget());
- call.addDetectPoint(DetectPoint.SERVER);
- topology.getCalls().add(call);
- });
-
- Set<String> nodeIds = new HashSet<>();
- serverSideCalls.forEach(call -> {
- if (!nodeIds.contains(call.getSource())) {
-
topology.getNodes().add(buildEndpointDependencyNode(call.getSource()));
- nodeIds.add(call.getSource());
+ DebuggingTraceContext traceContext = TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Service:
getEndpointDependencies");
+ span.setMsg("Duration: " + duration + ", EndpointId: " +
endpointId);
}
- if (!nodeIds.contains(call.getTarget())) {
-
topology.getNodes().add(buildEndpointDependencyNode(call.getTarget()));
- nodeIds.add(call.getTarget());
+ return invokeGetEndpointDependencies(duration, endpointId);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
}
- });
+ }
+ }
- return topology;
+ private EndpointTopology invokeGetEndpointDependencies(final Duration
duration,
+ final String endpointId)
throws IOException {
+ List<Call.CallDetail> serverSideCalls =
getTopologyQueryDAO().loadEndpointRelationDebuggable(
+ duration, endpointId);
+ EndpointTopologyBuilder builder = new EndpointTopologyBuilder();
+ return builder.build(serverSideCalls);
}
public ProcessTopology getProcessTopology(final String instanceId, final
Duration duration) throws Exception {
- final List<Call.CallDetail> clientCalls =
getTopologyQueryDAO().loadProcessRelationDetectedAtClientSide(instanceId,
duration);
- final List<Call.CallDetail> serverCalls =
getTopologyQueryDAO().loadProcessRelationDetectedAtServerSide(instanceId,
duration);
+ DebuggingTraceContext traceContext = TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Service:
getProcessTopology");
+ span.setMsg("InstanceId: " + instanceId + ", Duration: " +
duration);
+ }
+ return invokeGetProcessTopology(instanceId, duration);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ private ProcessTopology invokeGetProcessTopology(final String instanceId,
final Duration duration) throws Exception {
+ final List<Call.CallDetail> clientCalls =
getTopologyQueryDAO().loadProcessRelationDetectedAtClientSideDebuggable(instanceId,
duration);
+ final List<Call.CallDetail> serverCalls =
getTopologyQueryDAO().loadProcessRelationDetectedAtServerSideDebuggable(instanceId,
duration);
final ProcessTopologyBuilder topologyBuilder = new
ProcessTopologyBuilder(moduleManager, storageModels);
return topologyBuilder.build(clientCalls, serverCalls);
@@ -236,18 +301,4 @@ public class TopologyQueryService implements Service {
node.setReal(true);
return node;
}
-
- private EndpointNode buildEndpointDependencyNode(String endpointId) {
- final IDManager.EndpointID.EndpointIDDefinition endpointIDDefinition =
IDManager.EndpointID.analysisId(
- endpointId);
- EndpointNode instanceNode = new EndpointNode();
- instanceNode.setId(endpointId);
- instanceNode.setName(endpointIDDefinition.getEndpointName());
- instanceNode.setServiceId(endpointIDDefinition.getServiceId());
- final IDManager.ServiceID.ServiceIDDefinition serviceIDDefinition =
IDManager.ServiceID.analysisId(
- endpointIDDefinition.getServiceId());
- instanceNode.setServiceName(serviceIDDefinition.getName());
- instanceNode.setReal(serviceIDDefinition.isReal());
- return instanceNode;
- }
}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EndpointTopology.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EndpointTopology.java
index 2510d9117f..4267c7596f 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EndpointTopology.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EndpointTopology.java
@@ -21,11 +21,15 @@ package org.apache.skywalking.oap.server.core.query.type;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
+import lombok.Setter;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTrace;
@Getter
public class EndpointTopology {
private final List<EndpointNode> nodes;
private final List<Call> calls;
+ @Setter
+ private DebuggingTrace debuggingTrace;
public EndpointTopology() {
this.nodes = new ArrayList<>();
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProcessTopology.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProcessTopology.java
index 79518aa05e..1ae63b9371 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProcessTopology.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProcessTopology.java
@@ -22,14 +22,18 @@ import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
+import lombok.Setter;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTrace;
@Getter
public class ProcessTopology {
private final List<ProcessNode> nodes;
private final List<Call> calls;
+ @Setter
+ private DebuggingTrace debuggingTrace;
public ProcessTopology() {
this.nodes = new ArrayList<>();
this.calls = new ArrayList<>();
}
-}
\ No newline at end of file
+}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ServiceInstanceTopology.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ServiceInstanceTopology.java
index 30070d1335..2b38bd95b7 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ServiceInstanceTopology.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ServiceInstanceTopology.java
@@ -21,12 +21,16 @@ package org.apache.skywalking.oap.server.core.query.type;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
+import lombok.Setter;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTrace;
@Getter
public class ServiceInstanceTopology {
private final List<ServiceInstanceNode> nodes;
private final List<Call> calls;
+ @Setter
+ private DebuggingTrace debuggingTrace;
public ServiceInstanceTopology() {
this.nodes = new ArrayList<>();
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Topology.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Topology.java
index 7b571157db..274cb8dfb6 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Topology.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Topology.java
@@ -21,11 +21,15 @@ package org.apache.skywalking.oap.server.core.query.type;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
+import lombok.Setter;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTrace;
@Getter
public class Topology {
private final List<Node> nodes;
private final List<Call> calls;
+ @Setter
+ private DebuggingTrace debuggingTrace;
public Topology() {
this.nodes = new ArrayList<>();
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITopologyQueryDAO.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITopologyQueryDAO.java
index 2415911283..f55d10c5a0 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITopologyQueryDAO.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITopologyQueryDAO.java
@@ -26,9 +26,164 @@ import
org.apache.skywalking.oap.server.core.analysis.manual.relation.service.Se
import
org.apache.skywalking.oap.server.core.analysis.manual.relation.service.ServiceRelationServerSideMetrics;
import org.apache.skywalking.oap.server.core.query.input.Duration;
import org.apache.skywalking.oap.server.core.query.type.Call;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingSpan;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext;
import org.apache.skywalking.oap.server.library.module.Service;
public interface ITopologyQueryDAO extends Service {
+ default List<Call.CallDetail>
loadServiceRelationsDetectedAtServerSideDebuggable(Duration duration) throws
IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadServiceRelationsDetectedAtServerSide");
+ span.setMsg("Duration: " + duration);
+ }
+ return loadServiceRelationsDetectedAtServerSide(duration);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ default List<Call.CallDetail>
loadServiceRelationDetectedAtClientSideDebuggable(Duration duration) throws
IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadServiceRelationDetectedAtClientSide");
+ span.setMsg("Duration: " + duration);
+ }
+ return loadServiceRelationDetectedAtClientSide(duration);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ default List<Call.CallDetail>
loadServiceRelationsDetectedAtServerSideDebuggable(Duration duration,
+
List<String> serviceIds) throws IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadServiceRelationsDetectedAtServerSide");
+ span.setMsg("Duration: " + duration + ", ServiceIds: " +
serviceIds);
+ }
+ return loadServiceRelationsDetectedAtServerSide(duration,
serviceIds);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ default List<Call.CallDetail>
loadServiceRelationDetectedAtClientSideDebuggable(Duration duration,
+
List<String> serviceIds) throws IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadServiceRelationDetectedAtClientSide");
+ span.setMsg("Duration: " + duration + ", ServiceIds: " +
serviceIds);
+ }
+ return loadServiceRelationDetectedAtClientSide(duration,
serviceIds);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ default List<Call.CallDetail>
loadInstanceRelationDetectedAtServerSideDebuggable(String clientServiceId,
+
String serverServiceId,
+
Duration duration) throws IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadInstanceRelationDetectedAtServerSide");
+ span.setMsg("ClientServiceId: " + clientServiceId + ",
ServerServiceId: " + serverServiceId + ", Duration: " + duration);
+ }
+ return loadInstanceRelationDetectedAtServerSide(clientServiceId,
serverServiceId, duration);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ default List<Call.CallDetail>
loadInstanceRelationDetectedAtClientSideDebuggable(String clientServiceId,
+
String serverServiceId,
+
Duration duration) throws IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadInstanceRelationDetectedAtClientSide");
+ span.setMsg("ClientServiceId: " + clientServiceId + ",
ServerServiceId: " + serverServiceId + ", Duration: " + duration);
+ }
+ return loadInstanceRelationDetectedAtClientSide(clientServiceId,
serverServiceId, duration);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ default List<Call.CallDetail> loadEndpointRelationDebuggable(Duration
duration,
+ String destEndpointId) throws
IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadEndpointRelation");
+ span.setMsg("Duration: " + duration + ", DestEndpointId: " +
destEndpointId);
+ }
+ return loadEndpointRelation(duration, destEndpointId);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ default List<Call.CallDetail>
loadProcessRelationDetectedAtClientSideDebuggable(String serviceInstanceId,
+ Duration
duration) throws IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadProcessRelationDetectedAtClientSide");
+ span.setMsg("ServiceInstanceId: " + serviceInstanceId + ",
Duration: " + duration);
+ }
+ return loadProcessRelationDetectedAtClientSide(serviceInstanceId,
duration);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
+ default List<Call.CallDetail>
loadProcessRelationDetectedAtServerSideDebuggable(String serviceInstanceId,
+ Duration
duration) throws IOException {
+ DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
+ DebuggingSpan span = null;
+ try {
+ if (traceContext != null) {
+ span = traceContext.createSpan("Query Dao:
loadProcessRelationDetectedAtServerSide");
+ span.setMsg("ServiceInstanceId: " + serviceInstanceId + ",
Duration: " + duration);
+ }
+ return loadProcessRelationDetectedAtServerSide(serviceInstanceId,
duration);
+ } finally {
+ if (traceContext != null && span != null) {
+ traceContext.stopSpan(span);
+ }
+ }
+ }
+
/**
* Query {@link ServiceRelationServerSideMetrics} through the given
conditions
*/
diff --git
a/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/DebuggingHTTPHandler.java
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/DebuggingHTTPHandler.java
index db761b08b6..4e8b8c1982 100644
---
a/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/DebuggingHTTPHandler.java
+++
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/DebuggingHTTPHandler.java
@@ -27,6 +27,7 @@ import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.linecorp.armeria.common.AggregatedHttpResponse;
import com.linecorp.armeria.server.annotation.Default;
+import com.linecorp.armeria.server.annotation.ExceptionHandler;
import com.linecorp.armeria.server.annotation.Get;
import com.linecorp.armeria.server.annotation.Param;
import java.util.ArrayList;
@@ -39,11 +40,16 @@ import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.mqe.rt.type.ExpressionResult;
import org.apache.skywalking.oap.query.debug.mqe.DebuggingMQERsp;
+import
org.apache.skywalking.oap.query.debug.topology.DebuggingQueryEndpointTopologyRsp;
+import
org.apache.skywalking.oap.query.debug.topology.DebuggingQueryInstanceTopologyRsp;
+import
org.apache.skywalking.oap.query.debug.topology.DebuggingQueryProcessTopologyRsp;
+import
org.apache.skywalking.oap.query.debug.topology.DebuggingQueryServiceTopologyRsp;
import org.apache.skywalking.oap.query.debug.trace.DebuggingQueryTraceBriefRsp;
import org.apache.skywalking.oap.query.debug.trace.DebuggingQueryTraceRsp;
import
org.apache.skywalking.oap.query.debug.trace.zipkin.DebuggingZipkinQueryTraceRsp;
import
org.apache.skywalking.oap.query.debug.trace.zipkin.DebuggingZipkinQueryTracesRsp;
import org.apache.skywalking.oap.query.graphql.resolver.MetricsExpressionQuery;
+import org.apache.skywalking.oap.query.graphql.resolver.TopologyQuery;
import org.apache.skywalking.oap.query.graphql.resolver.TraceQuery;
import org.apache.skywalking.oap.query.zipkin.ZipkinQueryConfig;
import org.apache.skywalking.oap.query.zipkin.handler.ZipkinQueryHandler;
@@ -56,8 +62,12 @@ import
org.apache.skywalking.oap.server.core.query.enumeration.Step;
import org.apache.skywalking.oap.server.core.query.input.Duration;
import org.apache.skywalking.oap.server.core.query.input.Entity;
import org.apache.skywalking.oap.server.core.query.input.TraceQueryCondition;
+import org.apache.skywalking.oap.server.core.query.type.EndpointTopology;
import org.apache.skywalking.oap.server.core.query.type.Pagination;
+import org.apache.skywalking.oap.server.core.query.type.ProcessTopology;
import org.apache.skywalking.oap.server.core.query.type.QueryOrder;
+import
org.apache.skywalking.oap.server.core.query.type.ServiceInstanceTopology;
+import org.apache.skywalking.oap.server.core.query.type.Topology;
import org.apache.skywalking.oap.server.core.query.type.Trace;
import org.apache.skywalking.oap.server.core.query.type.TraceBrief;
import org.apache.skywalking.oap.server.core.query.type.TraceState;
@@ -69,11 +79,13 @@ import
org.apache.skywalking.oap.server.library.module.ModuleManager;
import zipkin2.Span;
@Slf4j
+@ExceptionHandler(DebuggingQueryExceptionHandler.class)
public class DebuggingHTTPHandler {
private final ServerStatusService serverStatusService;
private final MetricsExpressionQuery mqeQuery;
private final TraceQuery traceQuery;
private final ZipkinQueryHandler zipkinQueryHandler;
+ private final TopologyQuery topologyQuery;
final DebuggingQueryConfig config;
public DebuggingHTTPHandler(final ModuleManager manager, final
DebuggingQueryConfig config) {
@@ -85,6 +97,7 @@ public class DebuggingHTTPHandler {
this.traceQuery = new TraceQuery(manager);
//use zipkin default config for debugging
this.zipkinQueryHandler = new ZipkinQueryHandler(new
ZipkinQueryConfig(), manager);
+ this.topologyQuery = new TopologyQuery(manager);
}
@Get("/debugging/config/dump")
@@ -266,6 +279,104 @@ public class DebuggingHTTPHandler {
}
}
+ @SneakyThrows
+ @Get("/debugging/query/topology/getGlobalTopology")
+ public String getGlobalTopology(@Param("startTime") String startTime,
+ @Param("endTime") String endTime,
+ @Param("step") String step,
+ @Param("serviceLayer") Optional<String>
serviceLayer) {
+ Duration duration = new Duration();
+ duration.setStart(startTime);
+ duration.setEnd(endTime);
+ duration.setStep(Step.valueOf(step));
+ Topology topology = topologyQuery.getGlobalTopology(duration,
serviceLayer.orElse(null), true);
+ DebuggingQueryServiceTopologyRsp result = new
DebuggingQueryServiceTopologyRsp(
+ topology.getNodes(), topology.getCalls(),
transformTrace(topology.getDebuggingTrace()));
+ return transToYAMLString(result);
+ }
+
+ @SneakyThrows
+ @Get("/debugging/query/topology/getServicesTopology")
+ public String getServicesTopology(@Param("startTime") String startTime,
+ @Param("endTime") String endTime,
+ @Param("step") String step,
+ @Param("serviceLayer") String serviceLayer,
+ @Param("services") String services) {
+ Duration duration = new Duration();
+ duration.setStart(startTime);
+ duration.setEnd(endTime);
+ duration.setStep(Step.valueOf(step));
+
+ List<String> ids = Arrays.stream(services.split(Const.COMMA))
+ .map(name ->
IDManager.ServiceID.buildId(name, Layer.nameOf(serviceLayer).isNormal()))
+ .collect(Collectors.toList());
+ Topology topology = topologyQuery.getServicesTopology(ids, duration,
true);
+ DebuggingQueryServiceTopologyRsp result = new
DebuggingQueryServiceTopologyRsp(
+ topology.getNodes(), topology.getCalls(),
transformTrace(topology.getDebuggingTrace()));
+ return transToYAMLString(result);
+ }
+
+ @SneakyThrows
+ @Get("/debugging/query/topology/getServiceInstanceTopology")
+ public String getServiceInstanceTopology(@Param("startTime") String
startTime,
+ @Param("endTime") String endTime,
+ @Param("step") String step,
+ @Param("clientService") String
clientService,
+ @Param("serverService") String
serverService,
+ @Param("clientServiceLayer")
String clientServiceLayer,
+ @Param("serverServiceLayer")
String serverServiceLayer) {
+ Duration duration = new Duration();
+ duration.setStart(startTime);
+ duration.setEnd(endTime);
+ duration.setStep(Step.valueOf(step));
+ String clientServiceId = IDManager.ServiceID.buildId(clientService,
Layer.nameOf(clientServiceLayer).isNormal());
+ String serverServiceId = IDManager.ServiceID.buildId(serverService,
Layer.nameOf(serverServiceLayer).isNormal());
+ ServiceInstanceTopology topology =
topologyQuery.getServiceInstanceTopology(clientServiceId, serverServiceId,
duration, true);
+ DebuggingQueryInstanceTopologyRsp result = new
DebuggingQueryInstanceTopologyRsp(
+ topology.getNodes(), topology.getCalls(),
transformTrace(topology.getDebuggingTrace()));
+ return transToYAMLString(result);
+ }
+
+ @SneakyThrows
+ @Get("/debugging/query/topology/getEndpointDependencies")
+ public String getEndpointDependencies(@Param("startTime") String startTime,
+ @Param("endTime") String endTime,
+ @Param("step") String step,
+ @Param("service") String service,
+ @Param("serviceLayer") String
serviceLayer,
+ @Param("endpoint") String endpoint) {
+ Duration duration = new Duration();
+ duration.setStart(startTime);
+ duration.setEnd(endTime);
+ duration.setStep(Step.valueOf(step));
+ String endpointId = IDManager.EndpointID.buildId(
+ IDManager.ServiceID.buildId(service,
Layer.nameOf(serviceLayer).isNormal()), endpoint);
+ EndpointTopology topology =
topologyQuery.getEndpointDependencies(endpointId, duration, true);
+ DebuggingQueryEndpointTopologyRsp result = new
DebuggingQueryEndpointTopologyRsp(
+ topology.getNodes(), topology.getCalls(),
transformTrace(topology.getDebuggingTrace()));
+ return transToYAMLString(result);
+ }
+
+ @SneakyThrows
+ @Get("/debugging/query/topology/getProcessTopology")
+ public String getProcessTopology(@Param("startTime") String startTime,
+ @Param("endTime") String endTime,
+ @Param("step") String step,
+ @Param("service") String service,
+ @Param("serviceLayer") String
serviceLayer,
+ @Param("instance") String process) {
+ Duration duration = new Duration();
+ duration.setStart(startTime);
+ duration.setEnd(endTime);
+ duration.setStep(Step.valueOf(step));
+ String instanceId = IDManager.ServiceInstanceID.buildId(
+ IDManager.ServiceID.buildId(service,
Layer.nameOf(serviceLayer).isNormal()), process);
+ ProcessTopology topology =
topologyQuery.getProcessTopology(instanceId, duration, true);
+ DebuggingQueryProcessTopologyRsp result = new
DebuggingQueryProcessTopologyRsp(
+ topology.getNodes(), topology.getCalls(),
transformTrace(topology.getDebuggingTrace()));
+ return transToYAMLString(result);
+ }
+
private DebuggingTraceRsp transformTrace(DebuggingTrace trace) {
Map<Integer, DebuggingSpanRsp> spanMap = trace.getSpans().stream()
.collect(Collectors.toMap(
diff --git
a/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/DebuggingQueryExceptionHandler.java
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/DebuggingQueryExceptionHandler.java
new file mode 100644
index 0000000000..5bede1f430
--- /dev/null
+++
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/DebuggingQueryExceptionHandler.java
@@ -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.
+ *
+ */
+
+package org.apache.skywalking.oap.query.debug;
+
+import com.linecorp.armeria.common.HttpRequest;
+import com.linecorp.armeria.common.HttpResponse;
+import com.linecorp.armeria.server.ServiceRequestContext;
+import com.linecorp.armeria.server.annotation.ExceptionHandlerFunction;
+import lombok.extern.slf4j.Slf4j;
+
+import static com.linecorp.armeria.common.HttpStatus.BAD_REQUEST;
+import static com.linecorp.armeria.common.HttpStatus.INTERNAL_SERVER_ERROR;
+import static com.linecorp.armeria.common.MediaType.ANY_TEXT_TYPE;
+
+@Slf4j
+public class DebuggingQueryExceptionHandler implements
ExceptionHandlerFunction {
+ @Override
+ public HttpResponse handleException(final ServiceRequestContext ctx, final
HttpRequest req, final Throwable cause) {
+ String rspMsg = cause.getMessage() != null ? cause.getMessage() :
cause.getClass().getSimpleName();
+ // Response msg for illegal query args.
+ if (cause instanceof IllegalArgumentException) {
+ log.error(cause.getMessage(), cause);
+ return HttpResponse.of(BAD_REQUEST, ANY_TEXT_TYPE, rspMsg);
+ } else {
+ log.error(cause.getMessage(), cause);
+ return HttpResponse.of(INTERNAL_SERVER_ERROR, ANY_TEXT_TYPE,
rspMsg);
+ }
+ }
+}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EndpointTopology.java
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryEndpointTopologyRsp.java
similarity index 69%
copy from
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EndpointTopology.java
copy to
oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryEndpointTopologyRsp.java
index 2510d9117f..483ca7fbf3 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/EndpointTopology.java
+++
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryEndpointTopologyRsp.java
@@ -16,19 +16,19 @@
*
*/
-package org.apache.skywalking.oap.server.core.query.type;
+package org.apache.skywalking.oap.query.debug.topology;
-import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.skywalking.oap.query.debug.DebuggingTraceRsp;
+import org.apache.skywalking.oap.server.core.query.type.Call;
+import org.apache.skywalking.oap.server.core.query.type.EndpointNode;
+@RequiredArgsConstructor
@Getter
-public class EndpointTopology {
+public class DebuggingQueryEndpointTopologyRsp {
private final List<EndpointNode> nodes;
private final List<Call> calls;
-
- public EndpointTopology() {
- this.nodes = new ArrayList<>();
- this.calls = new ArrayList<>();
- }
+ private final DebuggingTraceRsp debuggingTrace;
}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ServiceInstanceTopology.java
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryInstanceTopologyRsp.java
similarity index 69%
copy from
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ServiceInstanceTopology.java
copy to
oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryInstanceTopologyRsp.java
index 30070d1335..a7d1c1db90 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ServiceInstanceTopology.java
+++
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryInstanceTopologyRsp.java
@@ -16,20 +16,19 @@
*
*/
-package org.apache.skywalking.oap.server.core.query.type;
+package org.apache.skywalking.oap.query.debug.topology;
-import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.skywalking.oap.query.debug.DebuggingTraceRsp;
+import org.apache.skywalking.oap.server.core.query.type.Call;
+import org.apache.skywalking.oap.server.core.query.type.ServiceInstanceNode;
+@RequiredArgsConstructor
@Getter
-public class ServiceInstanceTopology {
-
+public class DebuggingQueryInstanceTopologyRsp {
private final List<ServiceInstanceNode> nodes;
private final List<Call> calls;
-
- public ServiceInstanceTopology() {
- this.nodes = new ArrayList<>();
- this.calls = new ArrayList<>();
- }
+ private final DebuggingTraceRsp debuggingTrace;
}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProcessTopology.java
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryProcessTopologyRsp.java
similarity index 69%
copy from
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProcessTopology.java
copy to
oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryProcessTopologyRsp.java
index 79518aa05e..eb0e5bf8be 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/ProcessTopology.java
+++
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryProcessTopologyRsp.java
@@ -16,20 +16,19 @@
*
*/
-package org.apache.skywalking.oap.server.core.query.type;
+package org.apache.skywalking.oap.query.debug.topology;
-import lombok.Getter;
-
-import java.util.ArrayList;
import java.util.List;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.skywalking.oap.query.debug.DebuggingTraceRsp;
+import org.apache.skywalking.oap.server.core.query.type.Call;
+import org.apache.skywalking.oap.server.core.query.type.ProcessNode;
+@RequiredArgsConstructor
@Getter
-public class ProcessTopology {
+public class DebuggingQueryProcessTopologyRsp {
private final List<ProcessNode> nodes;
private final List<Call> calls;
-
- public ProcessTopology() {
- this.nodes = new ArrayList<>();
- this.calls = new ArrayList<>();
- }
-}
\ No newline at end of file
+ private final DebuggingTraceRsp debuggingTrace;
+}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Topology.java
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryServiceTopologyRsp.java
similarity index 69%
copy from
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Topology.java
copy to
oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryServiceTopologyRsp.java
index 7b571157db..c421787c38 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Topology.java
+++
b/oap-server/server-query-plugin/debugging-query-plugin/src/main/java/org/apache/skywalking/oap/query/debug/topology/DebuggingQueryServiceTopologyRsp.java
@@ -16,19 +16,19 @@
*
*/
-package org.apache.skywalking.oap.server.core.query.type;
+package org.apache.skywalking.oap.query.debug.topology;
-import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.skywalking.oap.query.debug.DebuggingTraceRsp;
+import org.apache.skywalking.oap.server.core.query.type.Call;
+import org.apache.skywalking.oap.server.core.query.type.Node;
+@RequiredArgsConstructor
@Getter
-public class Topology {
+public class DebuggingQueryServiceTopologyRsp {
private final List<Node> nodes;
private final List<Call> calls;
-
- public Topology() {
- this.nodes = new ArrayList<>();
- this.calls = new ArrayList<>();
- }
+ private final DebuggingTraceRsp debuggingTrace;
}
diff --git
a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/TopologyQuery.java
b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/TopologyQuery.java
index 7328a272af..b161b4cbb3 100644
---
a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/TopologyQuery.java
+++
b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/TopologyQuery.java
@@ -29,8 +29,12 @@ import
org.apache.skywalking.oap.server.core.query.type.EndpointTopology;
import org.apache.skywalking.oap.server.core.query.type.ProcessTopology;
import
org.apache.skywalking.oap.server.core.query.type.ServiceInstanceTopology;
import org.apache.skywalking.oap.server.core.query.type.Topology;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingSpan;
+import
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import static
org.apache.skywalking.oap.server.core.query.type.debugging.DebuggingTraceContext.TRACE_CONTEXT;
+
public class TopologyQuery implements GraphQLQueryResolver {
private final ModuleManager moduleManager;
@@ -47,31 +51,97 @@ public class TopologyQuery implements GraphQLQueryResolver {
return queryService;
}
- public Topology getGlobalTopology(final Duration duration, final String
layer) throws IOException {
- return getQueryService().getGlobalTopology(duration, layer);
+ public Topology getGlobalTopology(final Duration duration,
+ final String layer,
+ final boolean debug) throws IOException {
+ DebuggingTraceContext traceContext = new DebuggingTraceContext(
+ "Duration: " + duration + ", Layer: " + layer, debug, false);
+ DebuggingTraceContext.TRACE_CONTEXT.set(traceContext);
+ DebuggingSpan span = traceContext.createSpan("Query global topology");
+ try {
+ Topology topology = getQueryService().getGlobalTopology(duration,
layer);
+ if (debug) {
+ topology.setDebuggingTrace(traceContext.getExecTrace());
+ }
+ return topology;
+ } finally {
+ traceContext.stopSpan(span);
+ traceContext.stopTrace();
+ TRACE_CONTEXT.remove();
+ }
}
- public Topology getServiceTopology(final String serviceId, final Duration
duration) throws IOException {
- List<String> selectedServiceList = new ArrayList<>(1);
- selectedServiceList.add(serviceId);
- return this.getServicesTopology(selectedServiceList, duration);
+ public Topology getServiceTopology(final String serviceId,
+ final Duration duration,
+ final boolean debug) throws IOException
{
+ DebuggingTraceContext traceContext = new DebuggingTraceContext(
+ "ServiceId: " + serviceId + "Duration: " + duration, debug, false);
+ DebuggingTraceContext.TRACE_CONTEXT.set(traceContext);
+ DebuggingSpan span = traceContext.createSpan("Query service topology");
+ try {
+ List<String> selectedServiceList = new ArrayList<>(1);
+ selectedServiceList.add(serviceId);
+ Topology topology = this.getServicesTopology(selectedServiceList,
duration, debug);
+ if (debug) {
+ topology.setDebuggingTrace(traceContext.getExecTrace());
+ }
+ return topology;
+ } finally {
+
+ traceContext.stopSpan(span);
+ traceContext.stopTrace();
+ TRACE_CONTEXT.remove();
+ }
}
- public Topology getServicesTopology(final List<String> serviceIds, final
Duration duration) throws IOException {
- return getQueryService().getServiceTopology(duration, serviceIds);
+ public Topology getServicesTopology(final List<String> serviceIds,
+ final Duration duration,
+ final boolean debug) throws
IOException {
+ DebuggingTraceContext traceContext = new DebuggingTraceContext(
+ "ServiceIds: " + serviceIds + "Duration: " + duration, debug,
false);
+ DebuggingTraceContext.TRACE_CONTEXT.set(traceContext);
+ DebuggingSpan span = traceContext.createSpan("Query service topology");
+ try {
+ Topology topology = getQueryService().getServiceTopology(duration,
serviceIds);
+ if (debug) {
+ topology.setDebuggingTrace(traceContext.getExecTrace());
+ }
+ return topology;
+ } finally {
+ traceContext.stopSpan(span);
+ traceContext.stopTrace();
+ TRACE_CONTEXT.remove();
+ }
}
public ServiceInstanceTopology getServiceInstanceTopology(final String
clientServiceId,
final String
serverServiceId,
- final Duration
duration) throws IOException {
- return getQueryService().getServiceInstanceTopology(
- clientServiceId, serverServiceId,
- duration
+ final Duration
duration,
+ final boolean
debug) throws IOException {
+ DebuggingTraceContext traceContext = new DebuggingTraceContext(
+ "ClientServiceId: " + clientServiceId + ", ServerServiceId: " +
serverServiceId + ", Duration: " + duration,
+ debug, false
);
+ DebuggingTraceContext.TRACE_CONTEXT.set(traceContext);
+ DebuggingSpan span = traceContext.createSpan("Query service instance
topology");
+ try {
+ ServiceInstanceTopology topology =
getQueryService().getServiceInstanceTopology(
+ clientServiceId, serverServiceId,
+ duration
+ );
+ if (debug) {
+ topology.setDebuggingTrace(traceContext.getExecTrace());
+ }
+ return topology;
+ } finally {
+ traceContext.stopSpan(span);
+ traceContext.stopTrace();
+ TRACE_CONTEXT.remove();
+ }
}
/**
- * Replaced by {@link #getEndpointDependencies(String, Duration)}
+ * Replaced by {@link #getEndpointDependencies(String, Duration, boolean)}
*/
@Deprecated
public Topology getEndpointTopology(final String endpointId, final
Duration duration) throws IOException {
@@ -79,11 +149,40 @@ public class TopologyQuery implements GraphQLQueryResolver
{
}
public EndpointTopology getEndpointDependencies(final String endpointId,
- final Duration duration)
throws IOException {
- return getQueryService().getEndpointDependencies(duration, endpointId);
+ final Duration duration,
+ final boolean debug)
throws IOException {
+ DebuggingTraceContext traceContext = new DebuggingTraceContext(
+ "EndpointId: " + endpointId + ", Duration: " + duration, debug,
false);
+ DebuggingTraceContext.TRACE_CONTEXT.set(traceContext);
+ DebuggingSpan span = traceContext.createSpan("Query endpoint
dependencies");
+ try {
+ EndpointTopology topology =
getQueryService().getEndpointDependencies(duration, endpointId);
+ if (debug) {
+ topology.setDebuggingTrace(traceContext.getExecTrace());
+ }
+ return topology;
+ } finally {
+ traceContext.stopSpan(span);
+ traceContext.stopTrace();
+ TRACE_CONTEXT.remove();
+ }
}
- public ProcessTopology getProcessTopology(final String instanceId, final
Duration duration) throws Exception {
- return getQueryService().getProcessTopology(instanceId, duration);
+ public ProcessTopology getProcessTopology(final String instanceId, final
Duration duration, final boolean debug) throws Exception {
+ DebuggingTraceContext traceContext = new DebuggingTraceContext(
+ "InstanceId: " + instanceId + ", Duration: " + duration, debug,
false);
+ DebuggingTraceContext.TRACE_CONTEXT.set(traceContext);
+ DebuggingSpan span = traceContext.createSpan("Query process topology");
+ try {
+ ProcessTopology topology =
getQueryService().getProcessTopology(instanceId, duration);
+ if (debug) {
+ topology.setDebuggingTrace(traceContext.getExecTrace());
+ }
+ return topology;
+ } finally {
+ traceContext.stopSpan(span);
+ traceContext.stopTrace();
+ TRACE_CONTEXT.remove();
+ }
}
}
diff --git
a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
index ee577ac283..e93484a89c 160000
---
a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
+++
b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
@@ -1 +1 @@
-Subproject commit ee577ac283c1e0b418d9da502deba41dfbcb28c3
+Subproject commit e93484a89c9d59fda8303f1dc3cac78e64f56bf7
diff --git
a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBTopologyQueryDAO.java
b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBTopologyQueryDAO.java
index e1cd297ee3..e91fe30d43 100644
---
a/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBTopologyQueryDAO.java
+++
b/oap-server/server-storage-plugin/storage-banyandb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/banyandb/measure/BanyanDBTopologyQueryDAO.java
@@ -34,6 +34,7 @@ import org.apache.skywalking.banyandb.v1.client.MeasureQuery;
import org.apache.skywalking.banyandb.v1.client.MeasureQueryResponse;
import org.apache.skywalking.banyandb.v1.client.TimestampRange;
import org.apache.skywalking.oap.server.core.UnexpectedException;
+import org.apache.skywalking.oap.server.core.analysis.DownSampling;
import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
import
org.apache.skywalking.oap.server.core.analysis.manual.relation.endpoint.EndpointRelationServerSideMetrics;
import
org.apache.skywalking.oap.server.core.analysis.manual.relation.instance.ServiceInstanceRelationClientSideMetrics;
@@ -205,7 +206,7 @@ public class BanyanDBTopologyQueryDAO extends
AbstractBanyanDBDAO implements ITo
final String modelName = detectPoint == DetectPoint.SERVER ?
ServiceInstanceRelationServerSideMetrics.INDEX_NAME :
ServiceInstanceRelationClientSideMetrics.INDEX_NAME;
MetadataRegistry.Schema schema =
MetadataRegistry.INSTANCE.findMetadata(modelName, duration.getStep());
- MeasureQueryResponse resp = query(schema,
+ MeasureQueryResponse resp = queryDebuggable(schema,
ImmutableSet.of(
Metrics.ENTITY_ID
),
@@ -269,7 +270,7 @@ public class BanyanDBTopologyQueryDAO extends
AbstractBanyanDBDAO implements ITo
timestampRange = new
TimestampRange(TimeBucket.getTimestamp(startTB),
TimeBucket.getTimestamp(endTB));
}
MetadataRegistry.Schema schema =
MetadataRegistry.INSTANCE.findMetadata(EndpointRelationServerSideMetrics.INDEX_NAME,
duration.getStep());
- MeasureQueryResponse resp = query(schema,
+ MeasureQueryResponse resp = queryDebuggable(schema,
ImmutableSet.of(
Metrics.ENTITY_ID
),
@@ -303,8 +304,9 @@ public class BanyanDBTopologyQueryDAO extends
AbstractBanyanDBDAO implements ITo
}
final String modelName = detectPoint == DetectPoint.SERVER ?
ProcessRelationServerSideMetrics.INDEX_NAME :
ProcessRelationClientSideMetrics.INDEX_NAME;
- MetadataRegistry.Schema schema =
MetadataRegistry.INSTANCE.findMetadata(modelName, duration.getStep());
- MeasureQueryResponse resp = query(schema,
+ // process relation only has minute data
+ MetadataRegistry.Schema schema =
MetadataRegistry.INSTANCE.findMetadata(modelName, DownSampling.Minute);
+ MeasureQueryResponse resp = queryDebuggable(schema,
ImmutableSet.of(Metrics.ENTITY_ID,
ProcessRelationClientSideMetrics.COMPONENT_ID),
Collections.emptySet(), timestampRange, new
QueryBuilder<MeasureQuery>() {
@Override
diff --git
a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/base/EsDAO.java
b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/base/EsDAO.java
index 4af0614790..e070eccb6b 100644
---
a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/base/EsDAO.java
+++
b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/base/EsDAO.java
@@ -65,6 +65,10 @@ public abstract class EsDAO extends
AbstractDAO<ElasticSearchClient> {
}
}
+ protected SearchResponse searchDebuggable(String indexName, Search search)
{
+ return searchDebuggable(indexName, search, null);
+ }
+
protected SearchResponse searchDebuggable(String indexName, Search search,
SearchParams params) {
DebuggingTraceContext traceContext =
DebuggingTraceContext.TRACE_CONTEXT.get();
DebuggingSpan span = null;
diff --git
a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/RecordsQueryEsDAO.java
b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/RecordsQueryEsDAO.java
index 65023469eb..ce6663f927 100644
---
a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/RecordsQueryEsDAO.java
+++
b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/RecordsQueryEsDAO.java
@@ -71,7 +71,7 @@ public class RecordsQueryEsDAO extends EsDAO implements
IRecordsQueryDAO {
);
final SearchResponse response = searchDebuggable(
IndexController.LogicIndicesRegister.getPhysicalTableName(condition.getName()),
- search.build(), null
+ search.build()
);
List<Record> results = new ArrayList<>(condition.getTopN());
diff --git
a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TopologyQueryEsDAO.java
b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TopologyQueryEsDAO.java
index 0d4f47a1f0..a226c265bb 100644
---
a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TopologyQueryEsDAO.java
+++
b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TopologyQueryEsDAO.java
@@ -260,7 +260,7 @@ public class TopologyQueryEsDAO extends EsDAO implements
ITopologyQueryDAO {
if (IndexController.LogicIndicesRegister.isMergedTable(indexName)) {
query.must(Query.term(IndexController.LogicIndicesRegister.METRIC_TABLE_NAME,
indexName));
}
- final SearchResponse response = getClient().search(index,
sourceBuilder.build());
+ final SearchResponse response = searchDebuggable(index,
sourceBuilder.build());
final List<Call.CallDetail> calls = new ArrayList<>();
final Map<String, Object> entityTerms =
@@ -300,7 +300,7 @@ public class TopologyQueryEsDAO extends EsDAO implements
ITopologyQueryDAO {
final String index =
IndexController.LogicIndicesRegister.getPhysicalTableName(indexName);
- final SearchResponse response = getClient().search(index,
sourceBuilder.build());
+ final SearchResponse response = searchDebuggable(index,
sourceBuilder.build());
final List<Call.CallDetail> calls = new ArrayList<>();
final Map<String, Object> entityTerms =
@@ -337,7 +337,7 @@ public class TopologyQueryEsDAO extends EsDAO implements
ITopologyQueryDAO {
final String index =
IndexController.LogicIndicesRegister.getPhysicalTableName(indexName);
- SearchResponse response = getClient().search(index,
sourceBuilder.build());
+ SearchResponse response = searchDebuggable(index,
sourceBuilder.build());
List<Call.CallDetail> calls = new ArrayList<>();
final Map<String, Object> entityTerms =
@@ -365,7 +365,7 @@ public class TopologyQueryEsDAO extends EsDAO implements
ITopologyQueryDAO {
final String index =
IndexController.LogicIndicesRegister.getPhysicalTableName(indexName);
- final SearchResponse response = getClient().search(index,
sourceBuilder.build());
+ final SearchResponse response = searchDebuggable(index,
sourceBuilder.build());
final List<Call.CallDetail> calls = new ArrayList<>();
final Map<String, Object> entityTerms =