This is an automated email from the ASF dual-hosted git repository.
wankai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 84e45c5677 Envoy metrics service receiver: support adapter listener
metrics. (#13692)
84e45c5677 is described below
commit 84e45c5677a75cd0efcd8e60e254da057f828c64
Author: Wan Kai <[email protected]>
AuthorDate: Thu Feb 5 15:17:13 2026 +0800
Envoy metrics service receiver: support adapter listener metrics. (#13692)
---
docs/en/changes/changes.md | 1 +
.../receiver/envoy/EnvoyMetricReceiverConfig.java | 3 +
.../receiver/envoy/MetricServiceGRPCHandler.java | 2 +-
.../metrics/adapters/ListenerMetricsAdapter.java | 36 +++++++++
.../adapters/ProtoMetricFamily2MetricsAdapter.java | 5 ++
.../envoy/ClusterManagerMetricsAdapterTest.java | 5 +-
.../receiver/envoy/ListenerMetricsAdapterTest.java | 89 ++++++++++++++++++++++
test/e2e-v2/cases/virtual-mq/e2e.yaml | 2 +-
8 files changed, 140 insertions(+), 3 deletions(-)
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 3456dcfc65..f6c0bd8134 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -29,6 +29,7 @@
* `BanyanDB Client`: Property query support `Order By`.
* MQE: trim the label values condition for the labeled metrics query to
enhance the readability.
* PromQL service: fix time parse issue when using RFC3339 time format for
querying.
+* Envoy metrics service receiver: support adapter listener metrics.
#### UI
* Fix the missing icon in new native trace view.
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 5ae7cee716..6572c42faa 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
@@ -33,6 +33,7 @@ import
org.apache.skywalking.oap.meter.analyzer.prometheus.rule.Rules;
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
import
org.apache.skywalking.oap.server.receiver.envoy.metrics.adapters.ClusterManagerMetricsAdapter;
+import
org.apache.skywalking.oap.server.receiver.envoy.metrics.adapters.ListenerMetricsAdapter;
public class EnvoyMetricReceiverConfig extends ModuleConfig {
@Getter
@@ -67,6 +68,8 @@ public class EnvoyMetricReceiverConfig extends ModuleConfig {
private final ServiceMetaInfoFactory serviceMetaInfoFactory = new
ServiceMetaInfoFactoryImpl();
@Getter
private final ClusterManagerMetricsAdapter clusterManagerMetricsAdapter =
new ClusterManagerMetricsAdapter(this);
+ @Getter
+ private final ListenerMetricsAdapter listenerMetricsAdapter = new
ListenerMetricsAdapter();
public List<String> getAlsHTTPAnalysis() {
if (Strings.isNullOrEmpty(alsHTTPAnalysis)) {
diff --git
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/MetricServiceGRPCHandler.java
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/MetricServiceGRPCHandler.java
index bb40f18f3a..921edfee10 100644
---
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/MetricServiceGRPCHandler.java
+++
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/MetricServiceGRPCHandler.java
@@ -112,7 +112,7 @@ public class MetricServiceGRPCHandler extends
MetricsServiceGrpc.MetricsServiceI
counter.inc();
try (final HistogramMetrics.Timer ignored =
histogram.createTimer()) {
final ProtoMetricFamily2MetricsAdapter adapter =
new ProtoMetricFamily2MetricsAdapter(
- metricFamily,
config.getClusterManagerMetricsAdapter());
+ metricFamily,
config.getClusterManagerMetricsAdapter(), config.getListenerMetricsAdapter());
adapter.adapt().forEach(it -> {
it.getLabels().putIfAbsent("app",
service.getServiceName());
it.getLabels().putIfAbsent("instance",
service.getServiceInstanceName());
diff --git
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/metrics/adapters/ListenerMetricsAdapter.java
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/metrics/adapters/ListenerMetricsAdapter.java
new file mode 100644
index 0000000000..6307bf0a77
--- /dev/null
+++
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/metrics/adapters/ListenerMetricsAdapter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.receiver.envoy.metrics.adapters;
+
+import io.prometheus.client.Metrics;
+import java.util.Map;
+
+public class ListenerMetricsAdapter {
+
+ public String adaptMetricsName(final Metrics.MetricFamily metricFamily) {
+ return "envoy_listener_metrics";
+ }
+
+ public Map<String, String> adaptLabels(final Metrics.MetricFamily
metricFamily, final Map<String, String> labels) {
+ String metricsName = metricFamily.getName();
+ labels.putIfAbsent("metrics_name", metricsName);
+
+ return labels;
+ }
+}
diff --git
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/metrics/adapters/ProtoMetricFamily2MetricsAdapter.java
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/metrics/adapters/ProtoMetricFamily2MetricsAdapter.java
index 1be1966dff..d963641154 100644
---
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/metrics/adapters/ProtoMetricFamily2MetricsAdapter.java
+++
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/envoy/metrics/adapters/ProtoMetricFamily2MetricsAdapter.java
@@ -35,6 +35,7 @@ import static java.util.stream.Collectors.toMap;
public class ProtoMetricFamily2MetricsAdapter {
protected final Metrics.MetricFamily metricFamily;
private final ClusterManagerMetricsAdapter clusterManagerMetricsAdapter;
+ private final ListenerMetricsAdapter listenerMetricsAdapter;
public Stream<Metric> adapt() {
switch (metricFamily.getType()) {
@@ -75,6 +76,8 @@ public class ProtoMetricFamily2MetricsAdapter {
public String adaptMetricsName(final Metrics.Metric metric) {
if (metricFamily.getName().startsWith("cluster.")) {
return clusterManagerMetricsAdapter.adaptMetricsName(metricFamily);
+ } else if (metricFamily.getName().startsWith("listener.")) {
+ return listenerMetricsAdapter.adaptMetricsName(metricFamily);
}
return metricFamily.getName();
@@ -90,6 +93,8 @@ public class ProtoMetricFamily2MetricsAdapter {
.collect(toMap(Metrics.LabelPair::getName, Metrics.LabelPair::getValue));
if (metricFamily.getName().startsWith("cluster.")) {
return clusterManagerMetricsAdapter.adaptLabels(metricFamily,
labels);
+ } else if (metricFamily.getName().startsWith("listener.")) {
+ return listenerMetricsAdapter.adaptLabels(metricFamily, labels);
}
return labels;
diff --git
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/ClusterManagerMetricsAdapterTest.java
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/ClusterManagerMetricsAdapterTest.java
index 067721a023..0e0aa3439a 100644
---
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/ClusterManagerMetricsAdapterTest.java
+++
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/ClusterManagerMetricsAdapterTest.java
@@ -37,6 +37,7 @@ public class ClusterManagerMetricsAdapterTest {
private Metrics.MetricFamily cbNameOutboundFQDN =
Metrics.MetricFamily.newBuilder().setName("cluster.outbound|9080||reviews.default.svc.cluster.local.circuit_breakers.default.cx_pool_open").build();
private Metrics.MetricFamily cbNameOutboundFQDNSubset =
Metrics.MetricFamily.newBuilder().setName("cluster.outbound|9080|v1|reviews.default.svc.cluster.local.circuit_breakers.default.cx_pool_open").build();
private Metrics.MetricFamily cbNameInboundFQDN =
Metrics.MetricFamily.newBuilder().setName("cluster.inbound|9080||.upstream_cx_total").build();
+ private Metrics.MetricFamily ca =
Metrics.MetricFamily.newBuilder().setName("cluster.outbound|9080|v2-mysql|ratings.default.svc.cluster.local;.ssl.certificate.ROOTCA.expiration_unix_time_seconds").build();
@SneakyThrows
@BeforeEach
@@ -68,6 +69,8 @@ public class ClusterManagerMetricsAdapterTest {
assertThat(
clusterManagerMetricsAdapter.adaptLabels(cbNameInboundFQDN,
new HashMap<>()).toString()
).isEqualTo("{cluster_name=-.inbound:9080.-, metrics_name=" +
cbNameInboundFQDN.getName() + "}");
-
+ assertThat(
+ clusterManagerMetricsAdapter.adaptLabels(ca, new
HashMap<>()).toString()
+ ).isEqualTo("{cluster_name=v2-mysql.ratings.default, metrics_name=" +
ca.getName() + "}");
}
}
diff --git
a/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/ListenerMetricsAdapterTest.java
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/ListenerMetricsAdapterTest.java
new file mode 100644
index 0000000000..efbb7e6ab8
--- /dev/null
+++
b/oap-server/server-receiver-plugin/envoy-metrics-receiver-plugin/src/test/java/org/apache/skywalking/oap/server/receiver/envoy/ListenerMetricsAdapterTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.receiver.envoy;
+
+import io.prometheus.client.Metrics;
+import
org.apache.skywalking.oap.server.receiver.envoy.metrics.adapters.ListenerMetricsAdapter;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+public class ListenerMetricsAdapterTest {
+
+ private ListenerMetricsAdapter listenerMetricsAdapter;
+ private final Metrics.MetricFamily downstream =
Metrics.MetricFamily.newBuilder()
+
.setName(
+
"listener.0.0.0.0_15090.downstream_cx_total")
+
.build();
+ private final Metrics.MetricFamily http = Metrics.MetricFamily.newBuilder()
+ .setName(
+
"listener.0.0.0.0_15090.http.inbound_0.0.0.0_15090.downstream_rq_2xx")
+ .build();
+ private final Metrics.MetricFamily adminListener =
Metrics.MetricFamily.newBuilder()
+
.setName(
+
"listener.admin.downstream_cx_destroy")
+
.build();
+ private final Metrics.MetricFamily virtualListener =
Metrics.MetricFamily.newBuilder()
+
.setName(
+
"listener.0.0.0.0_15001.downstream_cx_active")
+
.build();
+ private final Metrics.MetricFamily ca = Metrics.MetricFamily.newBuilder()
+ .setName(
+
"listener.0.0.0.0_15006.ssl.certificate.ROOTCA.expiration_unix_time_seconds")
+ .build();
+
+ @BeforeEach
+ public void setUp() {
+ listenerMetricsAdapter = new ListenerMetricsAdapter();
+ }
+
+ @Test
+ public void testAdaptMetricsName() {
+
assertThat(listenerMetricsAdapter.adaptMetricsName(downstream)).isEqualTo("envoy_listener_metrics");
+
assertThat(listenerMetricsAdapter.adaptMetricsName(http)).isEqualTo("envoy_listener_metrics");
+
assertThat(listenerMetricsAdapter.adaptMetricsName(adminListener)).isEqualTo("envoy_listener_metrics");
+
assertThat(listenerMetricsAdapter.adaptMetricsName(virtualListener)).isEqualTo("envoy_listener_metrics");
+
assertThat(listenerMetricsAdapter.adaptMetricsName(ca)).isEqualTo("envoy_listener_metrics");
+ }
+
+ @Test
+ public void testAdaptLabels() {
+ assertThat(
+ listenerMetricsAdapter.adaptLabels(downstream, new
HashMap<>()).toString()
+ ).isEqualTo("{metrics_name=" + downstream.getName() + "}");
+
+ assertThat(
+ listenerMetricsAdapter.adaptLabels(http, new
HashMap<>()).toString()
+ ).isEqualTo("{metrics_name=" + http.getName() + "}");
+
+ assertThat(
+ listenerMetricsAdapter.adaptLabels(adminListener, new
HashMap<>()).toString()
+ ).isEqualTo("{metrics_name=" + adminListener.getName() + "}");
+
+ assertThat(
+ listenerMetricsAdapter.adaptLabels(virtualListener, new
HashMap<>()).toString()
+ ).isEqualTo("{metrics_name=" + virtualListener.getName() + "}");
+ assertThat(
+ listenerMetricsAdapter.adaptLabels(ca, new HashMap<>()).toString()
+ ).isEqualTo("{metrics_name=" + ca.getName() + "}");
+ }
+}
diff --git a/test/e2e-v2/cases/virtual-mq/e2e.yaml
b/test/e2e-v2/cases/virtual-mq/e2e.yaml
index 7256e86f57..23cf780cc3 100644
--- a/test/e2e-v2/cases/virtual-mq/e2e.yaml
+++ b/test/e2e-v2/cases/virtual-mq/e2e.yaml
@@ -38,7 +38,7 @@ trigger:
verify:
retry:
count: 20
- interval: 3s
+ interval: 10s
cases:
- includes:
- mq-cases.yaml