Support build Service/Instance Hierarchy and query. (#11698)
This commit is contained in:
parent
9ba0ad2991
commit
ce5d6a4ffb
|
|
@ -59,6 +59,7 @@
|
|||
<include>endpoint-name-grouping.yml</include>
|
||||
<include>metadata-service-mapping.yaml</include>
|
||||
<include>trace-sampling-policy-settings.yml</include>
|
||||
<include>hierarchy-definition.yml</include>
|
||||
<include>oal/*.oal</include>
|
||||
<include>fetcher-prom-rules/*.yaml</include>
|
||||
<include>envoy-metrics-rules/**</include>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
service metadata.
|
||||
* Set up the length of source and dest IDs in relation entities of service, instance, endpoint, and process to 250(was
|
||||
200).
|
||||
* Support build Service/Instance Hierarchy and query.
|
||||
|
||||
#### UI
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ extend type Query {
|
|||
# Query the service hierarchy, based on the given service. Will recursively return all related layers services in the hierarchy.
|
||||
getServiceHierarchy(serviceId: ID!, layer: String!): ServiceHierarchy!
|
||||
# Query the instance hierarchy, based on the given instance. Will return all direct related layers instances in the hierarchy, no recursive.
|
||||
getInstanceHierarchy(instanceId: ID!): InstanceHierarchy!
|
||||
getInstanceHierarchy(instanceId: ID!, layer: String!): InstanceHierarchy!
|
||||
}
|
||||
```
|
||||
New fields are going to be added to the `topology.graphqls`.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ import org.apache.skywalking.oap.server.core.command.CommandService;
|
|||
import org.apache.skywalking.oap.server.core.config.ConfigService;
|
||||
import org.apache.skywalking.oap.server.core.config.DownSamplingConfigService;
|
||||
import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
|
||||
import org.apache.skywalking.oap.server.core.config.HierarchyDefinitionService;
|
||||
import org.apache.skywalking.oap.server.core.config.NamingControl;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.HierarchyService;
|
||||
import org.apache.skywalking.oap.server.core.management.ui.menu.UIMenuManagementService;
|
||||
import org.apache.skywalking.oap.server.core.management.ui.template.UITemplateManagementService;
|
||||
import org.apache.skywalking.oap.server.core.oal.rt.OALEngineLoaderService;
|
||||
|
|
@ -41,6 +43,7 @@ import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
|
|||
import org.apache.skywalking.oap.server.core.query.AlarmQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.BrowserLogQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.EventQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.HierarchyQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.LogQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.MetadataQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.MetricsMetadataQueryService;
|
||||
|
|
@ -81,6 +84,7 @@ public class CoreModule extends ModuleDefine {
|
|||
classes.add(DownSamplingConfigService.class);
|
||||
classes.add(NamingControl.class);
|
||||
classes.add(IComponentLibraryCatalogService.class);
|
||||
classes.add(HierarchyDefinitionService.class);
|
||||
|
||||
classes.add(IWorkerInstanceGetter.class);
|
||||
classes.add(IWorkerInstanceSetter.class);
|
||||
|
|
@ -98,7 +102,7 @@ public class CoreModule extends ModuleDefine {
|
|||
addEBPFProfilingService(classes);
|
||||
|
||||
classes.add(CommandService.class);
|
||||
|
||||
classes.add(HierarchyService.class);
|
||||
return classes.toArray(new Class[]{});
|
||||
}
|
||||
|
||||
|
|
@ -138,6 +142,7 @@ public class CoreModule extends ModuleDefine {
|
|||
classes.add(EventQueryService.class);
|
||||
classes.add(TagAutoCompleteQueryService.class);
|
||||
classes.add(RecordQueryService.class);
|
||||
classes.add(HierarchyQueryService.class);
|
||||
}
|
||||
|
||||
private void addServerInterface(List<Class> classes) {
|
||||
|
|
|
|||
|
|
@ -223,6 +223,14 @@ public class CoreModuleConfig extends ModuleConfig {
|
|||
@Getter
|
||||
private int serviceCacheRefreshInterval = 10;
|
||||
|
||||
/**
|
||||
* If disable the hierarchy, the service and instance hierarchy relation will not be built.
|
||||
* And the query of hierarchy will return empty result.
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
private boolean enableHierarchy = true;
|
||||
|
||||
public CoreModuleConfig() {
|
||||
this.downsampling = new ArrayList<>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,11 +44,13 @@ import org.apache.skywalking.oap.server.core.command.CommandService;
|
|||
import org.apache.skywalking.oap.server.core.config.ComponentLibraryCatalogService;
|
||||
import org.apache.skywalking.oap.server.core.config.ConfigService;
|
||||
import org.apache.skywalking.oap.server.core.config.DownSamplingConfigService;
|
||||
import org.apache.skywalking.oap.server.core.config.HierarchyDefinitionService;
|
||||
import org.apache.skywalking.oap.server.core.config.IComponentLibraryCatalogService;
|
||||
import org.apache.skywalking.oap.server.core.config.NamingControl;
|
||||
import org.apache.skywalking.oap.server.core.config.group.EndpointNameGrouping;
|
||||
import org.apache.skywalking.oap.server.core.config.group.EndpointNameGroupingRuleWatcher;
|
||||
import org.apache.skywalking.oap.server.core.config.group.openapi.EndpointNameGroupingRule4OpenapiWatcher;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.HierarchyService;
|
||||
import org.apache.skywalking.oap.server.core.logging.LoggingConfigWatcher;
|
||||
import org.apache.skywalking.oap.server.core.management.ui.menu.UIMenuInitializer;
|
||||
import org.apache.skywalking.oap.server.core.management.ui.menu.UIMenuManagementService;
|
||||
|
|
@ -66,6 +68,7 @@ import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
|
|||
import org.apache.skywalking.oap.server.core.query.AlarmQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.BrowserLogQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.EventQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.HierarchyQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.LogQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.MetadataQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.MetricsMetadataQueryService;
|
||||
|
|
@ -253,6 +256,8 @@ public class CoreModuleProvider extends ModuleProvider {
|
|||
|
||||
this.registerServiceImplementation(ConfigService.class, new ConfigService(moduleConfig, this));
|
||||
this.registerServiceImplementation(ServerStatusService.class, new ServerStatusService(getManager(), moduleConfig));
|
||||
this.registerServiceImplementation(HierarchyDefinitionService.class, new HierarchyDefinitionService(moduleConfig));
|
||||
this.registerServiceImplementation(HierarchyService.class, new HierarchyService(getManager(), moduleConfig));
|
||||
this.registerServiceImplementation(
|
||||
DownSamplingConfigService.class, new DownSamplingConfigService(moduleConfig.getDownsampling()));
|
||||
|
||||
|
|
@ -293,6 +298,7 @@ public class CoreModuleProvider extends ModuleProvider {
|
|||
this.registerServiceImplementation(
|
||||
TagAutoCompleteQueryService.class, new TagAutoCompleteQueryService(getManager(), moduleConfig));
|
||||
this.registerServiceImplementation(RecordQueryService.class, new RecordQueryService(getManager()));
|
||||
this.registerServiceImplementation(HierarchyQueryService.class, new HierarchyQueryService(getManager(), moduleConfig));
|
||||
|
||||
// add profile service implementations
|
||||
this.registerServiceImplementation(
|
||||
|
|
|
|||
|
|
@ -71,6 +71,15 @@ public class IDManager {
|
|||
return define.sourceId + Const.RELATION_ID_CONNECTOR + define.destId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return encoded service hierarchy relation id
|
||||
*/
|
||||
public static String buildServiceHierarchyRelationId(ServiceHierarchyRelationDefine define) {
|
||||
return define.serviceId + Const.SERVICE_ID_CONNECTOR + define.serviceLayer.value() +
|
||||
Const.RELATION_ID_CONNECTOR +
|
||||
define.relatedServiceId + Const.SERVICE_ID_CONNECTOR + define.relatedServiceLayer.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return service relation ID object decoded from {@link #buildRelationId(ServiceRelationDefine)} result
|
||||
*/
|
||||
|
|
@ -100,6 +109,16 @@ public class IDManager {
|
|||
private final String sourceId;
|
||||
private final String destId;
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
public static class ServiceHierarchyRelationDefine {
|
||||
private final String serviceId;
|
||||
private final Layer serviceLayer;
|
||||
private final String relatedServiceId;
|
||||
private final Layer relatedServiceLayer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -140,6 +159,15 @@ public class IDManager {
|
|||
return define.sourceId + Const.RELATION_ID_CONNECTOR + define.destId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return encoded instance hierarchy relation id
|
||||
*/
|
||||
public static String buildInstanceHierarchyRelationId(InstanceHierarchyRelationDefine define) {
|
||||
return define.instanceId + Const.SERVICE_ID_CONNECTOR + define.serviceLayer.value() +
|
||||
Const.RELATION_ID_CONNECTOR +
|
||||
define.relatedInstanceId + Const.SERVICE_ID_CONNECTOR + define.relatedServiceLayer.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return service instance relation ID object decoded from {@link #buildRelationId(ServiceInstanceRelationDefine)}
|
||||
* result
|
||||
|
|
@ -175,6 +203,16 @@ public class IDManager {
|
|||
*/
|
||||
private final String destId;
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
public static class InstanceHierarchyRelationDefine {
|
||||
private final String instanceId;
|
||||
private final Layer serviceLayer;
|
||||
private final String relatedInstanceId;
|
||||
private final Layer relatedServiceLayer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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.config;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.Reader;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.skywalking.oap.server.core.CoreModuleConfig;
|
||||
import org.apache.skywalking.oap.server.core.UnexpectedException;
|
||||
import org.apache.skywalking.oap.server.library.module.Service;
|
||||
import org.apache.skywalking.oap.server.library.util.ResourceUtils;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
@Slf4j
|
||||
public class HierarchyDefinitionService implements Service {
|
||||
@Getter
|
||||
private Map<String, List<String>> hierarchyDefinition;
|
||||
|
||||
public HierarchyDefinitionService(CoreModuleConfig moduleConfig) {
|
||||
this.hierarchyDefinition = new HashMap<>();
|
||||
if (moduleConfig.isEnableHierarchy()) {
|
||||
this.init();
|
||||
this.checkLayers();
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
try {
|
||||
Reader applicationReader = ResourceUtils.read("hierarchy-definition.yml");
|
||||
Yaml yaml = new Yaml();
|
||||
this.hierarchyDefinition = yaml.loadAs(applicationReader, Map.class);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new UnexpectedException("hierarchy-definition.yml not found.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkLayers() {
|
||||
this.hierarchyDefinition.forEach((layer, lowerLayers) -> {
|
||||
if (lowerLayers.contains(layer)) {
|
||||
throw new IllegalArgumentException(
|
||||
"hierarchy-definition.yml " + layer + " contains recursive hierarchy relation.");
|
||||
}
|
||||
checkRecursive(layer);
|
||||
});
|
||||
}
|
||||
|
||||
private void checkRecursive(String layerName) {
|
||||
try {
|
||||
List<String> lowerLayers = this.hierarchyDefinition.get(layerName);
|
||||
if (lowerLayers == null) {
|
||||
return;
|
||||
}
|
||||
lowerLayers.forEach(this::checkRecursive);
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalArgumentException(
|
||||
"hierarchy-definition.yml " + layerName + " contains recursive hierarchy relation.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* 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.hierarchy;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.CoreModuleConfig;
|
||||
import org.apache.skywalking.oap.server.core.analysis.Layer;
|
||||
import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
|
||||
import org.apache.skywalking.oap.server.core.config.HierarchyDefinitionService;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.instance.InstanceHierarchyRelation;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.service.ServiceHierarchyRelation;
|
||||
import org.apache.skywalking.oap.server.core.source.SourceReceiver;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
import org.apache.skywalking.oap.server.library.module.Service;
|
||||
|
||||
@Slf4j
|
||||
public class HierarchyService implements Service {
|
||||
private final ModuleManager moduleManager;
|
||||
private final boolean isEnableHierarchy;
|
||||
private SourceReceiver sourceReceiver;
|
||||
private Map<String, List<String>> hierarchyDefinition;
|
||||
|
||||
public HierarchyService(ModuleManager moduleManager, CoreModuleConfig moduleConfig) {
|
||||
this.moduleManager = moduleManager;
|
||||
this.isEnableHierarchy = moduleConfig.isEnableHierarchy();
|
||||
}
|
||||
|
||||
private SourceReceiver getSourceReceiver() {
|
||||
if (sourceReceiver == null) {
|
||||
this.sourceReceiver = moduleManager.find(CoreModule.NAME).provider().getService(SourceReceiver.class);
|
||||
}
|
||||
return sourceReceiver;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getHierarchyDefinition() {
|
||||
if (hierarchyDefinition == null) {
|
||||
hierarchyDefinition = moduleManager.find(CoreModule.NAME)
|
||||
.provider()
|
||||
.getService(HierarchyDefinitionService.class).getHierarchyDefinition();
|
||||
}
|
||||
return hierarchyDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the hierarchy relation between the 2 services. the `serviceLayer` and `relatedServiceLayer` hierarchy
|
||||
* relations should be defined in `config/hierarchy-definition.yml`. Generally, if service A and service B could detect
|
||||
* each other, then build the hierarchy in one side is enough.
|
||||
*
|
||||
* @param serviceName the name of the source service (self)
|
||||
* @param serviceLayer the layer of the source service
|
||||
* @param relatedServiceName the name of the detected related service
|
||||
* @param relatedServiceLayer the layer of the detected related service
|
||||
*/
|
||||
public void toServiceHierarchyRelation(String serviceName,
|
||||
Layer serviceLayer,
|
||||
String relatedServiceName,
|
||||
Layer relatedServiceLayer) {
|
||||
if (!this.isEnableHierarchy) {
|
||||
return;
|
||||
}
|
||||
if (!checkHierarchyDefinition(serviceLayer, relatedServiceLayer)) {
|
||||
return;
|
||||
}
|
||||
ServiceHierarchyRelation serviceHierarchy = new ServiceHierarchyRelation();
|
||||
serviceHierarchy.setServiceName(serviceName);
|
||||
serviceHierarchy.setServiceLayer(serviceLayer);
|
||||
serviceHierarchy.setRelatedServiceName(relatedServiceName);
|
||||
serviceHierarchy.setRelatedServiceLayer(relatedServiceLayer);
|
||||
serviceHierarchy.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
|
||||
this.getSourceReceiver().receive(serviceHierarchy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the hierarchy relation between the 2 instances. the `serviceLayer` and `relatedServiceLayer` hierarchy
|
||||
* relations should be defined in `config/hierarchy-definition.yml`. Generally, if instance A and instance B could detect
|
||||
* each other, then build the hierarchy in one side is enough.
|
||||
*
|
||||
* @param instanceName the name of the source instance (self)
|
||||
* @param serviceName the name of the source service (self)
|
||||
* @param serviceLayer the layer of the source service
|
||||
* @param relatedInstanceName the name of the detected related instance
|
||||
* @param relatedServiceName the name of the detected related service
|
||||
* @param relatedServiceLayer the layer of the detected related service
|
||||
*/
|
||||
public void toInstanceHierarchyRelation(String instanceName,
|
||||
String serviceName,
|
||||
Layer serviceLayer,
|
||||
String relatedInstanceName,
|
||||
String relatedServiceName,
|
||||
Layer relatedServiceLayer) {
|
||||
if (!this.isEnableHierarchy) {
|
||||
return;
|
||||
}
|
||||
if (!checkHierarchyDefinition(serviceLayer, relatedServiceLayer)) {
|
||||
return;
|
||||
}
|
||||
InstanceHierarchyRelation instanceHierarchy = new InstanceHierarchyRelation();
|
||||
instanceHierarchy.setInstanceName(instanceName);
|
||||
instanceHierarchy.setServiceName(serviceName);
|
||||
instanceHierarchy.setServiceLayer(serviceLayer);
|
||||
instanceHierarchy.setRelatedInstanceName(relatedInstanceName);
|
||||
instanceHierarchy.setRelatedServiceName(relatedServiceName);
|
||||
instanceHierarchy.setRelatedServiceLayer(relatedServiceLayer);
|
||||
instanceHierarchy.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
|
||||
this.getSourceReceiver().receive(instanceHierarchy);
|
||||
}
|
||||
|
||||
private boolean checkHierarchyDefinition(Layer serviceLayer, Layer relatedServiceLayer) {
|
||||
List<String> lowerLayers = getHierarchyDefinition().get(serviceLayer.name());
|
||||
List<String> relatedLowerLayers = getHierarchyDefinition().get(relatedServiceLayer.name());
|
||||
if (lowerLayers == null || relatedLowerLayers == null) {
|
||||
log.error("serviceLayer " + serviceLayer.name() + " or relatedServiceLayer " + relatedServiceLayer.name()
|
||||
+ " is not defined in hierarchy-definition.yml.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!lowerLayers.contains(relatedServiceLayer.name()) || !relatedLowerLayers.contains(serviceLayer.name())) {
|
||||
log.error("serviceLayer " + serviceLayer.name() + " and relatedServiceLayer " + relatedServiceLayer.name()
|
||||
+ " should have the hierarchy relation in hierarchy-definition.yml.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.hierarchy.instance;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
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.source.DefaultScopeDefine;
|
||||
import org.apache.skywalking.oap.server.core.source.ScopeDeclaration;
|
||||
import org.apache.skywalking.oap.server.core.source.Source;
|
||||
|
||||
@ScopeDeclaration(id = DefaultScopeDefine.INSTANCE_HIERARCHY_RELATION, name = "InstanceHierarchyRelation")
|
||||
public class InstanceHierarchyRelation extends Source {
|
||||
@Setter
|
||||
@Getter
|
||||
private String instanceName;
|
||||
@Getter
|
||||
private String instanceId;
|
||||
@Setter
|
||||
@Getter
|
||||
private String serviceName;
|
||||
@Getter
|
||||
private String serviceId;
|
||||
@Setter
|
||||
@Getter
|
||||
private Layer serviceLayer;
|
||||
@Setter
|
||||
@Getter
|
||||
private String relatedInstanceName;
|
||||
@Getter
|
||||
private String relatedInstanceId;
|
||||
@Setter
|
||||
@Getter
|
||||
private String relatedServiceName;
|
||||
@Getter
|
||||
private String relatedServiceId;
|
||||
@Setter
|
||||
@Getter
|
||||
private Layer relatedServiceLayer;
|
||||
|
||||
@Override
|
||||
public int scope() {
|
||||
return DefaultScopeDefine.INSTANCE_HIERARCHY_RELATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
serviceId = IDManager.ServiceID.buildId(serviceName, serviceLayer.isNormal());
|
||||
relatedServiceId = IDManager.ServiceID.buildId(relatedServiceName, relatedServiceLayer.isNormal());
|
||||
instanceId = IDManager.ServiceInstanceID.buildId(serviceId, instanceName);
|
||||
relatedInstanceId = IDManager.ServiceInstanceID.buildId(relatedServiceId, relatedInstanceName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* 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.hierarchy.instance;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
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.analysis.MetricsExtension;
|
||||
import org.apache.skywalking.oap.server.core.analysis.Stream;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
|
||||
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
|
||||
import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
|
||||
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageID;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder;
|
||||
|
||||
@Stream(name = InstanceHierarchyRelationTraffic.INDEX_NAME, scopeId = DefaultScopeDefine.INSTANCE_HIERARCHY_RELATION,
|
||||
builder = InstanceHierarchyRelationTraffic.Builder.class, processor = MetricsStreamProcessor.class)
|
||||
@MetricsExtension(supportDownSampling = false, supportUpdate = false)
|
||||
@EqualsAndHashCode(of = {
|
||||
"instanceId",
|
||||
"serviceLayer",
|
||||
"relatedInstanceId",
|
||||
"relatedServiceLayer"
|
||||
}, callSuper = true)
|
||||
public class InstanceHierarchyRelationTraffic extends Metrics {
|
||||
public static final String INDEX_NAME = "instance_hierarchy_relation";
|
||||
public static final String SERVICE_LAYER = "service_layer";
|
||||
public static final String INSTANCE_ID = "instance_id";
|
||||
public static final String RELATED_SERVICE_LAYER = "related_service_layer";
|
||||
public static final String RELATED_INSTANCE_ID = "related_instance_id";
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Column(name = INSTANCE_ID, length = 250)
|
||||
@BanyanDB.SeriesID(index = 0)
|
||||
private String instanceId;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Column(name = SERVICE_LAYER)
|
||||
@BanyanDB.SeriesID(index = 1)
|
||||
private Layer serviceLayer = Layer.UNDEFINED;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Column(name = RELATED_INSTANCE_ID, length = 250)
|
||||
@BanyanDB.SeriesID(index = 2)
|
||||
private String relatedInstanceId;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Column(name = RELATED_SERVICE_LAYER)
|
||||
@BanyanDB.SeriesID(index = 3)
|
||||
private Layer relatedServiceLayer = Layer.UNDEFINED;
|
||||
|
||||
@Override
|
||||
protected StorageID id0() {
|
||||
String id = IDManager.ServiceInstanceID.buildInstanceHierarchyRelationId(
|
||||
new IDManager.ServiceInstanceID.InstanceHierarchyRelationDefine(
|
||||
instanceId, serviceLayer, relatedInstanceId, relatedServiceLayer));
|
||||
return new StorageID().appendMutant(new String[] {
|
||||
INSTANCE_ID,
|
||||
RELATED_INSTANCE_ID,
|
||||
SERVICE_LAYER,
|
||||
RELATED_SERVICE_LAYER
|
||||
}, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean combine(final Metrics metrics) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics toHour() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics toDay() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserialize(final RemoteData remoteData) {
|
||||
setInstanceId(remoteData.getDataStrings(0));
|
||||
setServiceLayer(Layer.valueOf(remoteData.getDataIntegers(0)));
|
||||
setRelatedInstanceId(remoteData.getDataStrings(1));
|
||||
setRelatedServiceLayer(Layer.valueOf(remoteData.getDataIntegers(1)));
|
||||
setTimeBucket(remoteData.getDataLongs(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteData.Builder serialize() {
|
||||
final RemoteData.Builder builder = RemoteData.newBuilder();
|
||||
builder.addDataStrings(instanceId);
|
||||
builder.addDataIntegers(serviceLayer.value());
|
||||
builder.addDataStrings(relatedInstanceId);
|
||||
builder.addDataIntegers(relatedServiceLayer.value());
|
||||
builder.addDataLongs(getTimeBucket());
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remoteHashCode() {
|
||||
return this.hashCode();
|
||||
}
|
||||
|
||||
public static class Builder implements StorageBuilder<InstanceHierarchyRelationTraffic> {
|
||||
@Override
|
||||
public InstanceHierarchyRelationTraffic storage2Entity(final Convert2Entity converter) {
|
||||
InstanceHierarchyRelationTraffic traffic = new InstanceHierarchyRelationTraffic();
|
||||
traffic.setInstanceId((String) converter.get(INSTANCE_ID));
|
||||
traffic.setRelatedInstanceId((String) converter.get(RELATED_INSTANCE_ID));
|
||||
if (converter.get(SERVICE_LAYER) != null) {
|
||||
traffic.setServiceLayer(Layer.valueOf(((Number) converter.get(SERVICE_LAYER)).intValue()));
|
||||
} else {
|
||||
traffic.setServiceLayer(Layer.UNDEFINED);
|
||||
}
|
||||
if (converter.get(RELATED_SERVICE_LAYER) != null) {
|
||||
traffic.setRelatedServiceLayer(
|
||||
Layer.valueOf(((Number) converter.get(RELATED_SERVICE_LAYER)).intValue()));
|
||||
} else {
|
||||
traffic.setRelatedServiceLayer(Layer.UNDEFINED);
|
||||
}
|
||||
if (converter.get(TIME_BUCKET) != null) {
|
||||
traffic.setTimeBucket(((Number) converter.get(TIME_BUCKET)).longValue());
|
||||
}
|
||||
return traffic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entity2Storage(final InstanceHierarchyRelationTraffic storageData,
|
||||
final Convert2Storage converter) {
|
||||
converter.accept(INSTANCE_ID, storageData.getInstanceId());
|
||||
converter.accept(RELATED_INSTANCE_ID, storageData.getRelatedInstanceId());
|
||||
converter.accept(SERVICE_LAYER, storageData.getServiceLayer().value());
|
||||
converter.accept(RELATED_SERVICE_LAYER, storageData.getRelatedServiceLayer().value());
|
||||
converter.accept(TIME_BUCKET, storageData.getTimeBucket());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.hierarchy.instance;
|
||||
|
||||
import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
|
||||
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
|
||||
|
||||
public class InstanceHierarchyTrafficRelationDispatcher implements SourceDispatcher<InstanceHierarchyRelation> {
|
||||
@Override
|
||||
public void dispatch(final InstanceHierarchyRelation source) {
|
||||
InstanceHierarchyRelationTraffic traffic = new InstanceHierarchyRelationTraffic();
|
||||
traffic.setInstanceId(source.getInstanceId());
|
||||
traffic.setServiceLayer(source.getServiceLayer());
|
||||
traffic.setRelatedInstanceId(source.getRelatedInstanceId());
|
||||
traffic.setRelatedServiceLayer(source.getRelatedServiceLayer());
|
||||
traffic.setTimeBucket(source.getTimeBucket());
|
||||
MetricsStreamProcessor.getInstance().in(traffic);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.hierarchy.service;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
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.source.DefaultScopeDefine;
|
||||
import org.apache.skywalking.oap.server.core.source.ScopeDeclaration;
|
||||
import org.apache.skywalking.oap.server.core.source.Source;
|
||||
|
||||
@ScopeDeclaration(id = DefaultScopeDefine.SERVICE_HIERARCHY_RELATION, name = "ServiceHierarchyRelation")
|
||||
public class ServiceHierarchyRelation extends Source {
|
||||
@Setter
|
||||
@Getter
|
||||
private String serviceName;
|
||||
@Getter
|
||||
private String serviceId;
|
||||
@Setter
|
||||
@Getter
|
||||
private Layer serviceLayer;
|
||||
@Setter
|
||||
@Getter
|
||||
private String relatedServiceName;
|
||||
@Getter
|
||||
private String relatedServiceId;
|
||||
@Setter
|
||||
@Getter
|
||||
private Layer relatedServiceLayer;
|
||||
|
||||
@Override
|
||||
public int scope() {
|
||||
return DefaultScopeDefine.SERVICE_HIERARCHY_RELATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
serviceId = IDManager.ServiceID.buildId(serviceName, serviceLayer.isNormal());
|
||||
relatedServiceId = IDManager.ServiceID.buildId(relatedServiceName, relatedServiceLayer.isNormal());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* 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.hierarchy.service;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
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.analysis.MetricsExtension;
|
||||
import org.apache.skywalking.oap.server.core.analysis.Stream;
|
||||
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
|
||||
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
|
||||
import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
|
||||
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageID;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.BanyanDB;
|
||||
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.Convert2Entity;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.Convert2Storage;
|
||||
import org.apache.skywalking.oap.server.core.storage.type.StorageBuilder;
|
||||
|
||||
@Stream(name = ServiceHierarchyRelationTraffic.INDEX_NAME, scopeId = DefaultScopeDefine.SERVICE_HIERARCHY_RELATION,
|
||||
builder = ServiceHierarchyRelationTraffic.Builder.class, processor = MetricsStreamProcessor.class)
|
||||
@MetricsExtension(supportDownSampling = false, supportUpdate = false)
|
||||
@EqualsAndHashCode(of = {
|
||||
"serviceId",
|
||||
"serviceLayer",
|
||||
"relatedServiceId",
|
||||
"relatedServiceLayer"
|
||||
}, callSuper = true)
|
||||
public class ServiceHierarchyRelationTraffic extends Metrics {
|
||||
public static final String INDEX_NAME = "service_hierarchy_relation";
|
||||
public static final String SERVICE_ID = "service_id";
|
||||
public static final String SERVICE_LAYER = "service_layer";
|
||||
public static final String RELATED_SERVICE_ID = "related_service_id";
|
||||
public static final String RELATED_SERVICE_LAYER = "related_service_layer";
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Column(name = SERVICE_ID, length = 250)
|
||||
@BanyanDB.SeriesID(index = 0)
|
||||
private String serviceId;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Column(name = SERVICE_LAYER)
|
||||
@BanyanDB.SeriesID(index = 1)
|
||||
private Layer serviceLayer = Layer.UNDEFINED;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Column(name = RELATED_SERVICE_ID, length = 250)
|
||||
@BanyanDB.SeriesID(index = 2)
|
||||
private String relatedServiceId;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Column(name = RELATED_SERVICE_LAYER)
|
||||
@BanyanDB.SeriesID(index = 3)
|
||||
private Layer relatedServiceLayer = Layer.UNDEFINED;
|
||||
|
||||
@Override
|
||||
protected StorageID id0() {
|
||||
String id = IDManager.ServiceID.buildServiceHierarchyRelationId(
|
||||
new IDManager.ServiceID.ServiceHierarchyRelationDefine(
|
||||
serviceId, serviceLayer, relatedServiceId, relatedServiceLayer));
|
||||
|
||||
return new StorageID().appendMutant(new String[] {
|
||||
SERVICE_ID,
|
||||
SERVICE_LAYER,
|
||||
RELATED_SERVICE_ID,
|
||||
RELATED_SERVICE_LAYER
|
||||
}, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean combine(final Metrics metrics) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics toHour() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics toDay() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserialize(final RemoteData remoteData) {
|
||||
setServiceId(remoteData.getDataStrings(0));
|
||||
setServiceLayer(Layer.valueOf(remoteData.getDataIntegers(0)));
|
||||
setRelatedServiceId(remoteData.getDataStrings(1));
|
||||
setRelatedServiceLayer(Layer.valueOf(remoteData.getDataIntegers(1)));
|
||||
setTimeBucket(remoteData.getDataLongs(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteData.Builder serialize() {
|
||||
final RemoteData.Builder builder = RemoteData.newBuilder();
|
||||
builder.addDataStrings(serviceId);
|
||||
builder.addDataIntegers(serviceLayer.value());
|
||||
builder.addDataStrings(relatedServiceId);
|
||||
builder.addDataIntegers(relatedServiceLayer.value());
|
||||
builder.addDataLongs(getTimeBucket());
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int remoteHashCode() {
|
||||
return this.hashCode();
|
||||
}
|
||||
|
||||
public static class Builder implements StorageBuilder<ServiceHierarchyRelationTraffic> {
|
||||
@Override
|
||||
public ServiceHierarchyRelationTraffic storage2Entity(final Convert2Entity converter) {
|
||||
ServiceHierarchyRelationTraffic traffic = new ServiceHierarchyRelationTraffic();
|
||||
traffic.setServiceId((String) converter.get(SERVICE_ID));
|
||||
traffic.setRelatedServiceId((String) converter.get(RELATED_SERVICE_ID));
|
||||
if (converter.get(SERVICE_LAYER) != null) {
|
||||
traffic.setServiceLayer(Layer.valueOf(((Number) converter.get(SERVICE_LAYER)).intValue()));
|
||||
} else {
|
||||
traffic.setServiceLayer(Layer.UNDEFINED);
|
||||
}
|
||||
if (converter.get(RELATED_SERVICE_LAYER) != null) {
|
||||
traffic.setRelatedServiceLayer(
|
||||
Layer.valueOf(((Number) converter.get(RELATED_SERVICE_LAYER)).intValue()));
|
||||
} else {
|
||||
traffic.setRelatedServiceLayer(Layer.UNDEFINED);
|
||||
}
|
||||
if (converter.get(TIME_BUCKET) != null) {
|
||||
traffic.setTimeBucket(((Number) converter.get(TIME_BUCKET)).longValue());
|
||||
}
|
||||
return traffic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entity2Storage(final ServiceHierarchyRelationTraffic storageData, final Convert2Storage converter) {
|
||||
converter.accept(SERVICE_ID, storageData.getServiceId());
|
||||
converter.accept(RELATED_SERVICE_ID, storageData.getRelatedServiceId());
|
||||
converter.accept(SERVICE_LAYER, storageData.getServiceLayer().value());
|
||||
converter.accept(RELATED_SERVICE_LAYER, storageData.getRelatedServiceLayer().value());
|
||||
converter.accept(TIME_BUCKET, storageData.getTimeBucket());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.hierarchy.service;
|
||||
|
||||
import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
|
||||
import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
|
||||
|
||||
public class ServiceHierarchyTrafficRelationDispatcher implements SourceDispatcher<ServiceHierarchyRelation> {
|
||||
@Override
|
||||
public void dispatch(final ServiceHierarchyRelation source) {
|
||||
ServiceHierarchyRelationTraffic traffic = new ServiceHierarchyRelationTraffic();
|
||||
traffic.setServiceId(source.getServiceId());
|
||||
traffic.setServiceLayer(source.getServiceLayer());
|
||||
traffic.setRelatedServiceId(source.getRelatedServiceId());
|
||||
traffic.setRelatedServiceLayer(source.getRelatedServiceLayer());
|
||||
traffic.setTimeBucket(source.getTimeBucket());
|
||||
MetricsStreamProcessor.getInstance().in(traffic);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* 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 com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.CoreModuleConfig;
|
||||
import org.apache.skywalking.oap.server.core.analysis.IDManager;
|
||||
import org.apache.skywalking.oap.server.core.config.HierarchyDefinitionService;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.instance.InstanceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.service.ServiceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.query.type.HierarchyInstanceRelation;
|
||||
import org.apache.skywalking.oap.server.core.query.type.HierarchyRelatedInstance;
|
||||
import org.apache.skywalking.oap.server.core.query.type.HierarchyRelatedService;
|
||||
import org.apache.skywalking.oap.server.core.query.type.HierarchyServiceRelation;
|
||||
import org.apache.skywalking.oap.server.core.query.type.InstanceHierarchy;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ServiceHierarchy;
|
||||
import org.apache.skywalking.oap.server.core.storage.StorageModule;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
import org.apache.skywalking.oap.server.library.module.Service;
|
||||
|
||||
@Slf4j
|
||||
public class HierarchyQueryService implements Service {
|
||||
private final ModuleManager moduleManager;
|
||||
private final boolean isEnableHierarchy;
|
||||
private IHierarchyQueryDAO hierarchyQueryDAO;
|
||||
private Map<String, List<String>> hierarchyDefinition;
|
||||
private LoadingCache<Boolean, Map<HierarchyRelatedService, ServiceRelations>> serviceHierarchyCache;
|
||||
|
||||
public HierarchyQueryService(ModuleManager moduleManager, CoreModuleConfig moduleConfig) {
|
||||
this.moduleManager = moduleManager;
|
||||
this.isEnableHierarchy = moduleConfig.isEnableHierarchy();
|
||||
if (moduleConfig.isEnableHierarchy()) {
|
||||
this.serviceHierarchyCache =
|
||||
CacheBuilder.newBuilder()
|
||||
.maximumSize(1)
|
||||
.refreshAfterWrite(moduleConfig.getServiceCacheRefreshInterval(), TimeUnit.SECONDS)
|
||||
.build(
|
||||
new CacheLoader<>() {
|
||||
@Override
|
||||
public Map<HierarchyRelatedService, ServiceRelations> load(final Boolean key) throws Exception {
|
||||
return mapServiceHierarchy();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private IHierarchyQueryDAO getHierarchyQueryDAO() {
|
||||
if (hierarchyQueryDAO == null) {
|
||||
this.hierarchyQueryDAO = moduleManager.find(StorageModule.NAME)
|
||||
.provider()
|
||||
.getService(IHierarchyQueryDAO.class);
|
||||
}
|
||||
return hierarchyQueryDAO;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getHierarchyDefinition() {
|
||||
if (hierarchyDefinition == null) {
|
||||
hierarchyDefinition = moduleManager.find(CoreModule.NAME)
|
||||
.provider()
|
||||
.getService(HierarchyDefinitionService.class).getHierarchyDefinition();
|
||||
}
|
||||
return hierarchyDefinition;
|
||||
}
|
||||
|
||||
private Map<HierarchyRelatedService, ServiceRelations> mapServiceHierarchy() throws Exception {
|
||||
List<ServiceHierarchyRelationTraffic> traffics = getHierarchyQueryDAO().readAllServiceHierarchyRelations();
|
||||
Map<HierarchyRelatedService, ServiceRelations> serviceRelationsMap = new HashMap<>();
|
||||
|
||||
for (ServiceHierarchyRelationTraffic traffic : traffics) {
|
||||
HierarchyRelatedService service = new HierarchyRelatedService();
|
||||
service.setId(traffic.getServiceId());
|
||||
service.setName(IDManager.ServiceID.analysisId(traffic.getServiceId()).getName());
|
||||
service.setLayer(traffic.getServiceLayer().name());
|
||||
HierarchyRelatedService relatedService = new HierarchyRelatedService();
|
||||
relatedService.setId(traffic.getRelatedServiceId());
|
||||
relatedService.setName(IDManager.ServiceID.analysisId(traffic.getRelatedServiceId()).getName());
|
||||
relatedService.setLayer(traffic.getRelatedServiceLayer().name());
|
||||
|
||||
ServiceRelations serviceRelations = serviceRelationsMap.computeIfAbsent(
|
||||
service, k -> new ServiceRelations());
|
||||
ServiceRelations relationServiceRelations = serviceRelationsMap.computeIfAbsent(
|
||||
relatedService, k -> new ServiceRelations());
|
||||
List<String> lowerLayers = getHierarchyDefinition().getOrDefault(
|
||||
traffic.getServiceLayer().name(), new ArrayList<>());
|
||||
List<String> relatedLowerLayers = getHierarchyDefinition().getOrDefault(
|
||||
traffic.getRelatedServiceLayer().name(), new ArrayList<>());
|
||||
|
||||
// Build the relations in 2 directions
|
||||
if (lowerLayers.contains(traffic.getRelatedServiceLayer().name())) {
|
||||
serviceRelations.getLowerServices().add(relatedService);
|
||||
relationServiceRelations.getUpperServices().add(service);
|
||||
} else if (relatedLowerLayers.contains(traffic.getServiceLayer().name())) {
|
||||
serviceRelations.getUpperServices().add(relatedService);
|
||||
relationServiceRelations.getLowerServices().add(service);
|
||||
}
|
||||
}
|
||||
return serviceRelationsMap;
|
||||
}
|
||||
|
||||
public ServiceHierarchy getServiceHierarchy(String serviceId, String layer) throws Exception {
|
||||
if (!this.isEnableHierarchy) {
|
||||
log.warn("CoreModuleConfig config {enableHierarchy} is false, return empty ServiceHierarchy.");
|
||||
return new ServiceHierarchy();
|
||||
}
|
||||
ServiceHierarchy hierarchy = new ServiceHierarchy();
|
||||
HierarchyRelatedService self = new HierarchyRelatedService();
|
||||
self.setId(serviceId);
|
||||
self.setName(IDManager.ServiceID.analysisId(serviceId).getName());
|
||||
self.setLayer(layer);
|
||||
Map<HierarchyRelatedService, ServiceRelations> serviceRelationsMap = serviceHierarchyCache.get(true);
|
||||
ServiceRelations serviceRelations = serviceRelationsMap.getOrDefault(self, new ServiceRelations());
|
||||
|
||||
serviceRelations.getLowerServices().forEach(relatedService -> {
|
||||
hierarchy.getRelations().add(new HierarchyServiceRelation(self, relatedService));
|
||||
});
|
||||
serviceRelations.getUpperServices().forEach(relatedService -> {
|
||||
hierarchy.getRelations().add(new HierarchyServiceRelation(relatedService, self));
|
||||
});
|
||||
|
||||
return hierarchy;
|
||||
}
|
||||
|
||||
public InstanceHierarchy getInstanceHierarchy(String instanceId, String layer) throws Exception {
|
||||
if (!this.isEnableHierarchy) {
|
||||
log.warn("CoreModuleConfig config {enableHierarchy} is false, return empty InstanceHierarchy.");
|
||||
return new InstanceHierarchy();
|
||||
}
|
||||
InstanceHierarchy hierarchy = new InstanceHierarchy();
|
||||
List<InstanceHierarchyRelationTraffic> traffics = getHierarchyQueryDAO().readInstanceHierarchyRelations(
|
||||
instanceId, layer);
|
||||
|
||||
for (InstanceHierarchyRelationTraffic traffic : traffics) {
|
||||
HierarchyRelatedInstance instance = new HierarchyRelatedInstance();
|
||||
instance.setId(traffic.getInstanceId());
|
||||
instance.setName(IDManager.ServiceInstanceID.analysisId(traffic.getInstanceId()).getName());
|
||||
instance.setLayer(traffic.getServiceLayer().name());
|
||||
HierarchyRelatedInstance relatedInstance = new HierarchyRelatedInstance();
|
||||
relatedInstance.setId(traffic.getRelatedInstanceId());
|
||||
relatedInstance.setName(IDManager.ServiceInstanceID.analysisId(traffic.getRelatedInstanceId()).getName());
|
||||
relatedInstance.setLayer(traffic.getRelatedServiceLayer().name());
|
||||
List<String> lowerLayers = getHierarchyDefinition().getOrDefault(
|
||||
traffic.getServiceLayer().name(), new ArrayList<>());
|
||||
List<String> relatedLowerLayers = getHierarchyDefinition().getOrDefault(
|
||||
traffic.getRelatedServiceLayer().name(), new ArrayList<>());
|
||||
|
||||
//should build the relations in 2 direction
|
||||
if (lowerLayers.contains(traffic.getRelatedServiceLayer().name())) {
|
||||
hierarchy.getRelations().add(new HierarchyInstanceRelation(instance, relatedInstance));
|
||||
} else if (relatedLowerLayers.contains(traffic.getServiceLayer().name())) {
|
||||
hierarchy.getRelations().add(new HierarchyInstanceRelation(relatedInstance, instance));
|
||||
}
|
||||
}
|
||||
|
||||
return hierarchy;
|
||||
}
|
||||
|
||||
@Data
|
||||
static class ServiceRelations {
|
||||
private List<HierarchyRelatedService> upperServices = new ArrayList<>();
|
||||
private List<HierarchyRelatedService> lowerServices = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
public class HierarchyInstanceRelation {
|
||||
private HierarchyRelatedInstance upperInstance;
|
||||
private HierarchyRelatedInstance lowerInstance;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class HierarchyRelatedInstance {
|
||||
private String id;
|
||||
private String name;
|
||||
private String layer;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode(of = {"id", "layer"})
|
||||
public class HierarchyRelatedService {
|
||||
private String id;
|
||||
private String name;
|
||||
private String layer;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class HierarchyServiceRelation {
|
||||
private HierarchyRelatedService upperService;
|
||||
private HierarchyRelatedService lowerService;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class InstanceHierarchy {
|
||||
private List<HierarchyInstanceRelation> relations = new ArrayList<>();
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class ServiceHierarchy {
|
||||
private List<HierarchyServiceRelation> relations = new ArrayList<>();
|
||||
}
|
||||
|
|
@ -127,6 +127,8 @@ public class DefaultScopeDefine {
|
|||
|
||||
public static final int UI_MENU = 69;
|
||||
|
||||
public static final int SERVICE_HIERARCHY_RELATION = 70;
|
||||
public static final int INSTANCE_HIERARCHY_RELATION = 71;
|
||||
/**
|
||||
* Catalog of scope, the metrics processor could use this to group all generated metrics by oal rt.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfili
|
|||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingScheduleDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.profiling.ebpf.IEBPFProfilingTaskDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.ILogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IMetadataQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IMetricsQueryDAO;
|
||||
|
|
@ -86,7 +87,8 @@ public class StorageModule extends ModuleDefine {
|
|||
IServiceLabelDAO.class,
|
||||
ITagAutoCompleteQueryDAO.class,
|
||||
IZipkinQueryDAO.class,
|
||||
ISpanAttachedEventQueryDAO.class
|
||||
ISpanAttachedEventQueryDAO.class,
|
||||
IHierarchyQueryDAO.class
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.storage.query;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.instance.InstanceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.service.ServiceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.storage.DAO;
|
||||
|
||||
public interface IHierarchyQueryDAO extends DAO {
|
||||
List<ServiceHierarchyRelationTraffic> readAllServiceHierarchyRelations() throws Exception;
|
||||
|
||||
/**
|
||||
* Return the given instance's hierarchy.
|
||||
*/
|
||||
List<InstanceHierarchyRelationTraffic> readInstanceHierarchyRelations(String instanceId, String layer) throws Exception;
|
||||
}
|
||||
|
|
@ -26,6 +26,6 @@ public class CoreModuleTest {
|
|||
public void testOpenServiceList() {
|
||||
CoreModule coreModule = new CoreModule();
|
||||
|
||||
Assertions.assertEquals(41, coreModule.services().length);
|
||||
Assertions.assertEquals(44, coreModule.services().length);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.apache.skywalking.oap.query.graphql.resolver.EBPFProcessProfilingMuta
|
|||
import org.apache.skywalking.oap.query.graphql.resolver.EBPFProcessProfilingQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.EventQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.HealthQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.HierarchyQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.LogQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.LogTestQuery;
|
||||
import org.apache.skywalking.oap.query.graphql.resolver.MetadataQuery;
|
||||
|
|
@ -143,7 +144,8 @@ public class GraphQLQueryProvider extends ModuleProvider {
|
|||
.file("query-protocol/continuous-profiling.graphqls")
|
||||
.resolvers(new ContinuousProfilingQuery(getManager()), new ContinuousProfilingMutation(getManager()))
|
||||
.file("query-protocol/record.graphqls")
|
||||
.resolvers(new RecordsQuery(getManager()));
|
||||
.resolvers(new RecordsQuery(getManager()))
|
||||
.file("query-protocol/hierarchy.graphqls").resolvers(new HierarchyQuery(getManager()));
|
||||
|
||||
if (config.isEnableOnDemandPodLog()) {
|
||||
schemaBuilder
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.graphql.resolver;
|
||||
|
||||
import graphql.kickstart.tools.GraphQLQueryResolver;
|
||||
import org.apache.skywalking.oap.server.core.CoreModule;
|
||||
import org.apache.skywalking.oap.server.core.query.HierarchyQueryService;
|
||||
import org.apache.skywalking.oap.server.core.query.type.InstanceHierarchy;
|
||||
import org.apache.skywalking.oap.server.core.query.type.ServiceHierarchy;
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleManager;
|
||||
|
||||
public class HierarchyQuery implements GraphQLQueryResolver {
|
||||
private final ModuleManager moduleManager;
|
||||
private HierarchyQueryService hierarchyQueryService;
|
||||
|
||||
public HierarchyQuery(ModuleManager moduleManager) {
|
||||
this.moduleManager = moduleManager;
|
||||
}
|
||||
|
||||
private HierarchyQueryService getHierarchyQueryService() {
|
||||
if (hierarchyQueryService == null) {
|
||||
this.hierarchyQueryService = moduleManager.find(CoreModule.NAME)
|
||||
.provider()
|
||||
.getService(HierarchyQueryService.class);
|
||||
}
|
||||
return hierarchyQueryService;
|
||||
}
|
||||
|
||||
public ServiceHierarchy getServiceHierarchy(String serviceId, String layer) throws Exception {
|
||||
return getHierarchyQueryService().getServiceHierarchy(serviceId, layer);
|
||||
}
|
||||
|
||||
public InstanceHierarchy getInstanceHierarchy(String instanceId, String layer) throws Exception {
|
||||
return getHierarchyQueryService().getInstanceHierarchy(instanceId, layer);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit e08b0a78258a4c56e67076424add6bc2d0a1dd08
|
||||
Subproject commit b5fe539bce21d464e5dff360a691b79729bf065b
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# 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.
|
||||
|
||||
# Define the hierarchy of layers, the layers under the specific layer are lower of the layer.
|
||||
# All the layers are defined in the file `org.apache.skywalking.oap.server.core.analysis.Layers.java`.
|
||||
|
||||
MESH:
|
||||
- MESH_DP
|
||||
- K8S_SERVICE
|
||||
- K8S
|
||||
|
||||
MESH_DP:
|
||||
- K8S_SERVICE
|
||||
- K8S
|
||||
|
||||
K8S_SERVICE:
|
||||
- K8S
|
||||
|
|
@ -43,6 +43,7 @@ import org.apache.skywalking.oap.server.core.storage.query.IAggregationQueryDAO;
|
|||
import org.apache.skywalking.oap.server.core.storage.query.IAlarmQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IBrowserLogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.ILogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IMetadataQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IMetricsQueryDAO;
|
||||
|
|
@ -58,6 +59,7 @@ import org.apache.skywalking.oap.server.library.module.ModuleStartException;
|
|||
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.measure.BanyanDBEBPFProfilingScheduleQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.measure.BanyanDBEventQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.measure.BanyanDBHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.measure.BanyanDBMetadataQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.measure.BanyanDBMetricsQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.measure.BanyanDBNetworkAddressAliasDAO;
|
||||
|
|
@ -163,6 +165,7 @@ public class BanyanDBStorageProvider extends ModuleProvider {
|
|||
this.registerServiceImplementation(IRecordsQueryDAO.class, new BanyanDBRecordsQueryDAO(client));
|
||||
this.registerServiceImplementation(IZipkinQueryDAO.class, new BanyanDBZipkinQueryDAO(client));
|
||||
this.registerServiceImplementation(ISpanAttachedEventQueryDAO.class, new BanyanDBSpanAttachedEventQueryDAO(client));
|
||||
this.registerServiceImplementation(IHierarchyQueryDAO.class, new BanyanDBHierarchyQueryDAO(client));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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.storage.plugin.banyandb.measure;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.skywalking.banyandb.v1.client.AbstractCriteria;
|
||||
import org.apache.skywalking.banyandb.v1.client.DataPoint;
|
||||
import org.apache.skywalking.banyandb.v1.client.MeasureQuery;
|
||||
import org.apache.skywalking.banyandb.v1.client.MeasureQueryResponse;
|
||||
import org.apache.skywalking.oap.server.core.analysis.DownSampling;
|
||||
import org.apache.skywalking.oap.server.core.analysis.Layer;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.instance.InstanceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.service.ServiceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.BanyanDBConverter;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.BanyanDBStorageClient;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.MetadataRegistry;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.banyandb.stream.AbstractBanyanDBDAO;
|
||||
|
||||
public class BanyanDBHierarchyQueryDAO extends AbstractBanyanDBDAO implements IHierarchyQueryDAO {
|
||||
private static final Set<String> SERVICE_HIERARCHY_RELATION_TAGS = ImmutableSet.of(
|
||||
ServiceHierarchyRelationTraffic.SERVICE_ID,
|
||||
ServiceHierarchyRelationTraffic.SERVICE_LAYER,
|
||||
ServiceHierarchyRelationTraffic.RELATED_SERVICE_ID,
|
||||
ServiceHierarchyRelationTraffic.RELATED_SERVICE_LAYER
|
||||
);
|
||||
|
||||
private static final Set<String> INSTANCE_HIERARCHY_RELATION_TAGS = ImmutableSet.of(
|
||||
InstanceHierarchyRelationTraffic.INSTANCE_ID,
|
||||
InstanceHierarchyRelationTraffic.SERVICE_LAYER,
|
||||
InstanceHierarchyRelationTraffic.RELATED_INSTANCE_ID,
|
||||
InstanceHierarchyRelationTraffic.RELATED_SERVICE_LAYER
|
||||
);
|
||||
|
||||
public BanyanDBHierarchyQueryDAO(final BanyanDBStorageClient client) {
|
||||
super(client);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceHierarchyRelationTraffic> readAllServiceHierarchyRelations() throws Exception {
|
||||
MeasureQueryResponse resp = query(ServiceHierarchyRelationTraffic.INDEX_NAME,
|
||||
SERVICE_HIERARCHY_RELATION_TAGS,
|
||||
Collections.emptySet(), new QueryBuilder<>() {
|
||||
@Override
|
||||
protected void apply(MeasureQuery query) {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
final List<ServiceHierarchyRelationTraffic> relations = new ArrayList<>();
|
||||
MetadataRegistry.Schema schema = MetadataRegistry.INSTANCE.findMetadata(
|
||||
ServiceHierarchyRelationTraffic.INDEX_NAME, DownSampling.Minute);
|
||||
|
||||
for (final DataPoint dataPoint : resp.getDataPoints()) {
|
||||
relations.add(new ServiceHierarchyRelationTraffic.Builder().storage2Entity(
|
||||
new BanyanDBConverter.StorageToMeasure(schema, dataPoint)));
|
||||
}
|
||||
|
||||
return relations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstanceHierarchyRelationTraffic> readInstanceHierarchyRelations(final String instanceId,
|
||||
final String layer) throws Exception {
|
||||
MeasureQueryResponse resp = query(InstanceHierarchyRelationTraffic.INDEX_NAME,
|
||||
INSTANCE_HIERARCHY_RELATION_TAGS,
|
||||
Collections.emptySet(), buildInstanceRelationsQuery(instanceId, layer)
|
||||
);
|
||||
|
||||
List<InstanceHierarchyRelationTraffic> relations = new ArrayList<>();
|
||||
MetadataRegistry.Schema schema = MetadataRegistry.INSTANCE.findMetadata(
|
||||
InstanceHierarchyRelationTraffic.INDEX_NAME, DownSampling.Minute);
|
||||
for (final DataPoint dataPoint : resp.getDataPoints()) {
|
||||
relations.add(new InstanceHierarchyRelationTraffic.Builder().storage2Entity(
|
||||
new BanyanDBConverter.StorageToMeasure(schema, dataPoint)));
|
||||
}
|
||||
return relations;
|
||||
}
|
||||
|
||||
private QueryBuilder<MeasureQuery> buildInstanceRelationsQuery(String instanceId, String layer) {
|
||||
int layerValue = Layer.valueOf(layer).value();
|
||||
return new QueryBuilder<>() {
|
||||
@Override
|
||||
protected void apply(MeasureQuery query) {
|
||||
List<AbstractCriteria> instanceRelationsQueryConditions = new ArrayList<>(2);
|
||||
|
||||
instanceRelationsQueryConditions.add(
|
||||
and(Lists.newArrayList(
|
||||
eq(InstanceHierarchyRelationTraffic.INSTANCE_ID, instanceId),
|
||||
eq(InstanceHierarchyRelationTraffic.SERVICE_LAYER, layerValue))
|
||||
));
|
||||
instanceRelationsQueryConditions.add(
|
||||
and(Lists.newArrayList(
|
||||
eq(InstanceHierarchyRelationTraffic.RELATED_INSTANCE_ID, instanceId),
|
||||
eq(InstanceHierarchyRelationTraffic.RELATED_SERVICE_LAYER, layerValue)
|
||||
))
|
||||
);
|
||||
query.criteria(or(instanceRelationsQueryConditions));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -48,6 +48,7 @@ import org.apache.skywalking.oap.server.core.storage.query.IAggregationQueryDAO;
|
|||
import org.apache.skywalking.oap.server.core.storage.query.IAlarmQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IBrowserLogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.ILogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IMetadataQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IMetricsQueryDAO;
|
||||
|
|
@ -79,6 +80,7 @@ import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.EBPFP
|
|||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.EBPFProfilingScheduleEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.EBPFProfilingTaskEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.ESEventQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.HierarchyQueryEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.LogQueryEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.MetadataQueryEsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query.MetricsQueryEsDAO;
|
||||
|
|
@ -254,6 +256,7 @@ public class StorageModuleElasticsearchProvider extends ModuleProvider {
|
|||
ISpanAttachedEventQueryDAO.class, new SpanAttachedEventEsDAO(elasticSearchClient, config));
|
||||
IndexController.INSTANCE.setLogicSharding(config.isLogicSharding());
|
||||
IndexController.INSTANCE.setEnableCustomRouting(config.isEnableCustomRouting());
|
||||
this.registerServiceImplementation(IHierarchyQueryDAO.class, new HierarchyQueryEsDAO(elasticSearchClient, config));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* 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.storage.plugin.elasticsearch.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.BoolQueryBuilder;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.Query;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.Search;
|
||||
import org.apache.skywalking.library.elasticsearch.requests.search.SearchBuilder;
|
||||
import org.apache.skywalking.library.elasticsearch.response.search.SearchHit;
|
||||
import org.apache.skywalking.library.elasticsearch.response.search.SearchResponse;
|
||||
import org.apache.skywalking.oap.server.core.analysis.Layer;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.instance.InstanceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.service.ServiceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchClient;
|
||||
import org.apache.skywalking.oap.server.library.client.elasticsearch.ElasticSearchScroller;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.StorageModuleElasticsearchConfig;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.ElasticSearchConverter;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.EsDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base.IndexController;
|
||||
|
||||
public class HierarchyQueryEsDAO extends EsDAO implements IHierarchyQueryDAO {
|
||||
private final int queryMaxSize;
|
||||
private final int scrollingBatchSize;
|
||||
|
||||
protected final Function<SearchHit, ServiceHierarchyRelationTraffic> serviceRelationsFunction = hit -> {
|
||||
final var sourceAsMap = hit.getSource();
|
||||
final var builder = new ServiceHierarchyRelationTraffic.Builder();
|
||||
return builder.storage2Entity(
|
||||
new ElasticSearchConverter.ToEntity(ServiceHierarchyRelationTraffic.INDEX_NAME, sourceAsMap));
|
||||
};
|
||||
|
||||
protected final Function<SearchHit, InstanceHierarchyRelationTraffic> instanceRelationsFunction = hit -> {
|
||||
final var sourceAsMap = hit.getSource();
|
||||
final var builder = new InstanceHierarchyRelationTraffic.Builder();
|
||||
return builder.storage2Entity(
|
||||
new ElasticSearchConverter.ToEntity(InstanceHierarchyRelationTraffic.INDEX_NAME, sourceAsMap));
|
||||
};
|
||||
|
||||
public HierarchyQueryEsDAO(final ElasticSearchClient client,
|
||||
final StorageModuleElasticsearchConfig config) {
|
||||
super(client);
|
||||
this.queryMaxSize = config.getMetadataQueryMaxSize();
|
||||
this.scrollingBatchSize = config.getScrollingBatchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceHierarchyRelationTraffic> readAllServiceHierarchyRelations() {
|
||||
final String index =
|
||||
IndexController.LogicIndicesRegister.getPhysicalTableName(ServiceHierarchyRelationTraffic.INDEX_NAME);
|
||||
|
||||
final int batchSize = Math.min(queryMaxSize, scrollingBatchSize);
|
||||
final BoolQueryBuilder query = Query.bool();
|
||||
final SearchBuilder search = Search.builder().query(query).size(batchSize);
|
||||
if (IndexController.LogicIndicesRegister.isMergedTable(ServiceHierarchyRelationTraffic.INDEX_NAME)) {
|
||||
query.must(Query.term(
|
||||
IndexController.LogicIndicesRegister.METRIC_TABLE_NAME,
|
||||
ServiceHierarchyRelationTraffic.INDEX_NAME
|
||||
));
|
||||
}
|
||||
|
||||
final var scroller = ElasticSearchScroller
|
||||
.<ServiceHierarchyRelationTraffic>builder()
|
||||
.client(getClient())
|
||||
.search(search.build())
|
||||
.index(index)
|
||||
.queryMaxSize(queryMaxSize)
|
||||
.resultConverter(serviceRelationsFunction)
|
||||
.build();
|
||||
return scroller.scroll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstanceHierarchyRelationTraffic> readInstanceHierarchyRelations(final String instanceId, final String layer) {
|
||||
final String index =
|
||||
IndexController.LogicIndicesRegister.getPhysicalTableName(InstanceHierarchyRelationTraffic.INDEX_NAME);
|
||||
int layerValue = Layer.valueOf(layer).value();
|
||||
final BoolQueryBuilder instanceSide =
|
||||
Query.bool()
|
||||
.must(Query.term(InstanceHierarchyRelationTraffic.INSTANCE_ID, instanceId))
|
||||
.must(Query.term(InstanceHierarchyRelationTraffic.SERVICE_LAYER, layerValue));
|
||||
|
||||
final BoolQueryBuilder relatedInstanceSide =
|
||||
Query.bool()
|
||||
.must(Query.term(InstanceHierarchyRelationTraffic.RELATED_INSTANCE_ID, instanceId))
|
||||
.must(Query.term(InstanceHierarchyRelationTraffic.RELATED_SERVICE_LAYER, layerValue));
|
||||
|
||||
final BoolQueryBuilder instanceQuery =
|
||||
Query.bool()
|
||||
.should(instanceSide)
|
||||
.should(relatedInstanceSide);
|
||||
|
||||
final BoolQueryBuilder query =
|
||||
Query.bool()
|
||||
.must(instanceQuery);
|
||||
if (IndexController.LogicIndicesRegister.isMergedTable(InstanceHierarchyRelationTraffic.INDEX_NAME)) {
|
||||
query.must(Query.term(
|
||||
IndexController.LogicIndicesRegister.METRIC_TABLE_NAME,
|
||||
InstanceHierarchyRelationTraffic.INDEX_NAME
|
||||
));
|
||||
}
|
||||
final SearchBuilder search = Search.builder().query(query);
|
||||
final SearchResponse response = getClient().search(index, search.build());
|
||||
return buildInstanceHierarchyRelations(response);
|
||||
}
|
||||
|
||||
private List<InstanceHierarchyRelationTraffic> buildInstanceHierarchyRelations(SearchResponse response) {
|
||||
List<InstanceHierarchyRelationTraffic> relations = new ArrayList<>();
|
||||
for (SearchHit searchHit : response.getHits()) {
|
||||
relations.add(instanceRelationsFunction.apply(searchHit));
|
||||
}
|
||||
return relations;
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ import org.apache.skywalking.oap.server.core.storage.query.IAggregationQueryDAO;
|
|||
import org.apache.skywalking.oap.server.core.storage.query.IAlarmQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IBrowserLogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.ILogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IMetadataQueryDAO;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IMetricsQueryDAO;
|
||||
|
|
@ -65,6 +66,7 @@ import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCEBPFP
|
|||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCEBPFProfilingScheduleDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCEBPFProfilingTaskDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCEventQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCHistoryDeleteDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCLogQueryDAO;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.dao.JDBCMetadataQueryDAO;
|
||||
|
|
@ -221,6 +223,8 @@ public abstract class JDBCStorageProvider extends ModuleProvider {
|
|||
this.registerServiceImplementation(
|
||||
ISpanAttachedEventQueryDAO.class,
|
||||
new JDBCSpanAttachedEventQueryDAO(jdbcClient, tableHelper));
|
||||
this.registerServiceImplementation(IHierarchyQueryDAO.class,
|
||||
new JDBCHierarchyQueryDAO(jdbcClient, config.getMetadataQueryMaxSize(), tableHelper));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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.storage.plugin.jdbc.common.dao;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.oap.server.core.analysis.Layer;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.instance.InstanceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.hierarchy.service.ServiceHierarchyRelationTraffic;
|
||||
import org.apache.skywalking.oap.server.core.query.type.Call;
|
||||
import org.apache.skywalking.oap.server.core.storage.query.IHierarchyQueryDAO;
|
||||
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCClient;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCEntityConverters;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCTableInstaller;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.SQLAndParameters;
|
||||
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.TableHelper;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
public class JDBCHierarchyQueryDAO implements IHierarchyQueryDAO {
|
||||
private final JDBCClient jdbcClient;
|
||||
private final int queryMaxSize;
|
||||
private final TableHelper tableHelper;
|
||||
|
||||
public JDBCHierarchyQueryDAO(JDBCClient jdbcClient, int metadataQueryMaxSize, TableHelper tableHelper) {
|
||||
this.jdbcClient = jdbcClient;
|
||||
this.queryMaxSize = metadataQueryMaxSize * 2;
|
||||
this.tableHelper = tableHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceHierarchyRelationTraffic> readAllServiceHierarchyRelations() throws Exception {
|
||||
final var results = new ArrayList<ServiceHierarchyRelationTraffic>();
|
||||
final var tables = tableHelper.getTablesWithinTTL(ServiceHierarchyRelationTraffic.INDEX_NAME);
|
||||
|
||||
for (final var table : tables) {
|
||||
final var sqlAndParameters = buildSQLForReadAllServiceRelations(table);
|
||||
results.addAll(jdbcClient.executeQuery(
|
||||
sqlAndParameters.sql(),
|
||||
this::buildServiceRelations,
|
||||
sqlAndParameters.parameters()
|
||||
)
|
||||
);
|
||||
}
|
||||
return results
|
||||
.stream()
|
||||
.limit(queryMaxSize)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstanceHierarchyRelationTraffic> readInstanceHierarchyRelations(final String instanceId,
|
||||
final String layer) throws Exception {
|
||||
final var results = new ArrayList<InstanceHierarchyRelationTraffic>();
|
||||
final var tables = tableHelper.getTablesWithinTTL(InstanceHierarchyRelationTraffic.INDEX_NAME);
|
||||
final var layerValue = Layer.valueOf(layer).value();
|
||||
List<Call.CallDetail> calls = new ArrayList<>();
|
||||
|
||||
for (final var table : tables) {
|
||||
final var sqlAndParameters = buildSQLForReadInstanceRelations(table, instanceId, layerValue);
|
||||
results.addAll(jdbcClient.executeQuery(
|
||||
sqlAndParameters.sql(),
|
||||
this::buildInstanceRelations,
|
||||
sqlAndParameters.parameters()
|
||||
)
|
||||
);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
protected SQLAndParameters buildSQLForReadAllServiceRelations(String table) {
|
||||
final var sql = new StringBuilder();
|
||||
final var parameters = new ArrayList<>(5);
|
||||
sql.append("select * from ").append(table)
|
||||
.append(" where ").append(JDBCTableInstaller.TABLE_COLUMN).append(" = ? ");
|
||||
parameters.add(ServiceHierarchyRelationTraffic.INDEX_NAME);
|
||||
sql.append(" limit ").append(queryMaxSize);
|
||||
return new SQLAndParameters(sql.toString(), parameters);
|
||||
}
|
||||
|
||||
protected SQLAndParameters buildSQLForReadInstanceRelations(String table, String instanceId, int layerValue) {
|
||||
final var sql = new StringBuilder();
|
||||
final var parameters = new ArrayList<>(5) {
|
||||
{
|
||||
add(InstanceHierarchyRelationTraffic.INDEX_NAME);
|
||||
add(instanceId);
|
||||
add(layerValue);
|
||||
add(instanceId);
|
||||
add(layerValue);
|
||||
}
|
||||
};
|
||||
sql.append("select * from ").append(table)
|
||||
.append(" where ").append(JDBCTableInstaller.TABLE_COLUMN).append(" = ? ")
|
||||
.append("and ((").append(InstanceHierarchyRelationTraffic.INSTANCE_ID)
|
||||
.append("=? and ")
|
||||
.append(InstanceHierarchyRelationTraffic.SERVICE_LAYER)
|
||||
.append("=?")
|
||||
.append(") or (")
|
||||
.append(InstanceHierarchyRelationTraffic.RELATED_INSTANCE_ID)
|
||||
.append("=? and ")
|
||||
.append(InstanceHierarchyRelationTraffic.RELATED_SERVICE_LAYER)
|
||||
.append("=?")
|
||||
.append("))");
|
||||
return new SQLAndParameters(sql.toString(), parameters);
|
||||
}
|
||||
|
||||
private List<ServiceHierarchyRelationTraffic> buildServiceRelations(ResultSet resultSet) throws SQLException {
|
||||
final var relations = new ArrayList<ServiceHierarchyRelationTraffic>();
|
||||
while (resultSet.next()) {
|
||||
relations.add(new ServiceHierarchyRelationTraffic.Builder().storage2Entity(
|
||||
JDBCEntityConverters.toEntity(resultSet)));
|
||||
}
|
||||
return relations;
|
||||
}
|
||||
|
||||
private List<InstanceHierarchyRelationTraffic> buildInstanceRelations(ResultSet resultSet) throws SQLException {
|
||||
final var relations = new ArrayList<InstanceHierarchyRelationTraffic>();
|
||||
while (resultSet.next()) {
|
||||
relations.add(new InstanceHierarchyRelationTraffic.Builder().storage2Entity(
|
||||
JDBCEntityConverters.toEntity(resultSet)));
|
||||
}
|
||||
return relations;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue