Support tracing topology query for debugging (#12413)

This commit is contained in:
Wan Kai 2024-07-04 15:09:53 +08:00 committed by GitHub
parent e96b75f186
commit 98ef399410
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 1196 additions and 151 deletions

View File

@ -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
}
```

View File

@ -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.

View File

@ -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,26 +646,7 @@ type TraceBrief {
#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,
just enable the debug parameter to true.
#### Tracing SkyWalking API queryTrace
- Bundle API: [Trace](../api/query-protocol.md#trace)
```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
...
}
```
```graphql
# The trace represents a distributed trace, includes all segments and spans.
type Trace {
...
@ -434,3 +659,61 @@ type Trace {
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 Topology Query
- Bundle API: [Topology](../api/query-protocol.md#topology)
```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, 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 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.

View File

@ -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;
}
}

View File

@ -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: {}",

View File

@ -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) {

View File

@ -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<>();

View File

@ -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(
DebuggingTraceContext traceContext = TRACE_CONTEXT.get();
DebuggingSpan span = null;
try {
if (traceContext != null) {
span = traceContext.createSpan("Query Service: getEndpointDependencies");
span.setMsg("Duration: " + duration + ", EndpointId: " + endpointId);
}
return invokeGetEndpointDependencies(duration, endpointId);
} finally {
if (traceContext != null && span != null) {
traceContext.stopSpan(span);
}
}
}
private EndpointTopology invokeGetEndpointDependencies(final Duration duration,
final String endpointId) throws IOException {
List<Call.CallDetail> serverSideCalls = getTopologyQueryDAO().loadEndpointRelationDebuggable(
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());
}
if (!nodeIds.contains(call.getTarget())) {
topology.getNodes().add(buildEndpointDependencyNode(call.getTarget()));
nodeIds.add(call.getTarget());
}
});
return topology;
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;
}
}

View File

@ -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<>();

View File

@ -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<>();
}
}
}

View File

@ -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<>();

View File

@ -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<>();

View File

@ -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
*/

View File

@ -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(

View File

@ -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);
}
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.topology;
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 DebuggingQueryEndpointTopologyRsp {
private final List<EndpointNode> nodes;
private final List<Call> calls;
private final DebuggingTraceRsp debuggingTrace;
}

View File

@ -0,0 +1,34 @@
/*
* 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.topology;
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 DebuggingQueryInstanceTopologyRsp {
private final List<ServiceInstanceNode> nodes;
private final List<Call> calls;
private final DebuggingTraceRsp debuggingTrace;
}

View File

@ -0,0 +1,34 @@
/*
* 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.topology;
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 DebuggingQueryProcessTopologyRsp {
private final List<ProcessNode> nodes;
private final List<Call> calls;
private final DebuggingTraceRsp debuggingTrace;
}

View File

@ -0,0 +1,34 @@
/*
* 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.topology;
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 DebuggingQueryServiceTopologyRsp {
private final List<Node> nodes;
private final List<Call> calls;
private final DebuggingTraceRsp debuggingTrace;
}

View File

@ -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();
}
}
}

@ -1 +1 @@
Subproject commit ee577ac283c1e0b418d9da502deba41dfbcb28c3
Subproject commit e93484a89c9d59fda8303f1dc3cac78e64f56bf7

View File

@ -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

View File

@ -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;

View File

@ -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());

View File

@ -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 =