This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 9dc4fd3b01 Support available layers of service in the topology.
(#11844)
9dc4fd3b01 is described below
commit 9dc4fd3b01e7e13d5a3cb83753e2fb74784b0ad8
Author: Wan Kai <[email protected]>
AuthorDate: Tue Jan 30 12:51:15 2024 +0800
Support available layers of service in the topology. (#11844)
---
docs/en/changes/changes.md | 7 ++-
docs/en/swip/SWIP-4.md | 57 ++++++++++++++++++++++
docs/en/swip/readme.md | 1 +
.../server/core/query/ServiceTopologyBuilder.java | 19 ++++++++
.../oap/server/core/query/type/Node.java | 5 ++
.../HierarchyQueryServiceTest.java | 2 +-
.../core/query/ServiceTopologyBuilderTest.java | 51 ++++++++++++++++---
.../src/main/resources/query-protocol | 2 +-
skywalking-ui | 2 +-
9 files changed, 134 insertions(+), 12 deletions(-)
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 6e7f129229..662bd179ed 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -38,13 +38,14 @@
- VIRTUAL_DATABASE -> MYSQL
- VIRTUAL_DATABASE -> POSTGRESQL
* Add Golang as a supported language for AMQP.
+* Support available layers of service in the topology.
#### UI
* Fix the mismatch between the unit and calculation of the "Network Bandwidth
Usage" widget in Linux-Service Dashboard.
* Add theme change animation.
* Implement the Service and Instance hierarchy topology.
-* Support Tabs in the widget visiable when MQE expressions.
+* Support Tabs in the widget visible when MQE expressions.
* Support search on Marketplace.
* Fix default route.
* Fix layout on the Log widget.
@@ -55,6 +56,10 @@
* Fix dashboard `K8S-Service-Root` metrics expression.
* Add dashboards for Service/Instance Hierarchy.
* Fix MQE in dashboards when using `Card widget`.
+* Optimize tooltips style.
+* Fix resizing window causes the trace graph to display incorrectly.
+* Add the not found page(404).
+* Enhance VNode logic and support multiple Trace IDs in span's ref.
#### Documentation
diff --git a/docs/en/swip/SWIP-4.md b/docs/en/swip/SWIP-4.md
new file mode 100644
index 0000000000..6db61f6160
--- /dev/null
+++ b/docs/en/swip/SWIP-4.md
@@ -0,0 +1,57 @@
+# Support available layers of service in the topology.
+
+## Motivation
+
+UI could jump to the service dashboard and query service hierarchy from the
topology node.
+For now topology node includes name and ID but without layer, as the service
could have multiple layers,
+the limitation is that it is only works on the current layer which the
topology represents:
+1. UI could not jump into another layer's dashboard of the service.
+2. UI could not query the service hierarchy from the topology node if the node
is not in current layer.
+
+Here are typical use cases:
+should have a chance to jump into another layer's dashboard of the service:
+1. In the mesh topology, mesh(layer MESH) and mesh-dp(layer MESH_DP) share a
similar topology, one node will have two layers.
+2. In the mesh topology, agent(layer GENERAL) + virtual database(layer
VIRTUAL_DATABASE), the node is in different layers.
+
+Both of these two cases have hybrid layer topology. If we could support that,
we could have a better x-layer interaction.
+
+## Architecture Graph
+
+There is no significant architecture-level change.
+
+## Propose Changes
+
+Add the layers info into topology node:
+1. When building the topology node fetch the layers info from the service
according to the service id.
+2. Return `layers` info in the `Node` when query the topology.
+
+## Imported Dependencies libs and their licenses.
+
+No new library is planned to be added to the codebase.
+
+## Compatibility
+
+About the **protocol**, there should be no breaking changes, but enhancements
only. New field `layers` is going to be added to the
+`Node` in the query protocol `topology.graphqls`.
+
+```graphql
+type Node {
+ # The service ID of the node.
+ id: ID!
+ # The literal name of the #id.
+ name: String!
+ # The type name may be
+ # 1. The service provider/middleware tech, such as: Tomcat, SpringMVC
+ # 2. Conjectural Service, e.g. MySQL, Redis, Kafka
+ type: String
+ # It is a conjecture node or real node, to represent a service or endpoint.
+ isReal: Boolean!
+ # The layers of the service.
+ layers: [String!]!
+}
+```
+
+## General usage docs
+
+This proposal doesn't impact the end user in any way of using SkyWalking. The
remarkable change will be in the UI topology map,
+users could jump into the proper layer's service dashboard and query the
service hierarchy from the topology node.
diff --git a/docs/en/swip/readme.md b/docs/en/swip/readme.md
index 0e0c031a2d..3961e7d89c 100644
--- a/docs/en/swip/readme.md
+++ b/docs/en/swip/readme.md
@@ -71,6 +71,7 @@ All accepted and proposed SWIPs could be found in
[here](https://github.com/apac
Next SWIP Number: 4
### Accepted SWIPs
+- [SWIP-4 Support available layers of service in the topology](SWIP-4.md)
- [SWIP-3 Support RocketMQ Monitoring](SWIP-3.md)
- [SWIP-2 Collecting and Gathering Kubernetes Monitoring Data](SWIP-2.md)
- [SWIP-1 Create and detect Service Hierarchy Relationship](SWIP-1.md)
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 288534fb77..181e272e3b 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
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.Const;
import org.apache.skywalking.oap.server.core.CoreModule;
@@ -31,6 +32,7 @@ import
org.apache.skywalking.oap.server.core.cache.NetworkAddressAliasCache;
import
org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
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.source.DetectPoint;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
@@ -41,6 +43,8 @@ class ServiceTopologyBuilder {
private final IComponentLibraryCatalogService
componentLibraryCatalogService;
private final NetworkAddressAliasCache networkAddressAliasCache;
private final String userID;
+ private final ModuleManager moduleManager;
+ private MetadataQueryService metadataQueryService;
ServiceTopologyBuilder(ModuleManager moduleManager) {
this.componentLibraryCatalogService =
moduleManager.find(CoreModule.NAME)
@@ -50,6 +54,16 @@ class ServiceTopologyBuilder {
.provider()
.getService(NetworkAddressAliasCache.class);
this.userID = IDManager.ServiceID.buildId(Const.USER_SERVICE_NAME,
false);
+ this.moduleManager = moduleManager;
+ }
+
+ private MetadataQueryService getMetadataQueryService() {
+ if (metadataQueryService == null) {
+ this.metadataQueryService = moduleManager.find(CoreModule.NAME)
+ .provider()
+
.getService(MetadataQueryService.class);
+ }
+ return metadataQueryService;
}
Topology build(List<Call.CallDetail> serviceRelationClientCalls,
List<Call.CallDetail> serviceRelationServerCalls) {
@@ -193,11 +207,16 @@ class ServiceTopologyBuilder {
return topology;
}
+ @SneakyThrows
private Node buildNode(String sourceId,
IDManager.ServiceID.ServiceIDDefinition sourceService) {
Node serviceNode = new Node();
serviceNode.setId(sourceId);
serviceNode.setName(sourceService.getName());
serviceNode.setReal(sourceService.isReal());
+ Service service = getMetadataQueryService().getService(sourceId);
+ if (service != null) {
+ serviceNode.getLayers().addAll(service.getLayers());
+ }
return serviceNode;
}
}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Node.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Node.java
index cb224bd2b1..a9ef562dbd 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Node.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Node.java
@@ -18,6 +18,8 @@
package org.apache.skywalking.oap.server.core.query.type;
+import java.util.HashSet;
+import java.util.Set;
import lombok.Getter;
import lombok.Setter;
import org.apache.skywalking.oap.server.core.query.NotGraphQLField;
@@ -35,6 +37,9 @@ public class Node {
@Getter
@Setter
private boolean isReal;
+ @Getter
+ @Setter
+ private Set<String> layers = new HashSet<>();
/**
* A flag indicate whether the {@link #type} has been set from the call
detected from service side.
diff --git
a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/Hierarchy/HierarchyQueryServiceTest.java
b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/hierarchy/HierarchyQueryServiceTest.java
similarity index 99%
rename from
oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/Hierarchy/HierarchyQueryServiceTest.java
rename to
oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/hierarchy/HierarchyQueryServiceTest.java
index 8049ca52c3..f0310eac0d 100644
---
a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/Hierarchy/HierarchyQueryServiceTest.java
+++
b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/hierarchy/HierarchyQueryServiceTest.java
@@ -16,7 +16,7 @@
*
*/
-package org.apache.skywalking.oap.server.core.Hierarchy;
+package org.apache.skywalking.oap.server.core.hierarchy;
import java.util.HashMap;
import java.util.Map;
diff --git
a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilderTest.java
b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilderTest.java
index f5905fd743..a643a668c0 100644
---
a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilderTest.java
+++
b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilderTest.java
@@ -20,17 +20,21 @@ package org.apache.skywalking.oap.server.core.query;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
+import lombok.SneakyThrows;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.CoreModuleConfig;
import org.apache.skywalking.oap.server.core.CoreModuleProvider;
import org.apache.skywalking.oap.server.core.MockModuleManager;
import org.apache.skywalking.oap.server.core.MockModuleProvider;
import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.analysis.Layer;
import org.apache.skywalking.oap.server.core.cache.NetworkAddressAliasCache;
import
org.apache.skywalking.oap.server.core.config.ComponentLibraryCatalogService;
import
org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
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.source.DetectPoint;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
@@ -38,14 +42,19 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
+import org.powermock.reflect.Whitebox;
+
+import static org.mockito.Mockito.when;
public class ServiceTopologyBuilderTest {
private CoreModuleProvider moduleProvider;
private ModuleManager moduleManager;
+ private MetadataQueryService metadataQueryService;
@BeforeEach
public void setupMetrics() throws Throwable {
moduleProvider = Mockito.mock(CoreModuleProvider.class);
+ metadataQueryService = Mockito.mock(MetadataQueryService.class);
moduleManager = new MockModuleManager() {
@Override
protected void init() {
@@ -62,16 +71,22 @@ public class ServiceTopologyBuilderTest {
};
}
+ @SneakyThrows
@Test
public void testServiceTopologyBuild() {
+ Service svrA = getSvrA();
+ Service svrB = getSvrB();
final ServiceTopologyBuilder serviceTopologyBuilder = new
ServiceTopologyBuilder(moduleManager);
+ Whitebox.setInternalState(serviceTopologyBuilder,
"metadataQueryService", metadataQueryService);
+ when(metadataQueryService.getService(svrA.getId())).thenReturn(svrA);
+ when(metadataQueryService.getService(svrB.getId())).thenReturn(svrB);
List<Call.CallDetail> serviceRelationClientCalls = new ArrayList<>();
Call.CallDetail call1 = new Call.CallDetail();
call1.buildFromServiceRelation(
IDManager.ServiceID.buildRelationId(
new IDManager.ServiceID.ServiceRelationDefine(
- IDManager.ServiceID.buildId("SvrA", true),
- IDManager.ServiceID.buildId("SvrB", true)
+ IDManager.ServiceID.buildId(svrA.getName(), true),
+ IDManager.ServiceID.buildId(svrB.getName(), true)
)
),
// mtls
@@ -83,8 +98,8 @@ public class ServiceTopologyBuilderTest {
call2.buildFromServiceRelation(
IDManager.ServiceID.buildRelationId(
new IDManager.ServiceID.ServiceRelationDefine(
- IDManager.ServiceID.buildId("SvrA", true),
- IDManager.ServiceID.buildId("SvrB", true)
+ IDManager.ServiceID.buildId(svrA.getName(), true),
+ IDManager.ServiceID.buildId(svrB.getName(), true)
)
),
// http
@@ -98,8 +113,8 @@ public class ServiceTopologyBuilderTest {
call3.buildFromServiceRelation(
IDManager.ServiceID.buildRelationId(
new IDManager.ServiceID.ServiceRelationDefine(
- IDManager.ServiceID.buildId("SvrA", true),
- IDManager.ServiceID.buildId("SvrB", true)
+ IDManager.ServiceID.buildId(svrA.getName(), true),
+ IDManager.ServiceID.buildId(svrB.getName(), true)
)
),
// mtls
@@ -111,8 +126,8 @@ public class ServiceTopologyBuilderTest {
call4.buildFromServiceRelation(
IDManager.ServiceID.buildRelationId(
new IDManager.ServiceID.ServiceRelationDefine(
- IDManager.ServiceID.buildId("SvrA", true),
- IDManager.ServiceID.buildId("SvrB", true)
+ IDManager.ServiceID.buildId(svrA.getName(), true),
+ IDManager.ServiceID.buildId(svrB.getName(), true)
)
),
// http
@@ -125,8 +140,10 @@ public class ServiceTopologyBuilderTest {
for (final Node node : topology.getNodes()) {
if (node.getName().equals("SvrB")) {
Assertions.assertEquals("http", node.getType());
+ Assertions.assertEquals(Set.of(Layer.MESH.name(),
Layer.MESH_DP.name()), node.getLayers());
} else if (node.getName().equals("SvrA")) {
Assertions.assertEquals(null, node.getType());
+ Assertions.assertEquals(Set.of(Layer.GENERAL.name()),
node.getLayers());
}
}
for (final Call call : topology.getCalls()) {
@@ -134,4 +151,22 @@ public class ServiceTopologyBuilderTest {
Assertions.assertEquals(List.of("mtls", "http"),
call.getTargetComponents());
}
}
+
+ private Service getSvrA() {
+ Service service = new Service();
+ service.setId(IDManager.ServiceID.buildId("SvrA", true));
+ service.setName("SvrA");
+ service.setShortName("SvrA");
+ service.setLayers(Set.of(Layer.GENERAL.name()));
+ return service;
+ }
+
+ private Service getSvrB() {
+ Service service = new Service();
+ service.setId(IDManager.ServiceID.buildId("SvrB", true));
+ service.setName("SvrB");
+ service.setShortName("SvrB");
+ service.setLayers(Set.of(Layer.MESH.name(), Layer.MESH_DP.name()));
+ return service;
+ }
}
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 72fdfe5660..f0bdba688a 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 72fdfe56603c6a6135f932fb402c0890bb78b4e7
+Subproject commit f0bdba688afecff2167d018ecdaf509d2c8598f7
diff --git a/skywalking-ui b/skywalking-ui
index f76500bb6e..860af150f7 160000
--- a/skywalking-ui
+++ b/skywalking-ui
@@ -1 +1 @@
-Subproject commit f76500bb6e5e796171f393994f88ede62a370b02
+Subproject commit 860af150f71f8dd0a2cbf555c8f7bd97954c5e53