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

hello-stephen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 038e2274ef6 [improvement](metrics) Unify build version metric labels 
(#68655)
038e2274ef6 is described below

commit 038e2274ef678c44f85214e31da6d3e1d48a794f
Author: Gavin Chou <[email protected]>
AuthorDate: Thu Oct 8 19:39:57 2026 +0800

    [improvement](metrics) Unify build version metric labels (#68655)
    
    Problem Summary:
    
    FE already exposes its build identity with `version`, `major`, `minor`,
    `patch`, `hotfix`, and `short_hash` labels. BE and Cloud expose the same
    numeric version value without those labels, even though the decimal
    concatenation is ambiguous for some versions and does not include RC or
    revision information.
    
    This change adds the same fixed label schema to the existing BE and
    Cloud metrics while preserving all three metric names and their numeric
    values. The version metrics still produce one series per process, so the
    fixed build labels do not introduce runtime-dependent cardinality. The
    regression case now parses the three exposition formats and verifies
    that FE, BE, and Cloud expose identical build metadata and values.
---
 be/src/common/config.cpp                           |  4 ++
 be/src/common/config.h                             |  3 +
 be/src/service/doris_main.cpp                      |  2 +
 be/src/util/debug_util.cpp                         | 39 +++++++++++-
 be/src/util/debug_util.h                           |  4 ++
 be/test/util/debug_util_test.cpp                   | 63 +++++++++++++++++++
 cloud/src/common/CMakeLists.txt                    |  1 +
 cloud/src/common/version_metrics.cpp               | 72 ++++++++++++++++++++++
 cloud/src/common/version_metrics.h                 | 26 ++++++++
 cloud/src/main.cpp                                 | 16 +----
 cloud/test/metric_test.cpp                         | 37 +++++++++++
 .../java/org/apache/doris/metric/MetricsTest.java  | 24 ++++++++
 .../suites/metrics_p0/test_version_metrics.groovy  | 51 +++++++++------
 13 files changed, 308 insertions(+), 34 deletions(-)

diff --git a/be/src/common/config.cpp b/be/src/common/config.cpp
index f04adb64147..8419126ae07 100644
--- a/be/src/common/config.cpp
+++ b/be/src/common/config.cpp
@@ -113,6 +113,10 @@ DEFINE_Int32(brpc_num_threads, "256");
 // the default value is set to -1, which means never close idle connection.
 DEFINE_Int32(brpc_idle_timeout_sec, "-1");
 
+// Maximum number of multi-dimensional bvar samples exported by /brpc_metrics.
+// brpc 1.4 defaults this flag to 0, which disables all MultiDimension metrics.
+DEFINE_String(bvar_max_dump_multi_dimension_metric_num, "5000");
+
 // Declare a selection strategy for those servers have many ips.
 // Note that there should at most one ip match this list.
 // this is a list in semicolon-delimited format, in CIDR notation, e.g. 
10.10.10.0/24
diff --git a/be/src/common/config.h b/be/src/common/config.h
index 473744f06fe..6b1b3db2569 100644
--- a/be/src/common/config.h
+++ b/be/src/common/config.h
@@ -157,6 +157,9 @@ DECLARE_Int32(arrow_flight_sql_proxy_port);
 DECLARE_Int32(brpc_num_threads);
 DECLARE_Int32(brpc_idle_timeout_sec);
 
+// Maximum number of multi-dimensional bvar samples exported by /brpc_metrics.
+DECLARE_String(bvar_max_dump_multi_dimension_metric_num);
+
 // Declare a selection strategy for those servers have many ips.
 // Note that there should at most one ip match this list.
 // This is a list in semicolon-delimited format, in CIDR notation, e.g. 
10.10.10.0/24
diff --git a/be/src/service/doris_main.cpp b/be/src/service/doris_main.cpp
index 374d698a2a5..5193e666d71 100644
--- a/be/src/service/doris_main.cpp
+++ b/be/src/service/doris_main.cpp
@@ -440,6 +440,8 @@ int main(int argc, char** argv) {
         return -1;
     }
 
+    doris::init_be_version_metrics();
+
     // ATTN: Callers that want to override default gflags variables should do 
so before calling this method
     google::ParseCommandLineFlags(&argc, &argv, true);
     // ATTN: MUST init before LOG
diff --git a/be/src/util/debug_util.cpp b/be/src/util/debug_util.cpp
index b98dd76967b..7362788c169 100644
--- a/be/src/util/debug_util.cpp
+++ b/be/src/util/debug_util.cpp
@@ -18,16 +18,23 @@
 #include "util/debug_util.h"
 
 #include <bvar/bvar.h>
+#include <bvar/multi_dimension.h>
 #include <gen_cpp/HeartbeatService_types.h>
 #include <gen_cpp/PlanNodes_types.h>
+#include <gflags/gflags.h>
 #include <stdint.h>
 
+#include <cstdlib>
 #include <cstring>
 #include <iomanip>
+#include <list>
 #include <map>
 #include <sstream> // IWYU pragma: keep
+#include <string>
 #include <utility>
 
+#include "common/check.h"
+#include "common/config.h"
 #include "common/version_internal.h"
 #include "fmt/core.h"
 #include "util/uid_util.h"
@@ -109,7 +116,9 @@ std::string hexdump(const char* buf, int len) {
     return ss.str();
 }
 
-bvar::Status<uint64_t> be_version_metrics("doris_be_version", [] {
+namespace {
+
+uint64_t get_be_version_metric_value() {
     std::stringstream ss;
     ss << version::doris_build_version_major() << 0 << 
version::doris_build_version_minor() << 0
        << version::doris_build_version_patch();
@@ -117,7 +126,33 @@ bvar::Status<uint64_t> 
be_version_metrics("doris_be_version", [] {
         ss << 0 << version::doris_build_version_hotfix();
     }
     return std::strtoul(ss.str().c_str(), nullptr, 10);
-}());
+}
+
+} // namespace
+
+void init_be_version_metrics() {
+    // MultiDimension metrics are omitted from /brpc_metrics while this brpc 
flag is 0.
+    DORIS_CHECK(
+            
!google::SetCommandLineOption("bvar_max_dump_multi_dimension_metric_number",
+                                          
config::bvar_max_dump_multi_dimension_metric_num.c_str())
+                     .empty());
+
+    static const bool initialized = [] {
+        static bvar::MultiDimension<bvar::Status<uint64_t>> metrics(
+                "doris_be_version", {"version", "major", "minor", "patch", 
"hotfix", "short_hash"});
+        auto* metric = metrics.get_stats(
+                std::list<std::string> {version::doris_build_version(),
+                                        
std::to_string(version::doris_build_version_major()),
+                                        
std::to_string(version::doris_build_version_minor()),
+                                        
std::to_string(version::doris_build_version_patch()),
+                                        
std::to_string(version::doris_build_version_hotfix()),
+                                        version::doris_build_short_hash()});
+        DORIS_CHECK(metric != nullptr);
+        metric->set_value(get_be_version_metric_value());
+        return true;
+    }();
+    static_cast<void>(initialized);
+}
 
 std::string PrintThriftNetworkAddress(const TNetworkAddress& add) {
     std::stringstream ss;
diff --git a/be/src/util/debug_util.h b/be/src/util/debug_util.h
index 19485ca07d2..5fad41ec637 100644
--- a/be/src/util/debug_util.h
+++ b/be/src/util/debug_util.h
@@ -50,6 +50,10 @@ std::string get_short_version();
 // Returns "<program short name> version <GetBuildVersion(compact)>"
 std::string get_version_string(bool compact);
 
+// Enables multi-dimensional bvar export and registers doris_be_version.
+// This must run before the brpc server starts.
+void init_be_version_metrics();
+
 std::string hexdump(const char* buf, int len);
 
 } // namespace doris
diff --git a/be/test/util/debug_util_test.cpp b/be/test/util/debug_util_test.cpp
new file mode 100644
index 00000000000..983268a4282
--- /dev/null
+++ b/be/test/util/debug_util_test.cpp
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "util/debug_util.h"
+
+#include <butil/iobuf.h>
+#include <butil/strings/string_piece.h>
+
+// brpc's header uses the butil types above without including their 
definitions.
+#include <brpc/builtin/prometheus_metrics_service.h>
+
+#include <cstdlib>
+#include <sstream>
+#include <string>
+
+#include "common/config.h"
+#include "common/version_internal.h"
+
+namespace doris {
+
+TEST(DebugUtilTest, BeVersionMetricIsExportedWithBuildLabels) {
+    config::bvar_max_dump_multi_dimension_metric_num = "5000";
+    init_be_version_metrics();
+
+    butil::IOBuf output;
+    ASSERT_EQ(0, brpc::DumpPrometheusMetricsToIOBuf(&output));
+    const std::string body = output.to_string();
+
+    std::stringstream value;
+    value << version::doris_build_version_major() << 0 << 
version::doris_build_version_minor() << 0
+          << version::doris_build_version_patch();
+    if (version::doris_build_version_hotfix() > 0) {
+        value << 0 << version::doris_build_version_hotfix();
+    }
+
+    std::stringstream sample;
+    sample << "doris_be_version{version=\"" << version::doris_build_version() 
<< "\",major=\""
+           << version::doris_build_version_major() << "\",minor=\""
+           << version::doris_build_version_minor() << "\",patch=\""
+           << version::doris_build_version_patch() << "\",hotfix=\""
+           << version::doris_build_version_hotfix() << "\",short_hash=\""
+           << version::doris_build_short_hash() << "\"} "
+           << std::strtoull(value.str().c_str(), nullptr, 10);
+
+    EXPECT_NE(std::string::npos, body.find("# TYPE doris_be_version gauge")) 
<< body;
+    EXPECT_NE(std::string::npos, body.find(sample.str())) << body;
+}
+
+} // namespace doris
diff --git a/cloud/src/common/CMakeLists.txt b/cloud/src/common/CMakeLists.txt
index a1b989cace1..9f29e1a183b 100644
--- a/cloud/src/common/CMakeLists.txt
+++ b/cloud/src/common/CMakeLists.txt
@@ -29,6 +29,7 @@ set(COMMON_FILES
     encryption_util.cpp
     http_helper.cpp
     metric.cpp
+    version_metrics.cpp
     kms.cpp
     network_util.cpp
     ../server/oss/cloud_server_starter_factory.cpp
diff --git a/cloud/src/common/version_metrics.cpp 
b/cloud/src/common/version_metrics.cpp
new file mode 100644
index 00000000000..e627c853d3e
--- /dev/null
+++ b/cloud/src/common/version_metrics.cpp
@@ -0,0 +1,72 @@
+// 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.
+
+#include "common/version_metrics.h"
+
+#include <bvar/bvar.h>
+#include <bvar/multi_dimension.h>
+#include <gen_cpp/cloud_version.h>
+#include <gflags/gflags.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <list>
+#include <sstream>
+#include <string>
+
+#include "common/config.h"
+
+namespace doris::cloud {
+namespace {
+
+uint64_t get_doris_cloud_version_metric_value() {
+    std::stringstream ss;
+    ss << DORIS_CLOUD_BUILD_VERSION_MAJOR << 0 << 
DORIS_CLOUD_BUILD_VERSION_MINOR << 0
+       << DORIS_CLOUD_BUILD_VERSION_PATCH;
+    if (DORIS_CLOUD_BUILD_VERSION_HOTFIX > 0) {
+        ss << 0 << DORIS_CLOUD_BUILD_VERSION_HOTFIX;
+    }
+    return std::strtoul(ss.str().c_str(), nullptr, 10);
+}
+
+} // namespace
+
+void init_doris_cloud_version_metrics() {
+    // MultiDimension metrics are omitted from /brpc_metrics while this brpc 
flag is 0.
+    
CHECK(!google::SetCommandLineOption("bvar_max_dump_multi_dimension_metric_number",
+                                        
config::bvar_max_dump_multi_dimension_metric_num.c_str())
+                   .empty());
+
+    static const bool initialized = [] {
+        // Keep the metric name role-neutral because one doris_cloud process 
can run meta-service,
+        // recycler, or both. Runtime roles should be represented by scrape 
target labels.
+        static bvar::MultiDimension<bvar::Status<uint64_t>> metrics(
+                "doris_cloud_version",
+                {"version", "major", "minor", "patch", "hotfix", 
"short_hash"});
+        auto* metric = metrics.get_stats(std::list<std::string> {
+                DORIS_CLOUD_BUILD_VERSION, 
std::to_string(DORIS_CLOUD_BUILD_VERSION_MAJOR),
+                std::to_string(DORIS_CLOUD_BUILD_VERSION_MINOR),
+                std::to_string(DORIS_CLOUD_BUILD_VERSION_PATCH),
+                std::to_string(DORIS_CLOUD_BUILD_VERSION_HOTFIX), 
DORIS_CLOUD_BUILD_SHORT_HASH});
+        CHECK(metric != nullptr);
+        metric->set_value(get_doris_cloud_version_metric_value());
+        return true;
+    }();
+    static_cast<void>(initialized);
+}
+
+} // namespace doris::cloud
diff --git a/cloud/src/common/version_metrics.h 
b/cloud/src/common/version_metrics.h
new file mode 100644
index 00000000000..d91b2420136
--- /dev/null
+++ b/cloud/src/common/version_metrics.h
@@ -0,0 +1,26 @@
+// 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.
+
+#pragma once
+
+namespace doris::cloud {
+
+// Enables multi-dimensional bvar export and registers doris_cloud_version.
+// This must run before the brpc server starts.
+void init_doris_cloud_version_metrics();
+
+} // namespace doris::cloud
diff --git a/cloud/src/main.cpp b/cloud/src/main.cpp
index bbaa7953a5a..319fcaaaaae 100644
--- a/cloud/src/main.cpp
+++ b/cloud/src/main.cpp
@@ -30,6 +30,7 @@
 #include <memory>
 #include <mutex>
 #include <sstream>
+#include <string>
 #include <thread>
 
 #include "common/arg_parser.h"
@@ -38,6 +39,7 @@
 #include "common/encryption_util.h"
 #include "common/logging.h"
 #include "common/network_util.h"
+#include "common/version_metrics.h"
 #include "meta-service/meta_server.h"
 #include "meta-store/mem_txn_kv.h"
 #include "meta-store/txn_kv.h"
@@ -151,17 +153,6 @@ static std::string build_info() {
     return ss.str();
 }
 
-// TODO(gavin): add doris cloud role to the metrics name
-bvar::Status<uint64_t> doris_cloud_version_metrics("doris_cloud_version", [] {
-    std::stringstream ss;
-    ss << DORIS_CLOUD_BUILD_VERSION_MAJOR << 0 << 
DORIS_CLOUD_BUILD_VERSION_MINOR << 0
-       << DORIS_CLOUD_BUILD_VERSION_PATCH;
-    if (DORIS_CLOUD_BUILD_VERSION_HOTFIX > 0) {
-        ss << 0 << DORIS_CLOUD_BUILD_VERSION_HOTFIX;
-    }
-    return std::strtoul(ss.str().c_str(), nullptr, 10);
-}());
-
 namespace brpc {
 DECLARE_uint64(max_body_size);
 DECLARE_int64(socket_max_unwritten_bytes);
@@ -245,8 +236,7 @@ int main(int argc, char** argv) {
         std::cerr << "try to start meta_service, recycler" << std::endl;
     }
 
-    google::SetCommandLineOption("bvar_max_dump_multi_dimension_metric_number",
-                                 
config::bvar_max_dump_multi_dimension_metric_num.c_str());
+    init_doris_cloud_version_metrics();
 
     brpc::Server server;
     brpc::FLAGS_max_body_size = config::brpc_max_body_size;
diff --git a/cloud/test/metric_test.cpp b/cloud/test/metric_test.cpp
index 5bcfb975598..9bbd2410cd0 100644
--- a/cloud/test/metric_test.cpp
+++ b/cloud/test/metric_test.cpp
@@ -17,15 +17,24 @@
 
 #include "common/metric.h"
 
+#include <butil/iobuf.h>
+#include <butil/strings/string_piece.h>
+
+// brpc's header uses the butil types above without including their 
definitions.
+#include <brpc/builtin/prometheus_metrics_service.h>
+#include <gen_cpp/cloud_version.h>
 #include <gtest/gtest.h>
 
+#include <cstdlib>
 #include <fstream>
 #include <iostream>
+#include <sstream>
 #include <string>
 #include <thread>
 
 #include "common/bvars.h"
 #include "common/config.h"
+#include "common/version_metrics.h"
 #include "meta-store/mem_txn_kv.h"
 #include "meta-store/txn_kv.h"
 #include "meta-store/txn_kv_error.h"
@@ -35,6 +44,34 @@ int main(int argc, char** argv) {
     return RUN_ALL_TESTS();
 }
 
+TEST(MetricTest, CloudVersionMetricIsExportedWithBuildLabels) {
+    using namespace doris::cloud;
+
+    config::bvar_max_dump_multi_dimension_metric_num = "5000";
+    init_doris_cloud_version_metrics();
+
+    butil::IOBuf output;
+    ASSERT_EQ(0, brpc::DumpPrometheusMetricsToIOBuf(&output));
+    const std::string body = output.to_string();
+
+    std::stringstream value;
+    value << DORIS_CLOUD_BUILD_VERSION_MAJOR << 0 << 
DORIS_CLOUD_BUILD_VERSION_MINOR << 0
+          << DORIS_CLOUD_BUILD_VERSION_PATCH;
+    if (DORIS_CLOUD_BUILD_VERSION_HOTFIX > 0) {
+        value << 0 << DORIS_CLOUD_BUILD_VERSION_HOTFIX;
+    }
+
+    std::stringstream sample;
+    sample << "doris_cloud_version{version=\"" << DORIS_CLOUD_BUILD_VERSION << 
"\",major=\""
+           << DORIS_CLOUD_BUILD_VERSION_MAJOR << "\",minor=\"" << 
DORIS_CLOUD_BUILD_VERSION_MINOR
+           << "\",patch=\"" << DORIS_CLOUD_BUILD_VERSION_PATCH << 
"\",hotfix=\""
+           << DORIS_CLOUD_BUILD_VERSION_HOTFIX << "\",short_hash=\"" << 
DORIS_CLOUD_BUILD_SHORT_HASH
+           << "\"} " << std::strtoull(value.str().c_str(), nullptr, 10);
+
+    EXPECT_NE(std::string::npos, body.find("# TYPE doris_cloud_version 
gauge")) << body;
+    EXPECT_NE(std::string::npos, body.find(sample.str())) << body;
+}
+
 TEST(MetricTest, FdbMetricExporterTest) {
     using namespace doris::cloud;
 
diff --git a/fe/fe-core/src/test/java/org/apache/doris/metric/MetricsTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/metric/MetricsTest.java
index 448bc5430ab..9432c2fa510 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/metric/MetricsTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/metric/MetricsTest.java
@@ -24,6 +24,7 @@ import org.apache.doris.cloud.JobWarmUpStats;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.FeConstants;
 import org.apache.doris.common.Pair;
+import org.apache.doris.common.Version;
 import org.apache.doris.common.jmockit.Deencapsulation;
 import org.apache.doris.common.util.JsonUtil;
 import org.apache.doris.ha.FrontendNodeType;
@@ -70,6 +71,29 @@ public class MetricsTest {
         MetricRepo.init();
     }
 
+    @Test
+    public void testVersionMetricIsExportedWithBuildLabels() {
+        StringBuilder value = new StringBuilder()
+                .append(Version.DORIS_BUILD_VERSION_MAJOR).append(0)
+                .append(Version.DORIS_BUILD_VERSION_MINOR).append(0)
+                .append(Version.DORIS_BUILD_VERSION_PATCH);
+        if (Version.DORIS_BUILD_VERSION_HOTFIX > 0) {
+            value.append(0).append(Version.DORIS_BUILD_VERSION_HOTFIX);
+        }
+
+        String expectedSample = "doris_fe_version{version=\"" + 
Version.DORIS_BUILD_VERSION
+                + "\", major=\"" + Version.DORIS_BUILD_VERSION_MAJOR
+                + "\", minor=\"" + Version.DORIS_BUILD_VERSION_MINOR
+                + "\", patch=\"" + Version.DORIS_BUILD_VERSION_PATCH
+                + "\", hotfix=\"" + Version.DORIS_BUILD_VERSION_HOTFIX
+                + "\", short_hash=\"" + Version.DORIS_BUILD_SHORT_HASH
+                + "\"} " + Long.parseLong(value.toString());
+
+        String metricResult = getPrometheusMetrics();
+        Assertions.assertTrue(metricResult.contains("# TYPE doris_fe_version 
gauge"), metricResult);
+        Assertions.assertTrue(metricResult.contains(expectedSample), 
metricResult);
+    }
+
     @Test
     public void testTcpMetrics() {
         List<Metric> metrics = MetricRepo.getMetricsByName("snmp");
diff --git a/regression-test/suites/metrics_p0/test_version_metrics.groovy 
b/regression-test/suites/metrics_p0/test_version_metrics.groovy
index e6625f698ea..39112ec6e77 100644
--- a/regression-test/suites/metrics_p0/test_version_metrics.groovy
+++ b/regression-test/suites/metrics_p0/test_version_metrics.groovy
@@ -19,6 +19,33 @@ import java.util.regex.Pattern
 // under the License.
 
 suite("test_version_metrics") {
+    def requiredVersionLabels = ["version", "major", "minor", "patch", 
"hotfix", "short_hash"] as Set
+    def parseVersionMetric = { body, metricName ->
+        def parsedMetric = null
+        Pattern pattern = Pattern.compile('^' + Pattern.quote(metricName) + 
'\\{([^}]*)}\\s+(\\d+)$')
+        for (final def line in body.readLines()) {
+            Matcher matcher = pattern.matcher(line)
+            if (!matcher.matches()) {
+                continue
+            }
+
+            def labels = [:]
+            for (String label : matcher.group(1).split(",")) {
+                String[] keyValue = label.trim().split("=", 2)
+                assertEquals(2, keyValue.length)
+                assertTrue(keyValue[1].startsWith("\"") && 
keyValue[1].endsWith("\""))
+                labels[keyValue[0]] = keyValue[1].substring(1, 
keyValue[1].length() - 1)
+            }
+            assertEquals(requiredVersionLabels, labels.keySet())
+            parsedMetric = [labels: labels, value: 
Long.parseLong(matcher.group(2))]
+            break
+        }
+        assertNotNull(parsedMetric)
+        assertTrue(parsedMetric.value >= 0)
+        return parsedMetric
+    }
+
+    def feVersionMetric = null
     httpTest {
         endpoint context.config.feHttpAddress
         uri "/metrics"
@@ -27,15 +54,7 @@ suite("test_version_metrics") {
             logger.debug("code:${code} body:${body}");
             assertEquals(200, code)
             assertTrue(body.contains("doris_fe_version"))
-            for (final def line in body.split("\n")) {
-                if (line.startsWith("doris_fe_version")) {
-                    Pattern pattern = 
Pattern.compile(/^doris_fe_version\{.*}\s+(\d+)$/)
-                    Matcher matcher = pattern.matcher(line)
-                    assertTrue(matcher.matches())
-                    assertTrue(Long.parseLong(matcher.group(1)) >= 0)
-                    break
-                }
-            }
+            feVersionMetric = parseVersionMetric(body, "doris_fe_version")
         }
     }
 
@@ -50,11 +69,8 @@ suite("test_version_metrics") {
             logger.debug("code:${code} body:${body}");
             assertEquals(200, code)
             assertTrue(body.contains("doris_be_version"))
-            for (final def line in body.split("\n")) {
-                if (line.contains("doris_be_version") && !line.contains("#")) {
-                    assertTrue(Long.parseLong(line.split(" ")[1]) >= 0)
-                }
-            }
+            def beVersionMetric = parseVersionMetric(body, "doris_be_version")
+            assertEquals(feVersionMetric, beVersionMetric)
         }
     }
 
@@ -71,11 +87,8 @@ suite("test_version_metrics") {
                 logger.debug("code:${code} body:${body}");
                 assertEquals(200, code)
                 assertTrue(body.contains("doris_cloud_version"))
-                for (final def line in body.split("\n")) {
-                    if (line.contains("doris_cloud_version") && 
!line.contains("#")) {
-                        assertTrue(Long.parseLong(line.split(" ")[1]) >= 0)
-                    }
-                }
+                def cloudVersionMetric = parseVersionMetric(body, 
"doris_cloud_version")
+                assertEquals(feVersionMetric, cloudVersionMetric)
             }
         }
     }


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

Reply via email to