This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 4e7d80f Support Metric level function `serviceRelation` in `MAL` and
binding envoy metrics into the topology. (#7399)
4e7d80f is described below
commit 4e7d80fb88a603e076f6c53ed9817d81dc55da3d
Author: wankai123 <[email protected]>
AuthorDate: Fri Aug 6 17:09:13 2021 +0800
Support Metric level function `serviceRelation` in `MAL` and binding envoy
metrics into the topology. (#7399)
* Support Metric level function `serviceRelation` in `MAL`.
* Support envoy metrics binding into the topology.
* add istio args
* remove istio 1.7
Co-authored-by: 吴晟 Wu Sheng <[email protected]>
Co-authored-by: Jared Tan <[email protected]>
Co-authored-by: Zhenxu <[email protected]>
---
.github/workflows/e2e.istio.yaml | 15 +-
CHANGES.md | 2 +
docs/en/concepts-and-designs/mal.md | 4 +-
docs/en/setup/envoy/metrics_service_setting.md | 23 +-
.../skywalking/oap/meter/analyzer/Analyzer.java | 52 +++-
.../skywalking/oap/meter/analyzer/dsl/DSL.java | 2 +
.../EndpointEntityDescription.java | 5 -
.../dsl/EntityDescription/EntityDescription.java | 6 -
.../InstanceEntityDescription.java | 5 -
.../ServiceEntityDescription.java | 10 -
....java => ServiceRelationEntityDescription.java} | 17 +-
.../oap/meter/analyzer/dsl/SampleFamily.java | 108 +++++--
.../oap/meter/analyzer/dsl/ScopeTest.java | 320 +++++++++++++++++----
.../envoy-metrics-rules/envoy-svc-relation.yaml | 48 ++++
.../main/resources/envoy-metrics-rules/envoy.yaml | 16 +-
.../server-bootstrap/src/main/resources/log4j2.xml | 2 +
.../main/resources/metadata-service-mapping.yaml | 2 +-
.../ui-initialized-templates/istio-dp.yml | 34 +--
.../topology-service-relation.yml | 80 ++++++
.../service/ServiceRelationClientSideMetrics.java | 7 +
.../server/core/analysis/meter/MeterEntity.java | 56 +++-
.../oap/server/core/analysis/meter/ScopeType.java | 3 +-
.../receiver/envoy/EnvoyMetricReceiverConfig.java | 2 +-
.../skywalking/e2e/metrics/MetricsQuery.java | 49 +++-
.../skywalking/e2e/mesh/MetricsServiceE2E.java | 75 ++++-
.../resources/expected/metricsservice/topo.yml | 26 +-
26 files changed, 789 insertions(+), 180 deletions(-)
diff --git a/.github/workflows/e2e.istio.yaml b/.github/workflows/e2e.istio.yaml
index ef5c45a..f123414 100644
--- a/.github/workflows/e2e.istio.yaml
+++ b/.github/workflows/e2e.istio.yaml
@@ -184,7 +184,7 @@ jobs:
strategy:
fail-fast: true
matrix:
- istio_version: [1.7.1, 1.8.2, 1.9.1]
+ istio_version: [1.8.2, 1.9.1]
env:
ISTIO_VERSION: ${{ matrix.istio_version }}
steps:
@@ -231,6 +231,14 @@ jobs:
bash ${SCRIPTS_DIR}/istio.sh \
--set profile=demo \
--set
meshConfig.defaultConfig.envoyMetricsService.address=skywalking-oap.istio-system:11800
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[0]=.*membership_healthy.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[1]=.*upstream_cx_active.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[2]=.*upstream_cx_total.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[3]=.*upstream_rq_active.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[4]=.*upstream_rq_total.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[5]=.*upstream_rq_pending_active.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[6]=.*lb_healthy_panic.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[7]=.*upstream_cx_none_healthy.*'
\
--set values.telemetry.v2.enabled=false # disable the
metadata-exchange extension intentionally to make sure metrics service doesn't
rely on it
- name: Install SkyWalking
@@ -262,7 +270,10 @@ jobs:
- name: Deploy demo services
if: env.SKIP_CI != 'true'
- run: bash ${SCRIPTS_DIR}/demo.sh
+ run: |
+ bash ${SCRIPTS_DIR}/demo.sh
+ kubectl apply -f
https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/networking/destination-rule-all.yaml
+ kubectl apply -f
https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/networking/virtual-service-all-v1.yaml
- name: Cluster Info
if: ${{ failure() }}
diff --git a/CHANGES.md b/CHANGES.md
index 983b22f..abbd7af 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -17,6 +17,8 @@ Release Notes.
1.21.
* kubernetes java client upgrade from 12.0.1 to 13.0.0
* Add `event` http receiver
+* Support Metric level function `serviceRelation` in `MAL`.
+* Support envoy metrics binding into the topology.
#### UI
diff --git a/docs/en/concepts-and-designs/mal.md
b/docs/en/concepts-and-designs/mal.md
index 752bd44..a9a92a9 100644
--- a/docs/en/concepts-and-designs/mal.md
+++ b/docs/en/concepts-and-designs/mal.md
@@ -236,13 +236,15 @@
last_server_state_sync_time_in_seconds.tagEqual('production', 'catalog').downsam
## Metric level function
-There are three levels in metric: service, instance and endpoint. They extract
level relevant labels from metric labels, then informs the meter-system the
level to which this metric belongs.
+They extract level relevant labels from metric labels, then informs the
meter-system the level to which this metric belongs.
- `servcie([svc_label1, svc_label2...])` extracts service level labels from
the array argument.
- `instance([svc_label1, svc_label2...], [ins_label1, ins_label2...])`
extracts service level labels from the first array argument,
extracts instance level labels from the second array argument.
- `endpoint([svc_label1, svc_label2...], [ep_label1, ep_label2...])` extracts
service level labels from the first array argument,
extracts
endpoint level labels from the second array argument.
+ - `serviceRelation(DetectPoint, [source_svc_label1...],
[dest_svc_label1...])` DetectPoint including `DetectPoint.CLIENT` and
`DetectPoint.SERVER`,
+ extracts `sourceService` labels from the first array argument, extracts
`destService` labels from the second array argument.
## More Examples
diff --git a/docs/en/setup/envoy/metrics_service_setting.md
b/docs/en/setup/envoy/metrics_service_setting.md
index a1ca6fd..6574ba8 100644
--- a/docs/en/setup/envoy/metrics_service_setting.md
+++ b/docs/en/setup/envoy/metrics_service_setting.md
@@ -72,7 +72,7 @@ Under this circumstance, emitting the metrics to SyWalking is
as simple as addin
```shell
istioctl install -y \
- --set profile=demo `# replace the profile as per your need` \
+ --set profile=demo # replace the profile as per your need \
--set
meshConfig.defaultConfig.envoyMetricsService.address=<skywalking.address.port.11800>
\ # replace <skywalking.address.port.11800> with your actual SkyWalking OAP
address
--set 'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[0]=.*'
```
@@ -81,11 +81,30 @@ If you already have Istio installed, you can use the
following command to apply
```shell
istioctl manifest install -y \
- --set profile=demo `# replace the profile as per your need` \
+ --set profile=demo # replace the profile as per your need \
--set
meshConfig.defaultConfig.envoyMetricsService.address=<skywalking.address.port.11800>
\ # replace <skywalking.address.port.11800> with your actual SkyWalking OAP
address
--set 'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[0]=.*'
```
+Note:
+`proxyStatsMatcher` only supported by `Istio 1.8+`.
+We recommend using `inclusionRegexps` to reserve the specific metrics which
need to analyze that can reduce Memory and CPU overhead.
+For example, OAP used these metrics:
+
+```shell
+istioctl manifest install -y \
+ --set profile=demo # replace the profile as per your need \
+ --set
meshConfig.defaultConfig.envoyMetricsService.address=<skywalking.address.port.11800>
\ # replace <skywalking.address.port.11800> with your actual SkyWalking OAP
address
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[0]=.*membership_healthy.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[1]=.*upstream_cx_active.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[2]=.*upstream_cx_total.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[3]=.*upstream_rq_active.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[4]=.*upstream_rq_total.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[5]=.*upstream_rq_pending_active.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[6]=.*lb_healthy_panic.*'
\
+ --set
'meshConfig.defaultConfig.proxyStatsMatcher.inclusionRegexps[7]=.*upstream_cx_none_healthy.*'
+```
+
# Metrics data
Some Envoy statistics are listed in this
[list](https://www.envoyproxy.io/docs/envoy/v1.17.0/configuration/upstream/cluster_manager/cluster_stats#config-cluster-manager-cluster-stats).
A sample data that contains identifier can be found [here](identify.json),
while the metrics only can be observed [here](metrics.json).
diff --git
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/Analyzer.java
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/Analyzer.java
index 4b9975e..5364b0c 100644
---
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/Analyzer.java
+++
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/Analyzer.java
@@ -39,6 +39,8 @@ import
org.apache.skywalking.oap.server.core.analysis.NodeType;
import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
import
org.apache.skywalking.oap.server.core.analysis.manual.endpoint.EndpointTraffic;
import
org.apache.skywalking.oap.server.core.analysis.manual.instance.InstanceTraffic;
+import
org.apache.skywalking.oap.server.core.analysis.manual.relation.service.ServiceRelationClientSideMetrics;
+import
org.apache.skywalking.oap.server.core.analysis.manual.relation.service.ServiceRelationServerSideMetrics;
import
org.apache.skywalking.oap.server.core.analysis.manual.service.ServiceTraffic;
import org.apache.skywalking.oap.server.core.analysis.meter.MeterEntity;
import org.apache.skywalking.oap.server.core.analysis.meter.MeterSystem;
@@ -240,11 +242,23 @@ public class Analyzer {
}
private void generateTraffic(MeterEntity entity) {
- ServiceTraffic s = new ServiceTraffic();
- s.setName(requireNonNull(entity.getServiceName()));
- s.setNodeType(NodeType.Normal);
-
s.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
- MetricsStreamProcessor.getInstance().in(s);
+ if (entity.getDetectPoint() != null) {
+ switch (entity.getDetectPoint()) {
+ case SERVER:
+ entity.setServiceName(entity.getDestServiceName());
+ toService(requireNonNull(entity.getDestServiceName()));
+ serverSide(entity);
+ break;
+ case CLIENT:
+ entity.setServiceName(entity.getSourceServiceName());
+ toService(requireNonNull(entity.getSourceServiceName()));
+ clientSide(entity);
+ break;
+ }
+ } else {
+ toService(requireNonNull(entity.getServiceName()));
+ }
+
if
(!com.google.common.base.Strings.isNullOrEmpty(entity.getInstanceName())) {
InstanceTraffic instanceTraffic = new InstanceTraffic();
instanceTraffic.setName(entity.getInstanceName());
@@ -261,4 +275,32 @@ public class Analyzer {
MetricsStreamProcessor.getInstance().in(endpointTraffic);
}
}
+
+ private void toService(String serviceName) {
+ ServiceTraffic s = new ServiceTraffic();
+ s.setName(requireNonNull(serviceName));
+ s.setNodeType(NodeType.Normal);
+
s.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
+ MetricsStreamProcessor.getInstance().in(s);
+ }
+
+ private void serverSide(MeterEntity entity) {
+ ServiceRelationServerSideMetrics metrics = new
ServiceRelationServerSideMetrics();
+
metrics.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
+ metrics.setSourceServiceId(entity.sourceServiceId());
+ metrics.setDestServiceId(entity.destServiceId());
+ metrics.setComponentId(0);
+ metrics.setEntityId(entity.id());
+ MetricsStreamProcessor.getInstance().in(metrics);
+ }
+
+ private void clientSide(MeterEntity entity) {
+ ServiceRelationClientSideMetrics metrics = new
ServiceRelationClientSideMetrics();
+
metrics.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
+ metrics.setSourceServiceId(entity.sourceServiceId());
+ metrics.setDestServiceId(entity.destServiceId());
+ metrics.setComponentId(0);
+ metrics.setEntityId(entity.id());
+ MetricsStreamProcessor.getInstance().in(metrics);
+ }
}
diff --git
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/DSL.java
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/DSL.java
index 65a93ae..bb8c737 100644
---
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/DSL.java
+++
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/DSL.java
@@ -22,6 +22,7 @@ import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.util.DelegatingScript;
import org.apache.skywalking.oap.meter.analyzer.dsl.tagOpt.K8sRetagType;
+import org.apache.skywalking.oap.server.core.source.DetectPoint;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
@@ -41,6 +42,7 @@ public final class DSL {
cc.setScriptBaseClass(DelegatingScript.class.getName());
ImportCustomizer icz = new ImportCustomizer();
icz.addImport("K8sRetagType", K8sRetagType.class.getName());
+ icz.addImport("DetectPoint", DetectPoint.class.getName());
cc.addCompilationCustomizers(icz);
GroovyShell sh = new GroovyShell(new Binding(), cc);
DelegatingScript script = (DelegatingScript) sh.parse(expression);
diff --git
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EndpointEntityDescription.java
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EndpointEntityDescription.java
index 15088cd..a7aa25d 100644
---
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EndpointEntityDescription.java
+++
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EndpointEntityDescription.java
@@ -38,9 +38,4 @@ public class EndpointEntityDescription implements
EntityDescription {
public List<String> getLabelKeys() {
return Stream.concat(this.serviceKeys.stream(),
this.endpointKeys.stream()).collect(Collectors.toList());
}
-
- @Override
- public List<String> getInstanceKeys() {
- throw new UnsupportedOperationException("Unsupported Operation of
getInstanceKeys() " + this.toString());
- }
}
diff --git
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EntityDescription.java
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EntityDescription.java
index 036d71f..24e0909 100644
---
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EntityDescription.java
+++
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EntityDescription.java
@@ -25,10 +25,4 @@ public interface EntityDescription {
ScopeType getScopeType();
List<String> getLabelKeys();
-
- List<String> getServiceKeys();
-
- List<String> getInstanceKeys();
-
- List<String> getEndpointKeys();
}
diff --git
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/InstanceEntityDescription.java
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/InstanceEntityDescription.java
index c801569..1e6013b 100644
---
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/InstanceEntityDescription.java
+++
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/InstanceEntityDescription.java
@@ -38,9 +38,4 @@ public class InstanceEntityDescription implements
EntityDescription {
public List<String> getLabelKeys() {
return Stream.concat(this.serviceKeys.stream(),
this.instanceKeys.stream()).collect(Collectors.toList());
}
-
- @Override
- public List<String> getEndpointKeys() {
- throw new UnsupportedOperationException("Unsupported Operation of
getEndpointKeys() " + this.toString());
- }
}
diff --git
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ServiceEntityDescription.java
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ServiceEntityDescription.java
index edbc6e3..c96c2b8 100644
---
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ServiceEntityDescription.java
+++
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ServiceEntityDescription.java
@@ -35,14 +35,4 @@ public class ServiceEntityDescription implements
EntityDescription {
public List<String> getLabelKeys() {
return serviceKeys;
}
-
- @Override
- public List<String> getInstanceKeys() {
- throw new UnsupportedOperationException("Unsupported Operation of
getInstanceKeys() " + this.toString());
- }
-
- @Override
- public List<String> getEndpointKeys() {
- throw new UnsupportedOperationException("Unsupported Operation of
getEndpointKeys() " + this.toString());
- }
}
diff --git
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EndpointEntityDescription.java
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ServiceRelationEntityDescription.java
similarity index 70%
copy from
oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EndpointEntityDescription.java
copy to
oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ServiceRelationEntityDescription.java
index 15088cd..a00f9eb 100644
---
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/EndpointEntityDescription.java
+++
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/EntityDescription/ServiceRelationEntityDescription.java
@@ -25,22 +25,19 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.apache.skywalking.oap.server.core.analysis.meter.ScopeType;
+import org.apache.skywalking.oap.server.core.source.DetectPoint;
@Getter
@RequiredArgsConstructor
@ToString
-public class EndpointEntityDescription implements EntityDescription {
- private final ScopeType scopeType = ScopeType.ENDPOINT;
- private final List<String> serviceKeys;
- private final List<String> endpointKeys;
+public class ServiceRelationEntityDescription implements EntityDescription {
+ private final ScopeType scopeType = ScopeType.SERVICE_RELATION;
+ private final List<String> sourceServiceKeys;
+ private final List<String> destServiceKeys;
+ private final DetectPoint detectPoint;
@Override
public List<String> getLabelKeys() {
- return Stream.concat(this.serviceKeys.stream(),
this.endpointKeys.stream()).collect(Collectors.toList());
- }
-
- @Override
- public List<String> getInstanceKeys() {
- throw new UnsupportedOperationException("Unsupported Operation of
getInstanceKeys() " + this.toString());
+ return Stream.concat(this.sourceServiceKeys.stream(),
this.destServiceKeys.stream()).collect(Collectors.toList());
}
}
diff --git
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java
index bfacea4..c153033 100644
---
a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java
+++
b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/SampleFamily.java
@@ -38,6 +38,7 @@ import
org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.EndpointEn
import
org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.EntityDescription;
import
org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.InstanceEntityDescription;
import
org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.ServiceEntityDescription;
+import
org.apache.skywalking.oap.meter.analyzer.dsl.EntityDescription.ServiceRelationEntityDescription;
import org.apache.skywalking.oap.meter.analyzer.dsl.tagOpt.K8sRetagType;
import org.apache.skywalking.oap.server.core.UnexpectedException;
import org.apache.skywalking.oap.server.core.analysis.meter.MeterEntity;
@@ -56,6 +57,7 @@ import java.util.function.DoubleBinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.apache.skywalking.oap.server.core.source.DetectPoint;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static java.util.function.UnaryOperator.identity;
@@ -213,7 +215,8 @@ public class SampleFamily {
}
if (by == null) {
double result =
Arrays.stream(samples).mapToDouble(Sample::getValue).average().orElse(0.0D);
- return SampleFamily.build(this.context,
InternalOps.newSample(samples[0].name, ImmutableMap.of(), samples[0].timestamp,
result));
+ return SampleFamily.build(
+ this.context, InternalOps.newSample(samples[0].name,
ImmutableMap.of(), samples[0].timestamp, result));
}
return SampleFamily.build(
@@ -238,7 +241,8 @@ public class SampleFamily {
}
if (by == null) {
double result = Arrays.stream(samples).mapToDouble(s ->
s.value).reduce(aggregator).orElse(0.0D);
- return SampleFamily.build(this.context,
InternalOps.newSample(samples[0].name, ImmutableMap.of(), samples[0].timestamp,
result));
+ return SampleFamily.build(
+ this.context, InternalOps.newSample(samples[0].name,
ImmutableMap.of(), samples[0].timestamp, result));
}
return SampleFamily.build(
this.context,
@@ -320,15 +324,19 @@ public class SampleFamily {
Object r = c.call(arg);
return sample.toBuilder()
.labels(
-
ImmutableMap.copyOf(Optional.ofNullable((r instanceof Map) ? (Map<String,
String>) r : null)
-
.orElse(arg)))
+ ImmutableMap.copyOf(
+ Optional.ofNullable((r instanceof
Map) ? (Map<String, String>) r : null)
+ .orElse(arg)))
.build();
}).toArray(Sample[]::new)
);
}
/* k8s retags*/
- public SampleFamily retagByK8sMeta(String newLabelName, K8sRetagType type,
String existingLabelName, String namespaceLabelName) {
+ public SampleFamily retagByK8sMeta(String newLabelName,
+ K8sRetagType type,
+ String existingLabelName,
+ String namespaceLabelName) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(newLabelName));
Preconditions.checkArgument(!Strings.isNullOrEmpty(existingLabelName));
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespaceLabelName));
@@ -337,7 +345,8 @@ public class SampleFamily {
return EMPTY;
}
- return SampleFamily.build(this.context, type.execute(samples,
newLabelName, existingLabelName, namespaceLabelName));
+ return SampleFamily.build(
+ this.context, type.execute(samples, newLabelName,
existingLabelName, namespaceLabelName));
}
public SampleFamily histogram() {
@@ -368,8 +377,17 @@ public class SampleFamily {
double r = this.context.histogramType ==
HistogramType.ORDINARY ? s.value : s.value - pre.get();
pre.set(s.value);
ImmutableMap<String, String> ll =
ImmutableMap.<String, String>builder()
- .putAll(Maps.filterKeys(s.labels, key ->
!Objects.equals(key, le)))
- .put("le", String.valueOf((long)
((Double.parseDouble(this.context.histogramType == HistogramType.ORDINARY ?
s.labels.get(le) : preLe.get())) * scale))).build();
+
.putAll(Maps.filterKeys(s.labels,
+
key -> !Objects.equals(
+
key, le)
+ ))
+ .put(
+
"le", String.valueOf(
+
(long) ((Double.parseDouble(
+
this.context.histogramType == HistogramType.ORDINARY ? s.labels
+
.get(
+
le) : preLe.get())) * scale)))
+
.build();
preLe.set(s.labels.get(le));
return InternalOps.newSample(s.name, ll,
s.timestamp, r);
})
@@ -381,7 +399,8 @@ public class SampleFamily {
Preconditions.checkArgument(percentiles.size() > 0);
int[] p = percentiles.stream().mapToInt(i -> i).toArray();
ExpressionParsingContext.get().ifPresent(ctx -> {
- Preconditions.checkState(ctx.isHistogram, "histogram() should be
invoked before invoking histogram_percentile()");
+ Preconditions.checkState(
+ ctx.isHistogram, "histogram() should be invoked before
invoking histogram_percentile()");
ctx.percentiles = p;
});
return this;
@@ -402,7 +421,6 @@ public class SampleFamily {
public SampleFamily instance(List<String> serviceKeys, List<String>
instanceKeys) {
Preconditions.checkArgument(serviceKeys.size() > 0);
Preconditions.checkArgument(instanceKeys.size() > 0);
- ExpressionParsingContext.get().ifPresent(ctx -> ctx.scopeType =
ScopeType.SERVICE_INSTANCE);
ExpressionParsingContext.get().ifPresent(ctx -> {
ctx.scopeType = ScopeType.SERVICE_INSTANCE;
ctx.scopeLabels.addAll(serviceKeys);
@@ -417,7 +435,6 @@ public class SampleFamily {
public SampleFamily endpoint(List<String> serviceKeys, List<String>
endpointKeys) {
Preconditions.checkArgument(serviceKeys.size() > 0);
Preconditions.checkArgument(endpointKeys.size() > 0);
- ExpressionParsingContext.get().ifPresent(ctx -> ctx.scopeType =
ScopeType.ENDPOINT);
ExpressionParsingContext.get().ifPresent(ctx -> {
ctx.scopeType = ScopeType.ENDPOINT;
ctx.scopeLabels.addAll(serviceKeys);
@@ -429,10 +446,26 @@ public class SampleFamily {
return createMeterSamples(new EndpointEntityDescription(serviceKeys,
endpointKeys));
}
+ public SampleFamily serviceRelation(DetectPoint detectPoint, List<String>
sourceServiceKeys, List<String> destServiceKeys) {
+ Preconditions.checkArgument(sourceServiceKeys.size() > 0);
+ Preconditions.checkArgument(destServiceKeys.size() > 0);
+ ExpressionParsingContext.get().ifPresent(ctx -> {
+ ctx.scopeType = ScopeType.SERVICE_RELATION;
+ ctx.scopeLabels.addAll(sourceServiceKeys);
+ ctx.scopeLabels.addAll(destServiceKeys);
+ });
+ if (this == EMPTY) {
+ return EMPTY;
+ }
+ return createMeterSamples(new
ServiceRelationEntityDescription(sourceServiceKeys, destServiceKeys,
detectPoint));
+ }
+
private SampleFamily createMeterSamples(EntityDescription
entityDescription) {
Map<MeterEntity, Sample[]> meterSamples = new HashMap<>();
Arrays.stream(samples)
- .collect(groupingBy(it ->
InternalOps.getLabels(entityDescription.getLabelKeys(), it),
mapping(identity(), toList())))
+ .collect(groupingBy(it ->
InternalOps.getLabels(entityDescription.getLabelKeys(), it),
+ mapping(identity(), toList())
+ ))
.forEach((labels, samples) -> {
MeterEntity meterEntity =
InternalOps.buildMeterEntity(samples, entityDescription);
meterSamples.put(meterEntity, InternalOps.left(samples,
entityDescription.getLabelKeys()));
@@ -452,7 +485,10 @@ public class SampleFamily {
Sample[] ss = Arrays.stream(samples)
.filter(sample -> ll.entrySet()
.stream()
- .allMatch(entry ->
op.apply(sample.labels.getOrDefault(entry.getKey(), ""), entry.getValue())))
+ .allMatch(
+ entry ->
op.apply(sample.labels.getOrDefault(entry.getKey(), ""),
+
entry.getValue()
+ )))
.toArray(Sample[]::new);
return ss.length > 0 ? SampleFamily.build(this.context, ss) : EMPTY;
}
@@ -480,7 +516,10 @@ public class SampleFamily {
Sample[] ss = Arrays.stream(samples)
.flatMap(cs ->
io.vavr.collection.Stream.of(another.samples)
.find(as
-> cs.labels.equals(as.labels))
- .map(as ->
cs.toBuilder().value(transform.apply(cs.value, as.value)))
+ .map(as ->
cs.toBuilder()
+
.value(transform.apply(cs.value,
+
as.value
+
)))
.map(Sample.SampleBuilder::build)
.toJavaStream())
.toArray(Sample[]::new);
@@ -506,9 +545,9 @@ public class SampleFamily {
static RunningContext instance() {
return RunningContext.builder()
- .histogramType(HistogramType.CUMULATIVE)
- .defaultHistogramBucketUnit(TimeUnit.SECONDS)
- .build();
+ .histogramType(HistogramType.CUMULATIVE)
+ .defaultHistogramBucketUnit(TimeUnit.SECONDS)
+ .build();
}
private Map<MeterEntity, Sample[]> meterSamples = new HashMap<>();
@@ -523,8 +562,10 @@ public class SampleFamily {
private static Sample[] left(List<Sample> samples, List<String>
labelKeys) {
return samples.stream().map(s -> {
ImmutableMap<String, String> ll = ImmutableMap.<String,
String>builder()
- .putAll(Maps.filterKeys(s.labels, key ->
!labelKeys.contains(key)))
- .build();
+
.putAll(Maps.filterKeys(s.labels,
+
key -> !labelKeys.contains(key)
+ ))
+ .build();
return s.toBuilder().labels(ll).build();
}).toArray(Sample[]::new);
}
@@ -540,22 +581,37 @@ public class SampleFamily {
EntityDescription
entityDescription) {
switch (entityDescription.getScopeType()) {
case SERVICE:
- return MeterEntity.newService(InternalOps.dim(samples,
entityDescription.getServiceKeys()));
+ ServiceEntityDescription serviceEntityDescription =
(ServiceEntityDescription) entityDescription;
+ return MeterEntity.newService(InternalOps.dim(samples,
serviceEntityDescription.getServiceKeys()));
case SERVICE_INSTANCE:
+ InstanceEntityDescription instanceEntityDescription =
(InstanceEntityDescription) entityDescription;
return MeterEntity.newServiceInstance(
- InternalOps.dim(samples,
entityDescription.getServiceKeys()),
- InternalOps.dim(samples,
entityDescription.getInstanceKeys())
+ InternalOps.dim(samples,
instanceEntityDescription.getServiceKeys()),
+ InternalOps.dim(samples,
instanceEntityDescription.getInstanceKeys())
);
case ENDPOINT:
+ EndpointEntityDescription endpointEntityDescription =
(EndpointEntityDescription) entityDescription;
return MeterEntity.newEndpoint(
- InternalOps.dim(samples,
entityDescription.getServiceKeys()),
- InternalOps.dim(samples,
entityDescription.getEndpointKeys())
+ InternalOps.dim(samples,
endpointEntityDescription.getServiceKeys()),
+ InternalOps.dim(samples,
endpointEntityDescription.getEndpointKeys())
+ );
+ case SERVICE_RELATION:
+ ServiceRelationEntityDescription
serviceRelationEntityDescription = (ServiceRelationEntityDescription)
entityDescription;
+ return MeterEntity.newServiceRelation(
+ InternalOps.dim(samples,
serviceRelationEntityDescription.getSourceServiceKeys()),
+ InternalOps.dim(samples,
serviceRelationEntityDescription.getDestServiceKeys()),
+ serviceRelationEntityDescription.getDetectPoint()
);
- default: throw new UnexpectedException("Unexpected scope type
of entityDescription " + entityDescription.toString());
+ default:
+ throw new UnexpectedException(
+ "Unexpected scope type of entityDescription " +
entityDescription.toString());
}
}
- private static Sample newSample(String name, ImmutableMap<String,
String> labels, long timestamp, double newValue) {
+ private static Sample newSample(String name,
+ ImmutableMap<String, String> labels,
+ long timestamp,
+ double newValue) {
return Sample.builder()
.value(newValue)
.labels(labels)
diff --git
a/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/ScopeTest.java
b/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/ScopeTest.java
index fcafba5..6fb6c07 100644
---
a/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/ScopeTest.java
+++
b/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/ScopeTest.java
@@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.analysis.meter.MeterEntity;
+import org.apache.skywalking.oap.server.core.source.DetectPoint;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -60,10 +61,26 @@ public class ScopeTest {
"sum_service",
of("http_success_request", SampleFamilyBuilder.newBuilder(
Sample.builder().labels(of("idc",
"t1")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"svc", "catalog")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"svc", "product")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"instance", "10.0.0.1")).value(100).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"instance", "10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "svc",
"catalog"))
+ .value(51)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "svc",
"product"))
+ .value(50)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "instance",
"10.0.0.1"))
+ .value(100)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "instance",
"10.0.0.1"))
+ .value(3)
+ .name("http_success_request")
+ .build()
).build()),
"http_success_request.sum(['idc']).service(['idc'])",
false,
@@ -84,10 +101,26 @@ public class ScopeTest {
"sum_service_labels",
of("http_success_request", SampleFamilyBuilder.newBuilder(
Sample.builder().labels(of("idc",
"t1")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"svc", "catalog")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"svc", "product")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"instance", "10.0.0.1")).value(100).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"instance", "10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "svc",
"catalog"))
+ .value(51)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "svc",
"product"))
+ .value(50)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "instance",
"10.0.0.1"))
+ .value(100)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "instance",
"10.0.0.1"))
+ .value(3)
+ .name("http_success_request")
+ .build()
).build()),
"http_success_request.sum(['region', 'idc']).service(['idc'])",
false,
@@ -96,13 +129,24 @@ public class ScopeTest {
put(
MeterEntity.newService("t1"),
new Sample[] {
- Sample.builder().labels(of("region",
"")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("region",
"us")).value(150).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("region", ""))
+ .value(50)
+ .name("http_success_request").build(),
+ Sample.builder()
+ .labels(of("region", "us"))
+ .value(150)
+ .name("http_success_request").build()
}
);
put(
MeterEntity.newService("t3"),
- new Sample[] {Sample.builder().labels(of("region",
"cn")).value(54).name("http_success_request").build()}
+ new Sample[] {
+ Sample.builder()
+ .labels(of("region", "cn"))
+ .value(54)
+ .name("http_success_request").build()
+ }
);
}
}
@@ -111,10 +155,26 @@ public class ScopeTest {
"sum_service_m",
of("http_success_request", SampleFamilyBuilder.newBuilder(
Sample.builder().labels(of("idc",
"t1")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"svc", "catalog")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"svc", "product")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"instance", "10.0.0.1")).value(100).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"instance", "10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "svc",
"catalog"))
+ .value(51)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "svc",
"product"))
+ .value(50)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "instance",
"10.0.0.1"))
+ .value(100)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "instance",
"10.0.0.1"))
+ .value(3)
+ .name("http_success_request")
+ .build()
).build()),
"http_success_request.sum(['idc', 'region']).service(['idc' ,
'region'])",
false,
@@ -139,10 +199,26 @@ public class ScopeTest {
"sum_service_endpiont",
of("http_success_request", SampleFamilyBuilder.newBuilder(
Sample.builder().labels(of("idc",
"t1")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"svc", "catalog")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"svc", "product")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"instance", "10.0.0.1")).value(100).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"instance", "10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "svc",
"catalog"))
+ .value(51)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "svc",
"product"))
+ .value(50)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "instance",
"10.0.0.1"))
+ .value(100)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "instance",
"10.0.0.1"))
+ .value(3)
+ .name("http_success_request")
+ .build()
).build()),
"http_success_request.sum(['region', 'idc']).endpoint(['idc']
, ['region'])",
false,
@@ -168,10 +244,26 @@ public class ScopeTest {
"sum_service_endpiont_labels",
of("http_success_request", SampleFamilyBuilder.newBuilder(
Sample.builder().labels(of("idc",
"t1")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"svc", "catalog")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"svc", "product")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"instance", "10.0.0.1")).value(100).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"instance", "10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "svc",
"catalog"))
+ .value(51)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "svc",
"product"))
+ .value(50)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "instance",
"10.0.0.1"))
+ .value(100)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "instance",
"10.0.0.1"))
+ .value(3)
+ .name("http_success_request")
+ .build()
).build()),
"http_success_request.sum(['region', 'idc' ,
'instance']).endpoint(['idc'] , ['region'])",
false,
@@ -180,20 +272,37 @@ public class ScopeTest {
put(
MeterEntity.newEndpoint("t1", "us"),
new Sample[] {
- Sample.builder().labels(of("instance",
"")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("instance",
"10.0.0.1")).value(100).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(50)
+ .name("http_success_request").build(),
+ Sample.builder()
+ .labels(of("instance", "10.0.0.1"))
+ .value(100)
+ .name("http_success_request").build()
}
);
put(
MeterEntity.newEndpoint("t3", "cn"),
new Sample[] {
- Sample.builder().labels(of("instance",
"")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("instance",
"10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(51)
+ .name("http_success_request").build(),
+ Sample.builder()
+ .labels(of("instance", "10.0.0.1"))
+ .value(3)
+ .name("http_success_request").build()
}
);
put(
MeterEntity.newEndpoint("t1", ""),
- new Sample[]
{Sample.builder().labels(of("instance",
"")).value(50).name("http_success_request").build()}
+ new Sample[] {
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(50)
+ .name("http_success_request").build()
+ }
);
}
}
@@ -202,8 +311,16 @@ public class ScopeTest {
"sum_service_endpiont_labels_m",
of("http_success_request", SampleFamilyBuilder.newBuilder(
Sample.builder().labels(of("idc",
"t1")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"svc", "product")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"svc", "catalog")).value(50).name("http_success_request").build(),
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "svc",
"product"))
+ .value(51)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "svc",
"catalog"))
+ .value(50)
+ .name("http_success_request")
+ .build(),
Sample.builder()
.labels(of("idc", "t1", "region", "us", "svc",
"catalog", "instance", "10.0.0.1"))
.value(100)
@@ -222,20 +339,37 @@ public class ScopeTest {
put(
MeterEntity.newEndpoint("t1", "us.catalog"),
new Sample[] {
- Sample.builder().labels(of("instance",
"")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("instance",
"10.0.0.1")).value(100).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(50)
+ .name("http_success_request").build(),
+ Sample.builder()
+ .labels(of("instance", "10.0.0.1"))
+ .value(100)
+ .name("http_success_request").build()
}
);
put(
MeterEntity.newEndpoint("t3", "cn.product"),
new Sample[] {
- Sample.builder().labels(of("instance",
"")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("instance",
"10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(51)
+ .name("http_success_request").build(),
+ Sample.builder()
+ .labels(of("instance", "10.0.0.1"))
+ .value(3)
+ .name("http_success_request").build()
}
);
put(
MeterEntity.newEndpoint("t1", ""),
- new Sample[]
{Sample.builder().labels(of("instance",
"")).value(50).name("http_success_request").build()}
+ new Sample[] {
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(50)
+ .name("http_success_request").build()
+ }
);
}
}
@@ -244,10 +378,26 @@ public class ScopeTest {
"sum_service_instance",
of("http_success_request", SampleFamilyBuilder.newBuilder(
Sample.builder().labels(of("idc",
"t1")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"svc", "catalog")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"svc", "product")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"instance", "10.0.0.1")).value(100).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"instance", "10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "svc",
"catalog"))
+ .value(51)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "svc",
"product"))
+ .value(50)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "instance",
"10.0.0.1"))
+ .value(100)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "instance",
"10.0.0.1"))
+ .value(3)
+ .name("http_success_request")
+ .build()
).build()),
"http_success_request.sum(['region', 'idc']).instance(['idc']
, ['region'])",
false,
@@ -272,10 +422,26 @@ public class ScopeTest {
"sum_service_instance_labels",
of("http_success_request", SampleFamilyBuilder.newBuilder(
Sample.builder().labels(of("idc",
"t1")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"svc", "catalog")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"svc", "product")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t1", "region", "us",
"instance", "10.0.0.1")).value(100).name("http_success_request").build(),
- Sample.builder().labels(of("idc", "t3", "region", "cn",
"instance", "10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "svc",
"catalog"))
+ .value(51)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "svc",
"product"))
+ .value(50)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t1", "region", "us", "instance",
"10.0.0.1"))
+ .value(100)
+ .name("http_success_request")
+ .build(),
+ Sample.builder()
+ .labels(of("idc", "t3", "region", "cn", "instance",
"10.0.0.1"))
+ .value(3)
+ .name("http_success_request")
+ .build()
).build()),
"http_success_request.sum(['region', 'idc' ,
'instance']).instance(['idc'] , ['region'])",
false,
@@ -284,25 +450,81 @@ public class ScopeTest {
put(
MeterEntity.newServiceInstance("t1", "us"),
new Sample[] {
- Sample.builder().labels(of("instance",
"")).value(50).name("http_success_request").build(),
- Sample.builder().labels(of("instance",
"10.0.0.1")).value(100).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(50)
+ .name("http_success_request").build(),
+ Sample.builder()
+ .labels(of("instance", "10.0.0.1"))
+ .value(100)
+ .name("http_success_request").build()
}
);
put(
MeterEntity.newServiceInstance("t3", "cn"),
new Sample[] {
- Sample.builder().labels(of("instance",
"")).value(51).name("http_success_request").build(),
- Sample.builder().labels(of("instance",
"10.0.0.1")).value(3).name("http_success_request").build()
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(51)
+ .name("http_success_request").build(),
+ Sample.builder()
+ .labels(of("instance", "10.0.0.1"))
+ .value(3)
+ .name("http_success_request").build()
}
);
put(
MeterEntity.newServiceInstance("t1", ""),
- new Sample[]
{Sample.builder().labels(of("instance",
"")).value(50).name("http_success_request").build()}
+ new Sample[] {
+ Sample.builder()
+ .labels(of("instance", ""))
+ .value(50)
+ .name("http_success_request").build()
+ }
);
}
}
},
- });
+ {
+ "sum_service_relation",
+ of("envoy_cluster_metrics_up_cx_active",
SampleFamilyBuilder.newBuilder(
+ Sample.builder()
+ .labels(of("app", "productpage", "cluster_name",
"details"))
+ .value(11)
+ .name("envoy_cluster_metrics_up_cx_active")
+ .build(),
+ Sample.builder()
+ .labels(of("app", "productpage", "cluster_name",
"reviews"))
+ .value(16)
+ .name("envoy_cluster_metrics_up_cx_active")
+ .build()
+ ).build()),
+ "envoy_cluster_metrics_up_cx_active.sum(['app'
,'cluster_name']).serviceRelation(DetectPoint.CLIENT, ['app'],
['cluster_name'])",
+ false,
+ new HashMap<MeterEntity, Sample[]>() {
+ {
+ put(
+ MeterEntity.newServiceRelation("productpage",
"details", DetectPoint.CLIENT),
+ new Sample[] {
+ Sample.builder()
+ .labels(of())
+ .value(11)
+
.name("envoy_cluster_metrics_up_cx_active").build()
+ }
+ );
+ put(
+ MeterEntity.newServiceRelation("productpage",
"reviews", DetectPoint.CLIENT),
+ new Sample[] {
+ Sample.builder()
+ .labels(of())
+ .value(16)
+
.name("envoy_cluster_metrics_up_cx_active").build()
+ }
+ );
+ }
+ }
+ }
+ });
}
@Test
diff --git
a/oap-server/server-bootstrap/src/main/resources/envoy-metrics-rules/envoy-svc-relation.yaml
b/oap-server/server-bootstrap/src/main/resources/envoy-metrics-rules/envoy-svc-relation.yaml
new file mode 100644
index 0000000..a682edc
--- /dev/null
+++
b/oap-server/server-bootstrap/src/main/resources/envoy-metrics-rules/envoy-svc-relation.yaml
@@ -0,0 +1,48 @@
+# 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.
+
+# This will parse a textual representation of a duration. The formats
+# accepted are based on the ISO-8601 duration format {@code PnDTnHnMn.nS}
+# with days considered to be exactly 24 hours.
+# <p>
+# Examples:
+# <pre>
+# "PT20.345S" -- parses as "20.345 seconds"
+# "PT15M" -- parses as "15 minutes" (where a minute is 60 seconds)
+# "PT10H" -- parses as "10 hours" (where an hour is 3600 seconds)
+# "P2D" -- parses as "2 days" (where a day is 24 hours or 86400
seconds)
+# "P2DT3H4M" -- parses as "2 days, 3 hours and 4 minutes"
+# "P-6H3M" -- parses as "-6 hours and +3 minutes"
+# "-P6H3M" -- parses as "-6 hours and -3 minutes"
+# "-P-6H+3M" -- parses as "+6 hours and -3 minutes"
+# </pre>
+
+expSuffix: serviceRelation(DetectPoint.CLIENT, ['app'], ['cluster_name'])
+metricPrefix: envoy_sr
+metricsRules:
+ - name: cluster_up_cx_active
+ exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_cx_active').tagMatch('metrics_name' ,
'cluster.outbound.+').sum(['app' ,'cluster_name'])
+ - name: cluster_up_cx_incr
+ exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_cx_total').tagMatch('metrics_name' ,
'cluster.outbound.+').sum(['app' , 'cluster_name']).increase('PT1M')
+ - name: cluster_up_rq_active
+ exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_rq_active').tagMatch('metrics_name' ,
'cluster.outbound.+').sum(['app', 'cluster_name'])
+ - name: cluster_up_rq_incr
+ exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_rq_total').tagMatch('metrics_name' ,
'cluster.outbound.+').sum(['app' , 'cluster_name']).increase('PT1M')
+ - name: cluster_up_rq_pending_active
+ exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_rq_pending_active').tagMatch('metrics_name' ,
'cluster.outbound.+').sum(['app' , 'cluster_name'])
+ - name: cluster_lb_healthy_panic_incr
+ exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+lb_healthy_panic').tagMatch('metrics_name' ,
'cluster.outbound.+').sum(['app', 'cluster_name']).increase('PT1M')
+ - name: cluster_up_cx_none_healthy_incr
+ exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_cx_none_healthy').tagMatch('metrics_name' ,
'cluster.outbound.+').sum(['app', 'cluster_name']).increase('PT1M')
diff --git
a/oap-server/server-bootstrap/src/main/resources/envoy-metrics-rules/envoy.yaml
b/oap-server/server-bootstrap/src/main/resources/envoy-metrics-rules/envoy.yaml
index 787025a..db3e5e9 100644
---
a/oap-server/server-bootstrap/src/main/resources/envoy-metrics-rules/envoy.yaml
+++
b/oap-server/server-bootstrap/src/main/resources/envoy-metrics-rules/envoy.yaml
@@ -61,17 +61,17 @@ metricsRules:
# envoy_cluster_metrics
- name: cluster_membership_healthy
exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+membership_healthy').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').tagNotMatch('cluster_name' ,
'.+kube-system').sum(['app', 'instance' , 'cluster_name'])
- - name: cluster_upstream_cx_active
+ - name: cluster_up_cx_active
exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_cx_active').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' ,
'cluster_name'])
- - name: cluster_upstream_cx_increase
+ - name: cluster_up_cx_incr
exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_cx_total').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' ,
'cluster_name']).increase('PT1M')
- - name: cluster_upstream_rq_active
+ - name: cluster_up_rq_active
exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_rq_active').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' ,
'cluster_name'])
- - name: cluster_upstream_rq_increase
+ - name: cluster_up_rq_incr
exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_rq_total').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' ,
'cluster_name']).increase('PT1M')
- - name: cluster_upstream_rq_pending_active
+ - name: cluster_up_rq_pending_active
exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_rq_pending_active').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' ,
'cluster_name'])
- - name: cluster_lb_healthy_panic_increase
- exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+lb_healthy_panic').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' ,
'cluster_name'])
- - name: cluster_upstream_cx_none_healthy_increase
+ - name: cluster_lb_healthy_panic_incr
+ exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+lb_healthy_panic').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' ,
'cluster_name']).increase('PT1M')
+ - name: cluster_up_cx_none_healthy_incr
exp: envoy_cluster_metrics.tagMatch('metrics_name' ,
'.+upstream_cx_none_healthy').tagMatch('metrics_name' ,
'cluster.outbound.+|cluster.inbound.+').sum(['app', 'instance' ,
'cluster_name']).increase('PT1M')
diff --git a/oap-server/server-bootstrap/src/main/resources/log4j2.xml
b/oap-server/server-bootstrap/src/main/resources/log4j2.xml
index a14272f..92c8884 100644
--- a/oap-server/server-bootstrap/src/main/resources/log4j2.xml
+++ b/oap-server/server-bootstrap/src/main/resources/log4j2.xml
@@ -37,6 +37,8 @@
<logger name="org.apache.skywalking.oap.server.core.analysis.worker"
level="DEBUG" />
<logger name="org.apache.skywalking.oap.server.core.remote.client"
level="DEBUG"/>
<logger name="org.apache.skywalking.oap.server.library.buffer"
level="INFO"/>
+ <logger
name="org.apache.skywalking.oap.server.receiver.envoy.MetricServiceGRPCHandler"
level="INFO"/>
+ <logger
name="org.apache.skywalking.oap.meter.analyzer.prometheus.PrometheusMetricConverter"
level="INFO"/>
<Root level="DEBUG">
<AppenderRef ref="Console"/>
</Root>
diff --git
a/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
b/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
index acb4d43..7737432 100644
---
a/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
+++
b/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
@@ -13,5 +13,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-serviceName:
${LABELS."service.istio.io/canonical-revision"}.${LABELS."service.istio.io/canonical-name",LABELS."app.kubernetes.io/name",LABELS.app}.${NAMESPACE}
+serviceName:
${LABELS."service.istio.io/canonical-name",LABELS."app.kubernetes.io/name",LABELS.app}
serviceInstanceName: ${NAME}
diff --git
a/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/istio-dp.yml
b/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/istio-dp.yml
index 2c674ca..b706460 100644
---
a/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/istio-dp.yml
+++
b/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/istio-dp.yml
@@ -86,58 +86,58 @@ templates:
},
{
"width": "3",
- "title": "Upstream CX Active",
+ "title": "Upstream Connection Active",
"height": 350,
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "LABELED_VALUE",
- "metricName": "envoy_cluster_upstream_cx_active",
+ "metricName": "envoy_cluster_up_cx_active",
"queryMetricType": "readLabeledMetricsValues",
"chartType": "ChartLine"
},
{
"width": "3",
- "title": "Upstream CX Increase",
+ "title": "Upstream Connection Increase",
"height": 350,
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "LABELED_VALUE",
- "metricName": "envoy_cluster_upstream_cx_increase",
+ "metricName": "envoy_cluster_up_cx_incr",
"queryMetricType": "readLabeledMetricsValues",
- "unit": "pm",
+ "unit": "Per Minute",
"chartType": "ChartLine"
},
{
"width": "3",
- "title": "Upstream RQ Active",
+ "title": "Upstream Request Active",
"height": 350,
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "LABELED_VALUE",
- "metricName": "envoy_cluster_upstream_rq_active",
+ "metricName": "envoy_cluster_up_rq_active",
"queryMetricType": "readLabeledMetricsValues",
"chartType": "ChartLine"
},
{
"width": "3",
- "title": "Upstream RQ Increase",
+ "title": "Upstream Request Increase",
"height": 350,
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "LABELED_VALUE",
- "metricName": "envoy_cluster_upstream_rq_increase",
+ "metricName": "envoy_cluster_up_rq_incr",
"queryMetricType": "readLabeledMetricsValues",
- "unit": "pm",
+ "unit": "Per Minute",
"chartType": "ChartLine"
},
{
"width": "3",
- "title": "Upstream RQ Pending Active",
+ "title": "Upstream Request Pending Active",
"height": 350,
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "LABELED_VALUE",
- "metricName": "envoy_cluster_upstream_rq_pending_active",
+ "metricName": "envoy_cluster_up_rq_pending_active",
"queryMetricType": "readLabeledMetricsValues",
"chartType": "ChartLine"
},
@@ -148,21 +148,21 @@ templates:
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "LABELED_VALUE",
- "metricName": "envoy_cluster_lb_healthy_panic_increase",
+ "metricName": "envoy_cluster_lb_healthy_panic_incr",
"queryMetricType": "readLabeledMetricsValues",
- "unit": "pm",
+ "unit": "Per Minute",
"chartType": "ChartLine"
},
{
"width": "3",
- "title": "Upstream CX None Healthy Increase",
+ "title": "Upstream Connection None Healthy Increase",
"height": 350,
"entityType": "ServiceInstance",
"independentSelector": false,
"metricType": "LABELED_VALUE",
- "metricName":
"envoy_cluster_upstream_cx_none_healthy_increase",
+ "metricName": "envoy_cluster_up_cx_none_healthy_incr",
"queryMetricType": "readLabeledMetricsValues",
- "unit": "pm",
+ "unit": "Per Minute",
"chartType": "ChartLine"
}
]
diff --git
a/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/topology-service-relation.yml
b/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/topology-service-relation.yml
index efc5a61..ee5e69b 100644
---
a/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/topology-service-relation.yml
+++
b/oap-server/server-bootstrap/src/main/resources/ui-initialized-templates/topology-service-relation.yml
@@ -243,6 +243,86 @@ templates:
"unit":"PPM - Packets Per Minutes"
}
]
+ },
+ "envoy_metrics":{
+ "server":[
+ ],
+ "client":[
+ {
+ "width":12,
+ "title":"Upstream Connection Active",
+ "height":"200",
+ "entityType":"ServiceRelation",
+ "metricType":"REGULAR_VALUE",
+ "metricName":"envoy_sr_cluster_up_cx_active",
+ "queryMetricType":"readMetricsValues",
+ "chartType":"ChartLine"
+ },
+ {
+ "width":12,
+ "title":"Upstream Connection Increase",
+ "height":"200",
+ "entityType":"ServiceRelation",
+ "metricType":"REGULAR_VALUE",
+ "metricName":"envoy_sr_cluster_up_cx_incr",
+ "queryMetricType":"readMetricsValues",
+ "chartType":"ChartLine",
+ "unit":"Per Minute"
+ },
+ {
+ "width":12,
+ "title":"Upstream Request Active",
+ "height":"200",
+ "entityType":"ServiceRelation",
+ "metricType":"REGULAR_VALUE",
+ "metricName":"envoy_sr_cluster_up_rq_active",
+ "queryMetricType":"readMetricsValues",
+ "chartType":"ChartLine"
+ },
+ {
+ "width":12,
+ "title":"Upstream Request Increase",
+ "height":"200",
+ "entityType":"ServiceRelation",
+ "metricType":"REGULAR_VALUE",
+ "metricName":"envoy_sr_cluster_up_rq_incr",
+ "queryMetricType":"readMetricsValues",
+ "chartType":"ChartLine",
+ "unit":"Per Minute"
+ },
+ {
+ "width":12,
+ "title":"Upstream Request Pending Active",
+ "height":"200",
+ "entityType":"ServiceRelation",
+ "metricType":"REGULAR_VALUE",
+ "metricName":"envoy_sr_cluster_up_rq_pending_active",
+ "queryMetricType":"readMetricsValues",
+ "chartType":"ChartLine"
+ },
+ {
+ "width":12,
+ "title":"LB Healthy Panic Increase",
+ "height":"200",
+ "entityType":"ServiceRelation",
+ "metricType":"REGULAR_VALUE",
+ "metricName":"envoy_sr_cluster_lb_healthy_panic_incr",
+ "queryMetricType":"readMetricsValues",
+ "chartType":"ChartLine",
+ "unit":"Per Minute"
+ },
+ {
+ "width":12,
+ "title":"Upstream Connection None Healthy Increase",
+ "height":"200",
+ "entityType":"ServiceRelation",
+ "metricType":"REGULAR_VALUE",
+ "metricName":"envoy_sr_cluster_up_cx_none_healthy_incr",
+ "queryMetricType":"readMetricsValues",
+ "chartType":"ChartLine",
+ "unit":"Per Minute"
+ }
+ ]
}
}
# Activated as the TOPOLOGY_INSTANCE type, makes this templates added into
the UI page automatically.
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java
index 1fa938c..4bacf15 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java
@@ -68,6 +68,13 @@ public class ServiceRelationClientSideMetrics extends
Metrics {
@Override
public boolean combine(Metrics metrics) {
+ ServiceRelationClientSideMetrics serviceRelationClientSideMetrics =
(ServiceRelationClientSideMetrics) metrics;
+ if (this.getComponentId() == 0 &&
serviceRelationClientSideMetrics.getComponentId() != 0) {
+ this.componentId =
serviceRelationClientSideMetrics.getComponentId();
+ }
+ if (this.getTimeBucket() > metrics.getTimeBucket()) {
+ this.setTimeBucket(metrics.getTimeBucket());
+ }
return true;
}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterEntity.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterEntity.java
index 2647bc7..d2d5958 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterEntity.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterEntity.java
@@ -18,11 +18,14 @@
package org.apache.skywalking.oap.server.core.analysis.meter;
+import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
+import lombok.Setter;
import lombok.ToString;
import org.apache.skywalking.oap.server.core.UnexpectedException;
import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.source.DetectPoint;
/**
* MeterEntity represents the entity in the meter system.
@@ -30,21 +33,16 @@ import
org.apache.skywalking.oap.server.core.analysis.IDManager;
@EqualsAndHashCode
@ToString
@Getter
+@Builder(toBuilder = true)
public class MeterEntity {
private ScopeType scopeType;
+ @Setter
private String serviceName;
private String instanceName;
private String endpointName;
-
- private MeterEntity(final ScopeType scopeType,
- final String serviceName,
- final String instanceName,
- final String endpointName) {
- this.scopeType = scopeType;
- this.serviceName = serviceName;
- this.instanceName = instanceName;
- this.endpointName = endpointName;
- }
+ private String sourceServiceName;
+ private String destServiceName;
+ private DetectPoint detectPoint;
public String id() {
switch (scopeType) {
@@ -56,6 +54,11 @@ public class MeterEntity {
IDManager.ServiceID.buildId(serviceName, true),
instanceName);
case ENDPOINT:
return
IDManager.EndpointID.buildId(IDManager.ServiceID.buildId(serviceName, true),
endpointName);
+ case SERVICE_RELATION:
+ return IDManager.ServiceID.buildRelationId(new
IDManager.ServiceID.ServiceRelationDefine(
+ sourceServiceId(),
+ destServiceId()
+ ));
default:
throw new UnexpectedException("Unexpected scope type of entity
" + this.toString());
}
@@ -65,24 +68,51 @@ public class MeterEntity {
return IDManager.ServiceID.buildId(serviceName, true);
}
+ public String sourceServiceId() {
+ return IDManager.ServiceID.buildId(sourceServiceName, true);
+ }
+
+ public String destServiceId() {
+ return IDManager.ServiceID.buildId(destServiceName, true);
+ }
+
/**
* Create a service level meter entity.
*/
public static MeterEntity newService(String serviceName) {
- return new MeterEntity(ScopeType.SERVICE, serviceName, null, null);
+ return
MeterEntity.builder().scopeType(ScopeType.SERVICE).serviceName(serviceName).build();
}
/**
* Create a service instance level meter entity.
*/
public static MeterEntity newServiceInstance(String serviceName, String
serviceInstance) {
- return new MeterEntity(ScopeType.SERVICE_INSTANCE, serviceName,
serviceInstance, null);
+ return MeterEntity.builder()
+ .scopeType(ScopeType.SERVICE_INSTANCE)
+ .serviceName(serviceName)
+ .instanceName(serviceInstance)
+ .build();
}
/**
* Create an endpoint level meter entity.
*/
public static MeterEntity newEndpoint(String serviceName, String
endpointName) {
- return new MeterEntity(ScopeType.ENDPOINT, serviceName, null,
endpointName);
+ return MeterEntity.builder()
+ .scopeType(ScopeType.ENDPOINT)
+ .serviceName(serviceName)
+ .endpointName(endpointName)
+ .build();
+ }
+
+ public static MeterEntity newServiceRelation(String sourceServiceName,
+ String destServiceName,
+ DetectPoint detectPoint) {
+ return MeterEntity.builder()
+ .scopeType(ScopeType.SERVICE_RELATION)
+ .sourceServiceName(sourceServiceName)
+ .destServiceName(destServiceName)
+ .detectPoint(detectPoint)
+ .build();
}
}
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
index 9907e56..3d0a4a2 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/ScopeType.java
@@ -24,7 +24,8 @@ import
org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
public enum ScopeType {
SERVICE(DefaultScopeDefine.SERVICE),
SERVICE_INSTANCE(DefaultScopeDefine.SERVICE_INSTANCE),
- ENDPOINT(DefaultScopeDefine.ENDPOINT);
+ ENDPOINT(DefaultScopeDefine.ENDPOINT),
+ SERVICE_RELATION(DefaultScopeDefine.SERVICE_RELATION);
@Getter
private final int scopeId;
diff --git
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/EnvoyMetricReceiverConfig.java
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/EnvoyMetricReceiverConfig.java
index 2f3d130..3db3fe0 100644
---
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/EnvoyMetricReceiverConfig.java
+++
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/EnvoyMetricReceiverConfig.java
@@ -57,7 +57,7 @@ public class EnvoyMetricReceiverConfig extends ModuleConfig {
}
public List<Rule> rules() throws ModuleStartException {
- return Rules.loadRules("envoy-metrics-rules",
Collections.singletonList("envoy"));
+ return Rules.loadRules("envoy-metrics-rules", Arrays.asList("envoy",
"envoy-svc-relation"));
}
public ServiceMetaInfoFactory serviceMetaInfoFactory() {
diff --git
a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/metrics/MetricsQuery.java
b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/metrics/MetricsQuery.java
index 73af78f..320182b 100644
---
a/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/metrics/MetricsQuery.java
+++
b/test/e2e/e2e-data/src/main/java/org/apache/skywalking/e2e/metrics/MetricsQuery.java
@@ -78,7 +78,7 @@ public class MetricsQuery extends AbstractQuery<MetricsQuery>
{
public static String INSTANCE_JVM_THREAD_RUNNABLE_STATE_THREAD_COUNT =
"instance_jvm_thread_runnable_state_thread_count";
public static String INSTANCE_JVM_CLASS_LOADED_CLASS_COUNT =
"instance_jvm_class_loaded_class_count";
public static String INSTANCE_JVM_CLASS_TOTAL_LOADED_CLASS_COUNT =
"instance_jvm_class_total_loaded_class_count";
- public static String [] ALL_INSTANCE_JVM_METRICS = {
+ public static String[] ALL_INSTANCE_JVM_METRICS = {
INSTANCE_JVM_CLASS_TOTAL_LOADED_CLASS_COUNT,
INSTANCE_JVM_CLASS_LOADED_CLASS_COUNT,
INSTANCE_JVM_THREAD_RUNNABLE_STATE_THREAD_COUNT,
@@ -88,16 +88,16 @@ public class MetricsQuery extends
AbstractQuery<MetricsQuery> {
INSTANCE_JVM_MEMORY_NOHEAP,
INSTANCE_JVM_MEMORY_HEAP_MAX,
INSTANCE_JVM_MEMORY_HEAP,
- };
+ };
- public static String [] ALL_INSTANCE_JVM_METRICS_COMPAT = {
+ public static String[] ALL_INSTANCE_JVM_METRICS_COMPAT = {
INSTANCE_JVM_THREAD_LIVE_COUNT,
INSTANCE_JVM_THREAD_DAEMON_COUNT,
INSTANCE_JVM_THREAD_PEAK_COUNT,
INSTANCE_JVM_MEMORY_NOHEAP,
INSTANCE_JVM_MEMORY_HEAP_MAX,
INSTANCE_JVM_MEMORY_HEAP,
- };
+ };
public static String SERVICE_RELATION_CLIENT_CPM =
"service_relation_client_cpm";
public static String SERVICE_RELATION_SERVER_CPM =
"service_relation_server_cpm";
@@ -110,6 +110,9 @@ public class MetricsQuery extends
AbstractQuery<MetricsQuery> {
public static String[] ALL_SERVICE_RELATION_CLIENT_METRICS = {
SERVICE_RELATION_CLIENT_CPM
};
+ public static String[] ENVOY_METRICS_SERVICE_RELATION_CLIENT_METRICS = {
+ "envoy_sr_cluster_up_cx_active"
+ };
public static String[] ALL_SERVICE_RELATION_SERVER_METRICS = {
SERVICE_RELATION_SERVER_CPM
@@ -161,11 +164,18 @@ public class MetricsQuery extends
AbstractQuery<MetricsQuery> {
"envoy_memory_allocated_max",
"envoy_memory_physical_size",
"envoy_memory_physical_size_max",
- "envoy_total_connections_used",
"envoy_worker_threads",
"envoy_worker_threads_max"
};
+ public static Map<String, List<String>> ALL_ENVOY_LABELED_METRICS =
+ ImmutableMap.<String, List<String>>builder()
+ .put(
+ "envoy_cluster_membership_healthy",
+ Arrays.asList("e2e::details")
+ )
+ .build();
+
public static String[] ALL_SO11Y_LABELED_METRICS = {
// Nothing to check for now.
};
@@ -182,10 +192,19 @@ public class MetricsQuery extends
AbstractQuery<MetricsQuery> {
};
public static Map<String, List<String>> SIMPLE_ZABBIX_METERS =
ImmutableMap.<String, List<String>>builder()
- .put("meter_agent_system_cpu_util", Arrays.asList("idle"))
- .put("meter_agent_vm_memory_size", Arrays.asList("total"))
- .put("meter_agent_vfs_fs_size", Arrays.asList("/-total"))
- .build();
+
.put(
+
"meter_agent_system_cpu_util",
+
Arrays.asList("idle")
+
)
+
.put(
+
"meter_agent_vm_memory_size",
+
Arrays.asList("total")
+
)
+
.put(
+
"meter_agent_vfs_fs_size",
+
Arrays.asList("/-total")
+
)
+
.build();
public static String[] SIMPLE_PROM_VM_METERS = {
"meter_vm_memory_used",
@@ -201,8 +220,14 @@ public class MetricsQuery extends
AbstractQuery<MetricsQuery> {
};
public static Map<String, List<String>> SIMPLE_PROM_VM_LABELED_METERS =
ImmutableMap.<String, List<String>>builder()
- .put("meter_vm_cpu_average_used", Arrays.asList("idle"))
- .put("meter_vm_filesystem_percentage", Arrays.asList("/etc/hosts"))
- .build();
+
.put(
+
"meter_vm_cpu_average_used",
+
Arrays.asList("idle")
+
)
+
.put(
+
"meter_vm_filesystem_percentage",
+
Arrays.asList("/etc/hosts")
+
)
+
.build();
}
diff --git
a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/mesh/MetricsServiceE2E.java
b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/mesh/MetricsServiceE2E.java
index 0d87e9b..f758896 100644
---
a/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/mesh/MetricsServiceE2E.java
+++
b/test/e2e/e2e-test/src/test/java/org/apache/skywalking/e2e/mesh/MetricsServiceE2E.java
@@ -21,6 +21,7 @@ package org.apache.skywalking.e2e.mesh;
import com.google.common.base.Strings;
import java.net.URL;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
@@ -28,7 +29,9 @@ import org.apache.skywalking.e2e.base.SkyWalkingTestAdapter;
import org.apache.skywalking.e2e.base.TrafficController;
import org.apache.skywalking.e2e.common.HostAndPort;
import org.apache.skywalking.e2e.metrics.AtLeastOneOfMetricsMatcher;
+import org.apache.skywalking.e2e.metrics.Metrics;
import org.apache.skywalking.e2e.metrics.MetricsValueMatcher;
+import org.apache.skywalking.e2e.metrics.ReadLabeledMetricsQuery;
import org.apache.skywalking.e2e.metrics.ReadMetrics;
import org.apache.skywalking.e2e.metrics.ReadMetricsQuery;
import org.apache.skywalking.e2e.retryable.RetryableTest;
@@ -39,10 +42,17 @@ import org.apache.skywalking.e2e.service.instance.Instance;
import org.apache.skywalking.e2e.service.instance.Instances;
import org.apache.skywalking.e2e.service.instance.InstancesMatcher;
import org.apache.skywalking.e2e.service.instance.InstancesQuery;
+import org.apache.skywalking.e2e.topo.Call;
+import org.apache.skywalking.e2e.topo.TopoMatcher;
+import org.apache.skywalking.e2e.topo.TopoQuery;
+import org.apache.skywalking.e2e.topo.Topology;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.TestInstance;
+import static org.apache.skywalking.e2e.metrics.MetricsMatcher.verifyMetrics;
+import static
org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENVOY_LABELED_METRICS;
import static
org.apache.skywalking.e2e.metrics.MetricsQuery.ALL_ENVOY_LINER_METRICS;
+import static
org.apache.skywalking.e2e.metrics.MetricsQuery.ENVOY_METRICS_SERVICE_RELATION_CLIENT_METRICS;
import static org.apache.skywalking.e2e.utils.Times.now;
import static org.apache.skywalking.e2e.utils.Yamls.exists;
import static org.apache.skywalking.e2e.utils.Yamls.load;
@@ -50,9 +60,11 @@ import static org.apache.skywalking.e2e.utils.Yamls.load;
@Slf4j
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MetricsServiceE2E extends SkyWalkingTestAdapter {
- private final String swWebappHost =
Optional.ofNullable(Strings.emptyToNull(System.getenv("WEBAPP_HOST"))).orElse("127.0.0.1");
+ private final String swWebappHost =
Optional.ofNullable(Strings.emptyToNull(System.getenv("WEBAPP_HOST")))
+ .orElse("127.0.0.1");
- private final String swWebappPort =
Optional.ofNullable(Strings.emptyToNull(System.getenv("WEBAPP_PORT"))).orElse("12800");
+ private final String swWebappPort =
Optional.ofNullable(Strings.emptyToNull(System.getenv("WEBAPP_PORT")))
+ .orElse("12800");
protected HostAndPort swWebappHostPort = HostAndPort.builder()
.host(swWebappHost)
@@ -65,8 +77,10 @@ public class MetricsServiceE2E extends SkyWalkingTestAdapter
{
queryClient(swWebappHostPort);
- String gatewayHost =
Strings.isNullOrEmpty(System.getenv("GATEWAY_HOST")) ? "127.0.0.1" :
System.getenv("GATEWAY_HOST");
- String gatewayPort =
Strings.isNullOrEmpty(System.getenv("GATEWAY_PORT")) ? "80" :
System.getenv("GATEWAY_PORT");
+ String gatewayHost =
Strings.isNullOrEmpty(System.getenv("GATEWAY_HOST")) ? "127.0.0.1" :
System.getenv(
+ "GATEWAY_HOST");
+ String gatewayPort =
Strings.isNullOrEmpty(System.getenv("GATEWAY_PORT")) ? "80" : System.getenv(
+ "GATEWAY_PORT");
HostAndPort serviceHostPort = HostAndPort.builder()
.host(gatewayHost)
@@ -124,6 +138,59 @@ public class MetricsServiceE2E extends
SkyWalkingTestAdapter {
instanceRespTimeMatcher.setValue(greaterThanZero);
instanceRespTimeMatcher.verify(instanceMetrics.getValues());
}
+
+ for (Map.Entry<String, List<String>> entry :
ALL_ENVOY_LABELED_METRICS.entrySet()) {
+ String metricsName = entry.getKey();
+ List<String> labels = entry.getValue();
+ LOGGER.info("verifying envoy labeledMetrics: {}",
metricsName);
+ List<ReadMetrics> labeledMetrics =
graphql.readLabeledMetrics(
+ new ReadLabeledMetricsQuery().stepByMinute()
+ .metricsName(metricsName)
+
.serviceName(service.getLabel())
+ .scope("ServiceInstance")
+
.instanceName(instance.getLabel())
+ .labels(labels)
+ );
+ LOGGER.info("envoy labeledMetrics: {}", labeledMetrics);
+
+ Metrics allValues = new Metrics();
+ for (ReadMetrics readMetrics : labeledMetrics) {
+
allValues.getValues().addAll(readMetrics.getValues().getValues());
+ }
+ final AtLeastOneOfMetricsMatcher instanceRespTimeMatcher =
new AtLeastOneOfMetricsMatcher();
+ final MetricsValueMatcher greaterThanZero = new
MetricsValueMatcher();
+ greaterThanZero.setValue("gt 0");
+ instanceRespTimeMatcher.setValue(greaterThanZero);
+ instanceRespTimeMatcher.verify(allValues);
+ }
+ }
+ }
+ }
+
+ @RetryableTest
+ void topology() throws Exception {
+ LOGGER.info("topology starts {} {}", graphql, startTime);
+
+ final Topology topology = graphql.topo(new
TopoQuery().stepByMinute().start(startTime.minusDays(1)).end(now()));
+
+ LOGGER.info("topology: {}", topology);
+
+
load("expected/metricsservice/topo.yml").as(TopoMatcher.class).verify(topology);
+
+ verifyServiceRelationMetrics(topology.getCalls());
+ }
+
+ private void verifyServiceRelationMetrics(final List<Call> calls) throws
Exception {
+ verifyRelationMetrics(calls,
ENVOY_METRICS_SERVICE_RELATION_CLIENT_METRICS);
+ }
+
+ private void verifyRelationMetrics(final List<Call> calls,
+ final String[] relationClientMetrics)
throws Exception {
+ for (Call call : calls) {
+ for (String detectPoint : call.getDetectPoints()) {
+ for (String metricName : relationClientMetrics) {
+ verifyMetrics(graphql, metricName, call.getId(),
startTime);
+ }
}
}
}
diff --git
a/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
b/test/e2e/e2e-test/src/test/resources/expected/metricsservice/topo.yml
similarity index 62%
copy from
oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
copy to test/e2e/e2e-test/src/test/resources/expected/metricsservice/topo.yml
index acb4d43..beb5c95 100644
---
a/oap-server/server-bootstrap/src/main/resources/metadata-service-mapping.yaml
+++ b/test/e2e/e2e-test/src/test/resources/expected/metricsservice/topo.yml
@@ -13,5 +13,27 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-serviceName:
${LABELS."service.istio.io/canonical-revision"}.${LABELS."service.istio.io/canonical-name",LABELS."app.kubernetes.io/name",LABELS.app}.${NAMESPACE}
-serviceInstanceName: ${NAME}
+nodes:
+ - id: not null
+ name: e2e::reviews
+ type: null
+ isReal: true
+ - id: not null
+ name: e2e::productpage
+ isReal: true
+ - id: not null
+ name: e2e::details
+ type: null
+ isReal: true
+
+calls:
+ - id: not null
+ source: ZTJlOjpwcm9kdWN0cGFnZQ==.1
+ target: ZTJlOjpyZXZpZXdz.1
+ detectPoints:
+ - CLIENT
+ - id: not null
+ source: ZTJlOjpwcm9kdWN0cGFnZQ==.1
+ target: ZTJlOjpkZXRhaWxz.1
+ detectPoints:
+ - CLIENT