This is an automated email from the ASF dual-hosted git repository.

zrlw pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-samples.git


The following commit(s) were added to refs/heads/master by this push:
     new 1952d572e apply full metric-kind mapping for prometheus metrics IT 
assertions (#1293)
1952d572e is described below

commit 1952d572e5d8cb542403bce55a979917490a3375
Author: SavitarC <[email protected]>
AuthorDate: Thu Apr 23 08:33:56 2026 +0800

    apply full metric-kind mapping for prometheus metrics IT assertions (#1293)
---
 .../prometheus/consumer/ConsumerMetricsIT.java     | 145 +++++++++-------
 .../prometheus/util/PrometheusMetricAssert.java    | 151 +++++++++++++++++
 .../prometheus/provider/ProviderMetricsIT.java     | 185 ++++++++++++---------
 3 files changed, 335 insertions(+), 146 deletions(-)

diff --git 
a/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-consumer/src/test/java/org/apache/dubbo/samples/metrics/prometheus/consumer/ConsumerMetricsIT.java
 
b/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-consumer/src/test/java/org/apache/dubbo/samples/metrics/prometheus/consumer/ConsumerMetricsIT.java
index ec3f8637c..6892e1291 100644
--- 
a/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-consumer/src/test/java/org/apache/dubbo/samples/metrics/prometheus/consumer/ConsumerMetricsIT.java
+++ 
b/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-consumer/src/test/java/org/apache/dubbo/samples/metrics/prometheus/consumer/ConsumerMetricsIT.java
@@ -17,6 +17,7 @@
 
 package org.apache.dubbo.samples.metrics.prometheus.consumer;
 
+import org.apache.dubbo.samples.metrics.prometheus.util.PrometheusMetricAssert;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -40,89 +41,96 @@ import java.util.stream.Collectors;
 public class ConsumerMetricsIT {
     private static final Logger logger = 
LoggerFactory.getLogger(ConsumerMetricsIT.class);
 
-
     private final String port = "20889";
 
-    private final List<String> metricKeys = new ArrayList();
+    private final List<MetricExpectation> metricExpectations = new 
ArrayList<>();
 
     @Before
     public void setUp() {
-        add("dubbo_application_info_total");
+        addCounter("dubbo.application.info.total");
 
         //config
-        add("dubbo_configcenter_total");
-
-        add("dubbo_provider_rt_milliseconds_p99");
-        add("dubbo_provider_requests_total_aggregate");
-        add("dubbo_provider_rt_milliseconds_p90");
-        add("dubbo_provider_rt_max_milliseconds_aggregate");
-        add("dubbo_provider_requests_succeed_total");
-        add("dubbo_provider_requests_business_failed_aggregate");
-        add("dubbo_provider_requests_business_failed_total");
-        add("dubbo_provider_requests_total");
-        
add("dubbo_provider_requests_failed_service_unavailable_total_aggregate");
-        add("dubbo_provider_requests_limit_aggregate");
-        add("dubbo_provider_qps_total");
-        add("dubbo_provider_rt_milliseconds_p50");
-        add("dubbo_provider_requests_processing_total");
-        add("dubbo_provider_requests_failed_total");
-        add("dubbo_provider_requests_succeed_aggregate");
-        add("dubbo_provider_rt_milliseconds_p95");
-        add("dubbo_provider_requests_failed_aggregate");
-        add("dubbo_provider_rt_avg_milliseconds_aggregate");
-        add("dubbo_provider_requests_failed_total_aggregate");
-        add("dubbo_provider_requests_failed_network_total_aggregate");
-        add("dubbo_provider_rt_min_milliseconds_aggregate");
-        add("dubbo_provider_requests_failed_codec_total_aggregate");
-        add("dubbo_provider_requests_timeout_failed_aggregate");
+        addGauge("dubbo.configcenter.total");
+
+        addGauge("dubbo.provider.rt.milliseconds.p99");
+        addGauge("dubbo.provider.requests.total.aggregate");
+        addGauge("dubbo.provider.rt.milliseconds.p90");
+        addGauge("dubbo.provider.rt.max.milliseconds.aggregate");
+        addCounter("dubbo.provider.requests.succeed.total");
+        addGauge("dubbo.provider.requests.business.failed.aggregate");
+        addCounter("dubbo.provider.requests.business.failed.total");
+        addCounter("dubbo.provider.requests.total");
+        
addGauge("dubbo.provider.requests.failed.service.unavailable.total.aggregate");
+        addGauge("dubbo.provider.requests.limit.aggregate");
+        addGauge("dubbo.provider.qps.total");
+        addGauge("dubbo.provider.rt.milliseconds.p50");
+        addGauge("dubbo.provider.requests.processing.total");
+        addCounter("dubbo.provider.requests.failed.total");
+        addGauge("dubbo.provider.requests.succeed.aggregate");
+        addGauge("dubbo.provider.rt.milliseconds.p95");
+        addGauge("dubbo.provider.requests.failed.aggregate");
+        addGauge("dubbo.provider.rt.avg.milliseconds.aggregate");
+        addGauge("dubbo.provider.requests.failed.total.aggregate");
+        addGauge("dubbo.provider.requests.failed.network.total.aggregate");
+        addGauge("dubbo.provider.rt.min.milliseconds.aggregate");
+        addGauge("dubbo.provider.requests.failed.codec.total.aggregate");
+        addGauge("dubbo.provider.requests.timeout.failed.aggregate");
 
         //consumer
-        add("dubbo_consumer_requests_failed_service_unavailable_total");
+        addCounter("dubbo.consumer.requests.failed.service.unavailable.total");
 
         //register
-        add("dubbo_registry_subscribe_num_total");
-        add("dubbo_registry_register_requests_succeed_total");
-        add("dubbo_register_rt_milliseconds_last");
-        add("dubbo_registry_register_requests_total");
-        add("dubbo_register_rt_milliseconds_avg");
-        add("dubbo_registry_subscribe_num_succeed_total");
-        add("dubbo_register_rt_milliseconds_max");
-        add("dubbo_register_rt_milliseconds_min");
-        add("dubbo_register_rt_milliseconds_sum");
-        add("dubbo_registry_notify_requests_total");
-        add("dubbo_registry_register_requests_failed_total");
-        add("dubbo_registry_subscribe_num_failed_total");
-        add("dubbo_register_rt_milliseconds_max");
-        add("dubbo_registry_register_requests_succeed_total");
+        addGauge("dubbo.registry.subscribe.num.total");
+        addGauge("dubbo.registry.register.requests.succeed.total");
+        addGauge("dubbo.register.rt.milliseconds.last");
+        addGauge("dubbo.registry.register.requests.total");
+        addGauge("dubbo.register.rt.milliseconds.avg");
+        addGauge("dubbo.registry.subscribe.num.succeed.total");
+        addGauge("dubbo.register.rt.milliseconds.max");
+        addGauge("dubbo.register.rt.milliseconds.min");
+        addGauge("dubbo.register.rt.milliseconds.sum");
+        addGauge("dubbo.registry.notify.requests.total");
+        addGauge("dubbo.registry.register.requests.failed.total");
+        addGauge("dubbo.registry.subscribe.num.failed.total");
+        addGauge("dubbo.register.rt.milliseconds.max");
+        addGauge("dubbo.registry.register.requests.succeed.total");
 
         //metadata
-        add("dubbo_metadata_subscribe_num_failed_total");
-        add("dubbo_metadata_push_num_failed_total");
-        add("dubbo_metadata_subscribe_num_total");
-        add("dubbo_metadata_subscribe_num_succeed_total");
-        add("dubbo_metadata_push_num_succeed_total");
-        add("dubbo_metadata_push_num_total");
+        addGauge("dubbo.metadata.subscribe.num.failed.total");
+        addGauge("dubbo.metadata.push.num.failed.total");
+        addGauge("dubbo.metadata.subscribe.num.total");
+        addGauge("dubbo.metadata.subscribe.num.succeed.total");
+        addGauge("dubbo.metadata.push.num.succeed.total");
+        addGauge("dubbo.metadata.push.num.total");
 
         //thread
-        add("dubbo_thread_pool_thread_count");
-        add("dubbo_thread_pool_largest_size");
-        add("dubbo_thread_pool_active_size");
-        add("dubbo_thread_pool_queue_size");
-        add("dubbo_thread_pool_core_size");
-        add("dubbo_thread_pool_max_size");
+        addGauge("dubbo.thread.pool.thread.count");
+        addGauge("dubbo.thread.pool.largest.size");
+        addGauge("dubbo.thread.pool.active.size");
+        addGauge("dubbo.thread.pool.queue.size");
+        addGauge("dubbo.thread.pool.core.size");
+        addGauge("dubbo.thread.pool.max.size");
+    }
+
+    // Use explicit kind only when it changes cross-registry compatible names.
+    // Example: `dubbo.application.info.total` resolves to 
`dubbo_application_total` on new clients.
+    private void addCounter(String rawName) {
+        metricExpectations.add(new MetricExpectation(rawName, 
PrometheusMetricAssert.MetricKind.COUNTER));
     }
 
-    private void add(String dubboStoreProviderInterfaceRtMillisecondsMin) {
-        metricKeys.add(dubboStoreProviderInterfaceRtMillisecondsMin);
+    // Example: `...qps.total` is exposed without `_total` on new clients when 
treated as a gauge.
+    private void addGauge(String rawName) {
+        metricExpectations.add(new MetricExpectation(rawName, 
PrometheusMetricAssert.MetricKind.GAUGE));
     }
 
+
     @Test
     public void test() throws Exception {
         new EmbeddedZooKeeper(2181, false).start();
 
         ClassPathXmlApplicationContext context = new 
ClassPathXmlApplicationContext("dubbo-demo-consumer.xml");
 
-        List<String> notExistedList = new ArrayList<>();
+        List<MetricExpectation> notExistedList = new ArrayList<>();
         HttpGet request = new HttpGet("http://localhost:"; + port + "/metrics");
         try (CloseableHttpClient client = HttpClients.createDefault()) {
             // retry 3 times as all metrics data are not collected immediately.
@@ -132,9 +140,11 @@ public class ConsumerMetricsIT {
                 InputStream inputStream = response.getEntity().getContent();
                 String text = new BufferedReader(new 
InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
                         .collect(Collectors.joining("\n"));
-                for (String metricKey : metricKeys) {
-                    if (!text.contains(metricKey)) {
-                        notExistedList.add(metricKey);
+                for (MetricExpectation expectation : metricExpectations) {
+                    try {
+                        PrometheusMetricAssert.assertDubboMetricExposed(text, 
expectation.rawName, expectation.kind);
+                    } catch (AssertionError ignored) {
+                        notExistedList.add(expectation);
                     }
                 }
                 if (notExistedList.isEmpty()) {
@@ -146,10 +156,19 @@ public class ConsumerMetricsIT {
             Assert.fail(e.getMessage());
         }
         context.stop();
-        for (String metricKey : notExistedList) {
-            logger.error("metric key:{} doesn't exist", metricKey);
+        for (MetricExpectation metric : notExistedList) {
+            logger.error("metric rawName:{} with kind:{} doesn't exist", 
metric.rawName, metric.kind);
         }
         Assert.assertTrue(notExistedList.isEmpty());
     }
 
+    private static final class MetricExpectation {
+        private final String rawName;
+        private final PrometheusMetricAssert.MetricKind kind;
+
+        private MetricExpectation(String rawName, 
PrometheusMetricAssert.MetricKind kind) {
+            this.rawName = rawName;
+            this.kind = kind;
+        }
+    }
 }
diff --git 
a/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-interface/src/main/java/org/apache/dubbo/samples/metrics/prometheus/util/PrometheusMetricAssert.java
 
b/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-interface/src/main/java/org/apache/dubbo/samples/metrics/prometheus/util/PrometheusMetricAssert.java
new file mode 100644
index 000000000..019edc181
--- /dev/null
+++ 
b/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-interface/src/main/java/org/apache/dubbo/samples/metrics/prometheus/util/PrometheusMetricAssert.java
@@ -0,0 +1,151 @@
+/*
+ * 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.dubbo.samples.metrics.prometheus.util;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+public final class PrometheusMetricAssert {
+
+    private static final String[] RESERVED_SUFFIXES = {
+            "_total", "_created", "_bucket", "_info",
+            ".total", ".created", ".bucket", ".info"
+    };
+
+    private PrometheusMetricAssert() {
+    }
+
+    public enum MetricKind {
+        COUNTER,
+        GAUGE,
+        INFO,
+        HISTOGRAM,
+        SUMMARY,
+        UNKNOWN
+    }
+
+    public static void assertDubboMetricExposed(String scrapeText, String 
dubboRawName, MetricKind kind) {
+        Set<String> compatibleNames = resolveCompatibleNames(dubboRawName, 
kind);
+        boolean matched = compatibleNames.stream().anyMatch(name -> 
containsMetricLine(scrapeText, name));
+        if (!matched) {
+            throw new AssertionError("Expected dubbo metric to be exposed. 
rawName=" + dubboRawName
+                    + ", kind=" + kind
+                    + ", compatibleNames=" + compatibleNames);
+        }
+    }
+
+    public static Set<String> resolveCompatibleNames(String dubboRawName, 
MetricKind kind) {
+        Set<String> names = new LinkedHashSet<>();
+        names.add(legacyPrometheusName(dubboRawName, kind));
+        names.add(newPrometheusName(dubboRawName, kind));
+        return names;
+    }
+
+    private static boolean containsMetricLine(String scrapeText, String 
metricName) {
+        Pattern pattern = Pattern.compile("(?m)^" + Pattern.quote(metricName) 
+ "(\\{|\\s).*");
+        return pattern.matcher(scrapeText).find();
+    }
+
+    private static String legacyPrometheusName(String rawName, MetricKind 
kind) {
+        String conventionName = snakeCase(rawName);
+        if (kind == MetricKind.COUNTER && !conventionName.endsWith("_total")) {
+            conventionName += "_total";
+        }
+
+        String sanitized = conventionName.replaceAll("[^a-zA-Z0-9_:]", "_");
+        if (sanitized.isEmpty()) {
+            return "m_";
+        }
+        if (!Character.isLetter(sanitized.charAt(0))) {
+            return "m_" + sanitized;
+        }
+        return sanitized;
+    }
+
+    private static String snakeCase(String rawName) {
+        StringBuilder result = new StringBuilder();
+        char[] chars = rawName.toCharArray();
+        for (int i = 0; i < chars.length; i++) {
+            char current = chars[i];
+            if (Character.isUpperCase(current)) {
+                if (i > 0 && Character.isLowerCase(chars[i - 1])) {
+                    result.append('_');
+                }
+                result.append(Character.toLowerCase(current));
+            } else if (Character.isLetterOrDigit(current) || current == '_') {
+                result.append(current);
+            } else {
+                result.append('_');
+            }
+        }
+        return result.toString();
+    }
+
+    private static String newPrometheusName(String rawName, MetricKind kind) {
+        String baseName = stripReservedSuffixesRepeatedly(rawName);
+        String prometheusName = sanitizePrometheusName(baseName.replace('.', 
'_'));
+
+        switch (kind) {
+            case COUNTER:
+                return appendSuffixIfAbsent(prometheusName, "_total");
+            case INFO:
+                return appendSuffixIfAbsent(prometheusName, "_info");
+            case GAUGE:
+            case UNKNOWN:
+            case HISTOGRAM:
+            case SUMMARY:
+            default:
+                return prometheusName;
+        }
+    }
+
+    private static String appendSuffixIfAbsent(String metricName, String 
suffix) {
+        if (metricName.endsWith(suffix)) {
+            return metricName;
+        }
+        return metricName + suffix;
+    }
+
+    private static String stripReservedSuffixesRepeatedly(String rawName) {
+        String value = rawName;
+        boolean stripped;
+        do {
+            stripped = false;
+            for (String suffix : RESERVED_SUFFIXES) {
+                if (value.endsWith(suffix)) {
+                    value = value.substring(0, value.length() - 
suffix.length());
+                    stripped = true;
+                    break;
+                }
+            }
+        } while (stripped);
+        return value;
+    }
+
+    private static String sanitizePrometheusName(String value) {
+        String sanitized = value.replaceAll("[^a-zA-Z0-9_:]", "_");
+        if (sanitized.isEmpty()) {
+            return "m_";
+        }
+        if (!Character.isLetter(sanitized.charAt(0))) {
+            return "m_" + sanitized;
+        }
+        return sanitized;
+    }
+}
diff --git 
a/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-provider/src/test/java/org/apache/dubbo/samples/metrics/prometheus/provider/ProviderMetricsIT.java
 
b/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-provider/src/test/java/org/apache/dubbo/samples/metrics/prometheus/provider/ProviderMetricsIT.java
index 6ce19833a..2086eb61b 100644
--- 
a/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-provider/src/test/java/org/apache/dubbo/samples/metrics/prometheus/provider/ProviderMetricsIT.java
+++ 
b/4-governance/dubbo-samples-metrics-prometheus/dubbo-samples-metrics-prometheus-provider/src/test/java/org/apache/dubbo/samples/metrics/prometheus/provider/ProviderMetricsIT.java
@@ -17,6 +17,7 @@
 
 package org.apache.dubbo.samples.metrics.prometheus.provider;
 
+import org.apache.dubbo.samples.metrics.prometheus.util.PrometheusMetricAssert;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -42,130 +43,148 @@ public class ProviderMetricsIT {
 
     private final String port = "20888";
 
-    private final List<String> metricKeys = new ArrayList();
+    private final List<MetricExpectation> metricExpectations = new 
ArrayList<>();
 
     @Before
     public void setUp() {
         //application
-        add("dubbo_application_info_total");
+        addCounter("dubbo.application.info.total");
 
         //provider
-        add("dubbo_provider_requests_succeed_total");
-        add("dubbo_provider_rt_milliseconds_p99");
-        add("dubbo_provider_requests_failed_codec_total_aggregate");
-        add("dubbo_provider_requests_business_failed_aggregate");
-        add("dubbo_provider_requests_failed_aggregate");
-        add("dubbo_provider_requests_timeout_failed_aggregate");
-        add("dubbo_provider_requests_limit_aggregate");
-        
add("dubbo_provider_requests_failed_service_unavailable_total_aggregate");
-        add("dubbo_provider_qps_total");
-        add("dubbo_provider_rt_min_milliseconds_aggregate");
-        add("dubbo_provider_rt_max_milliseconds_aggregate");
-        add("dubbo_provider_rt_milliseconds_p90");
-        add("dubbo_provider_rt_milliseconds_p50");
-        add("dubbo_provider_rt_milliseconds_p95");
-        add("dubbo_provider_requests_total");
-        add("dubbo_provider_rt_avg_milliseconds_aggregate");
-        add("dubbo_provider_requests_total_aggregate");
-        add("dubbo_provider_requests_failed_total");
-        add("dubbo_provider_requests_processing_total");
-        add("dubbo_provider_requests_failed_total_aggregate");
-        add("dubbo_provider_requests_failed_network_total_aggregate");
-        add("dubbo_provider_requests_succeed_aggregate");
-        add("dubbo_provider_requests_business_failed_total");
+        addCounter("dubbo.provider.requests.succeed.total");
+        addGauge("dubbo.provider.rt.milliseconds.p99");
+        addGauge("dubbo.provider.requests.failed.codec.total.aggregate");
+        addGauge("dubbo.provider.requests.business.failed.aggregate");
+        addGauge("dubbo.provider.requests.failed.aggregate");
+        addGauge("dubbo.provider.requests.timeout.failed.aggregate");
+        addGauge("dubbo.provider.requests.limit.aggregate");
+        
addGauge("dubbo.provider.requests.failed.service.unavailable.total.aggregate");
+        addGauge("dubbo.provider.qps.total");
+        addGauge("dubbo.provider.rt.min.milliseconds.aggregate");
+        addGauge("dubbo.provider.rt.max.milliseconds.aggregate");
+        addGauge("dubbo.provider.rt.milliseconds.p90");
+        addGauge("dubbo.provider.rt.milliseconds.p50");
+        addGauge("dubbo.provider.rt.milliseconds.p95");
+        addCounter("dubbo.provider.requests.total");
+        addGauge("dubbo.provider.rt.avg.milliseconds.aggregate");
+        addGauge("dubbo.provider.requests.total.aggregate");
+        addCounter("dubbo.provider.requests.failed.total");
+        addGauge("dubbo.provider.requests.processing.total");
+        addGauge("dubbo.provider.requests.failed.total.aggregate");
+        addGauge("dubbo.provider.requests.failed.network.total.aggregate");
+        addGauge("dubbo.provider.requests.succeed.aggregate");
+        addCounter("dubbo.provider.requests.business.failed.total");
 
         //consumer
-        add("dubbo_consumer_requests_failed_service_unavailable_total");
+        addCounter("dubbo.consumer.requests.failed.service.unavailable.total");
 
         //config
-        add("dubbo_configcenter_total");
+        addGauge("dubbo.configcenter.total");
 
         //register
-        add("dubbo_register_service_rt_milliseconds_sum");
-        add("dubbo_registry_register_service_total");
-        add("dubbo_registry_register_service_succeed_total");
-        add("dubbo_register_service_rt_milliseconds_min");
-        add("dubbo_registry_register_requests_succeed_total");
-        add("dubbo_registry_register_requests_total");
-        add("dubbo_register_rt_milliseconds_last");
-        add("dubbo_register_rt_milliseconds_avg");
-        add("dubbo_register_rt_milliseconds_min");
-        add("dubbo_register_service_rt_milliseconds_last");
-        add("dubbo_register_rt_milliseconds_sum");
-        add("dubbo_register_service_rt_milliseconds_max");
-        add("dubbo_register_rt_milliseconds_max");
-        add("dubbo_register_service_rt_milliseconds_avg");
-
-        add("dubbo_registry_notify_requests_total");
-        add("dubbo_registry_subscribe_num_total");
-        add("dubbo_registry_register_requests_failed_total");
-        add("dubbo_registry_subscribe_num_succeed_total");
-        add("dubbo_registry_subscribe_num_failed_total");
-
-        add("dubbo_push_rt_milliseconds_avg");
-        add("dubbo_push_rt_milliseconds_min");
-        add("dubbo_push_rt_milliseconds_last");
-        add("dubbo_push_rt_milliseconds_sum");
-        add("dubbo_push_rt_milliseconds_max");
-
-        add("dubbo_store_provider_interface_rt_milliseconds_min");
-        add("dubbo_store_provider_interface_rt_milliseconds_max");
-        add("dubbo_store_provider_interface_rt_milliseconds_avg");
-        add("dubbo_store_provider_interface_rt_milliseconds_last");
-        add("dubbo_store_provider_interface_rt_milliseconds_sum");
+        addGauge("dubbo.register.service.rt.milliseconds.sum");
+        addGauge("dubbo.registry.register.service.total");
+        addGauge("dubbo.registry.register.service.succeed.total");
+        addGauge("dubbo.register.service.rt.milliseconds.min");
+        addGauge("dubbo.registry.register.requests.succeed.total");
+        addGauge("dubbo.registry.register.requests.total");
+        addGauge("dubbo.register.rt.milliseconds.last");
+        addGauge("dubbo.register.rt.milliseconds.avg");
+        addGauge("dubbo.register.rt.milliseconds.min");
+        addGauge("dubbo.register.service.rt.milliseconds.last");
+        addGauge("dubbo.register.rt.milliseconds.sum");
+        addGauge("dubbo.register.service.rt.milliseconds.max");
+        addGauge("dubbo.register.rt.milliseconds.max");
+        addGauge("dubbo.register.service.rt.milliseconds.avg");
+
+        addGauge("dubbo.registry.notify.requests.total");
+        addGauge("dubbo.registry.subscribe.num.total");
+        addGauge("dubbo.registry.register.requests.failed.total");
+        addGauge("dubbo.registry.subscribe.num.succeed.total");
+        addGauge("dubbo.registry.subscribe.num.failed.total");
+
+        addGauge("dubbo.push.rt.milliseconds.avg");
+        addGauge("dubbo.push.rt.milliseconds.min");
+        addGauge("dubbo.push.rt.milliseconds.last");
+        addGauge("dubbo.push.rt.milliseconds.sum");
+        addGauge("dubbo.push.rt.milliseconds.max");
+
+        addGauge("dubbo.store.provider.interface.rt.milliseconds.min");
+        addGauge("dubbo.store.provider.interface.rt.milliseconds.max");
+        addGauge("dubbo.store.provider.interface.rt.milliseconds.avg");
+        addGauge("dubbo.store.provider.interface.rt.milliseconds.last");
+        addGauge("dubbo.store.provider.interface.rt.milliseconds.sum");
 
         //metadata
-        add("dubbo_metadata_store_provider_succeed_total");
-        add("dubbo_metadata_store_provider_total");
-        add("dubbo_metadata_subscribe_num_failed_total");
-        add("dubbo_metadata_push_num_total");
-        add("dubbo_metadata_subscribe_num_total");
-        add("dubbo_metadata_subscribe_num_succeed_total");
-        add("dubbo_metadata_push_num_succeed_total");
-        add("dubbo_metadata_push_num_failed_total");
+        addGauge("dubbo.metadata.store.provider.succeed.total");
+        addGauge("dubbo.metadata.store.provider.total");
+        addGauge("dubbo.metadata.subscribe.num.failed.total");
+        addGauge("dubbo.metadata.push.num.total");
+        addGauge("dubbo.metadata.subscribe.num.total");
+        addGauge("dubbo.metadata.subscribe.num.succeed.total");
+        addGauge("dubbo.metadata.push.num.succeed.total");
+        addGauge("dubbo.metadata.push.num.failed.total");
 
         //thread
-        add("dubbo_thread_pool_thread_count");
-        add("dubbo_thread_pool_largest_size");
-        add("dubbo_thread_pool_active_size");
-        add("dubbo_thread_pool_queue_size");
-        add("dubbo_thread_pool_core_size");
-        add("dubbo_thread_pool_max_size");
+        addGauge("dubbo.thread.pool.thread.count");
+        addGauge("dubbo.thread.pool.largest.size");
+        addGauge("dubbo.thread.pool.active.size");
+        addGauge("dubbo.thread.pool.queue.size");
+        addGauge("dubbo.thread.pool.core.size");
+        addGauge("dubbo.thread.pool.max.size");
 
         // it usually does not appear in test case.
-        // add("dubbo_thread_pool_reject_thread_count");
+        // add("dubbo.thread.pool.reject.thread.count");
     }
 
-    private void add(String dubboStoreProviderInterfaceRtMillisecondsMin) {
-        metricKeys.add(dubboStoreProviderInterfaceRtMillisecondsMin);
+    // Use explicit kind only when it changes cross-registry compatible names.
+    // Example: `dubbo.application.info.total` resolves to 
`dubbo_application_total` on new clients.
+    private void addCounter(String rawName) {
+        metricExpectations.add(new MetricExpectation(rawName, 
PrometheusMetricAssert.MetricKind.COUNTER));
     }
 
+    // Example: `...qps.total` is exposed without `_total` on new clients when 
treated as a gauge.
+    private void addGauge(String rawName) {
+        metricExpectations.add(new MetricExpectation(rawName, 
PrometheusMetricAssert.MetricKind.GAUGE));
+    }
+
+
     @Test
     public void test() throws Exception {
         new EmbeddedZooKeeper(2181, false).start();
         ClassPathXmlApplicationContext context = new 
ClassPathXmlApplicationContext("dubbo-demo-provider.xml");
         context.start();
-        List<String> notExistedList = new ArrayList<>();
+        List<MetricExpectation> notExistedList = new ArrayList<>();
         try (CloseableHttpClient client = HttpClients.createDefault()) {
             HttpGet request = new HttpGet("http://localhost:"; + port + 
"/metrics");
             CloseableHttpResponse response = client.execute(request);
             InputStream inputStream = response.getEntity().getContent();
             String text = new BufferedReader(new 
InputStreamReader(inputStream, StandardCharsets.UTF_8))
                     .lines().collect(Collectors.joining("\n"));
-            for (int i = 0; i < metricKeys.size(); i++) {
-                String metricKey = metricKeys.get(i);
-                if (!text.contains(metricKey)) {
-                    notExistedList.add(metricKey);
+            for (MetricExpectation expectation : metricExpectations) {
+                try {
+                    PrometheusMetricAssert.assertDubboMetricExposed(text, 
expectation.rawName, expectation.kind);
+                } catch (AssertionError ignored) {
+                    notExistedList.add(expectation);
                 }
             }
         } catch (Throwable e) {
             Assert.fail(e.getMessage());
         }
         context.stop();
-        for (String metricKey : notExistedList) {
-            logger.error("metric key:{} doesn't exist", metricKey);
+        for (MetricExpectation metric : notExistedList) {
+            logger.error("metric rawName:{} with kind:{} doesn't exist", 
metric.rawName, metric.kind);
         }
         Assert.assertTrue(notExistedList.isEmpty());
     }
 
+    private static final class MetricExpectation {
+        private final String rawName;
+        private final PrometheusMetricAssert.MetricKind kind;
+
+        private MetricExpectation(String rawName, 
PrometheusMetricAssert.MetricKind kind) {
+            this.rawName = rawName;
+            this.kind = kind;
+        }
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to