This is an automated email from the ASF dual-hosted git repository.
gongchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
The following commit(s) were added to refs/heads/master by this push:
new fe54d42bc [improve] Improve Prometheus label PromQL parsing logic
(#3725)
fe54d42bc is described below
commit fe54d42bc05c25ec5af5184bf1b8aafe7ae99d49
Author: Duansg <[email protected]>
AuthorDate: Thu Aug 28 23:56:22 2025 +0800
[improve] Improve Prometheus label PromQL parsing logic (#3725)
---
.../http/promethus/PrometheusMatrixParser.java | 3 +-
.../http/promethus/PrometheusVectorParser.java | 2 +-
.../collect/http/HttpCollectImplTest.java | 165 +++++++++++++++++++++
.../hertzbeat/collector/util/CollectUtil.java | 11 +-
4 files changed, 177 insertions(+), 4 deletions(-)
diff --git
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/promethus/PrometheusMatrixParser.java
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/promethus/PrometheusMatrixParser.java
index a5bc29f59..37f80ad39 100644
---
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/promethus/PrometheusMatrixParser.java
+++
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/promethus/PrometheusMatrixParser.java
@@ -60,7 +60,7 @@ public class PrometheusMatrixParser extends
AbstractPrometheusParse {
boolean setValueFlag = false;
CollectRep.ValueRow.Builder valueRowBuilder =
CollectRep.ValueRow.newBuilder();
for (String aliasField : aliasFields) {
- if (!CollectUtil.assertPromRequireField(aliasField)) {
+ if (!CollectUtil.assertPromRequireField(aliasField) ||
CollectUtil.isValueAsLabel(aliasField, r.getMetric())) {
JsonElement jsonElement =
r.getMetric().get(aliasField);
if (jsonElement != null) {
valueRowBuilder.addColumn(jsonElement.getAsString());
@@ -93,7 +93,6 @@ public class PrometheusMatrixParser extends
AbstractPrometheusParse {
}
builder.addValueRow(valueRowBuilder.build());
}
-
}
}
}
diff --git
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/promethus/PrometheusVectorParser.java
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/promethus/PrometheusVectorParser.java
index 6d9c4f93a..3045c0af5 100644
---
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/promethus/PrometheusVectorParser.java
+++
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/http/promethus/PrometheusVectorParser.java
@@ -59,7 +59,7 @@ public class PrometheusVectorParser extends
AbstractPrometheusParse {
for (PromVectorOrMatrix.Result r : result) {
CollectRep.ValueRow.Builder valueRowBuilder =
CollectRep.ValueRow.newBuilder();
for (String aliasField : aliasFields) {
- if (!CollectUtil.assertPromRequireField(aliasField)) {
+ if (!CollectUtil.assertPromRequireField(aliasField) ||
CollectUtil.isValueAsLabel(aliasField, r.getMetric())) {
JsonElement jsonElement = r.getMetric().get(aliasField);
if (jsonElement != null) {
valueRowBuilder.addColumn(jsonElement.getAsString());
diff --git
a/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/http/HttpCollectImplTest.java
b/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/http/HttpCollectImplTest.java
index d03f591a9..5ea4596da 100644
---
a/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/http/HttpCollectImplTest.java
+++
b/hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/http/HttpCollectImplTest.java
@@ -293,6 +293,171 @@ class HttpCollectImplTest {
assertEquals("0.268751364291017", firstRow.getColumns(0));
}
+ @Test
+ void testParsePromQlLabelValue() throws Exception {
+ // Create Prometheus format test data
+ String prometheusData = """
+ {
+ "status": "success",
+ "data": {
+ "resultType": "vector",
+ "result": [
+ {
+ "metric": {
+ "__name__": "taos_cluster_info_first_ep",
+ "cluster_id": "590779086215866783",
+ "instance": "host.docker.internal:6043",
+ "job": "tdengine",
+ "value": "localhost:6030"
+ },
+ "value": [
+ 1756233177.048,
+ "1"
+ ]
+ }
+ ]
+ }
+ }""";
+ List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
+ CollectRep.MetricsData.Builder builder = new
CollectRep.MetricsData.Builder() {
+ @Override
+ public CollectRep.MetricsData.Builder
addValueRow(CollectRep.ValueRow valueRow) {
+ capturedRows.add(valueRow);
+ return super.addValueRow(valueRow);
+ }
+
+ @Override
+ public String getMetrics() {
+ return "jvm_memory_used_bytes";
+ }
+ };
+ Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
+ "parseResponseByPromQl",
+ String.class,
+ List.class,
+ HttpProtocol.class,
+ CollectRep.MetricsData.Builder.class);
+ parseMethod.setAccessible(true);
+
+ parseMethod.invoke(httpCollectImpl, prometheusData,
Lists.newArrayList("cluster_id", "value"), new HttpProtocol(), builder);
+
+ // Verify the results
+ assertEquals(1, capturedRows.size());
+ CollectRep.ValueRow firstRow = capturedRows.get(0);
+ assertEquals("590779086215866783", firstRow.getColumns(0));
+ assertEquals("localhost:6030", firstRow.getColumns(1));
+ }
+
+ @Test
+ void testParsePromQlMetricValue() throws Exception {
+ // Create Prometheus format test data
+ String prometheusData = """
+ {
+ "status": "success",
+ "data": {
+ "resultType": "vector",
+ "result": [
+ {
+ "metric": {
+ "__name__": "taos_cluster_info_first_ep",
+ "cluster_id": "590779086215866783",
+ "instance": "host.docker.internal:6043",
+ "job": "tdengine",
+ "value": "localhost:6030"
+ },
+ "value": [
+ 1756233177.048,
+ "1"
+ ]
+ }
+ ]
+ }
+ }""";
+ List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
+ CollectRep.MetricsData.Builder builder = new
CollectRep.MetricsData.Builder() {
+ @Override
+ public CollectRep.MetricsData.Builder
addValueRow(CollectRep.ValueRow valueRow) {
+ capturedRows.add(valueRow);
+ return super.addValueRow(valueRow);
+ }
+
+ @Override
+ public String getMetrics() {
+ return "jvm_memory_used_bytes";
+ }
+ };
+ Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
+ "parseResponseByPromQl",
+ String.class,
+ List.class,
+ HttpProtocol.class,
+ CollectRep.MetricsData.Builder.class);
+ parseMethod.setAccessible(true);
+
+ parseMethod.invoke(httpCollectImpl, prometheusData,
Lists.newArrayList("cluster_id", "value", "metric_value"), new HttpProtocol(),
builder);
+
+ // Verify the results
+ assertEquals(1, capturedRows.size());
+ CollectRep.ValueRow firstRow = capturedRows.get(0);
+ assertEquals("590779086215866783", firstRow.getColumns(0));
+ assertEquals("localhost:6030", firstRow.getColumns(1));
+ assertEquals("1", firstRow.getColumns(2));
+ }
+
+ @Test
+ void testParsePromQlValue() throws Exception {
+ // Create Prometheus format test data
+ String prometheusData = """
+ {
+ "status": "success",
+ "data": {
+ "resultType": "vector",
+ "result": [
+ {
+ "metric": {
+ "__name__": "taos_cluster_info_first_ep",
+ "cluster_id": "590779086215866783",
+ "instance": "host.docker.internal:6043",
+ "job": "tdengine"
+ },
+ "value": [
+ 1756233177.048,
+ "1"
+ ]
+ }
+ ]
+ }
+ }""";
+ List<CollectRep.ValueRow> capturedRows = new ArrayList<>();
+ CollectRep.MetricsData.Builder builder = new
CollectRep.MetricsData.Builder() {
+ @Override
+ public CollectRep.MetricsData.Builder
addValueRow(CollectRep.ValueRow valueRow) {
+ capturedRows.add(valueRow);
+ return super.addValueRow(valueRow);
+ }
+
+ @Override
+ public String getMetrics() {
+ return "jvm_memory_used_bytes";
+ }
+ };
+ Method parseMethod = HttpCollectImpl.class.getDeclaredMethod(
+ "parseResponseByPromQl",
+ String.class,
+ List.class,
+ HttpProtocol.class,
+ CollectRep.MetricsData.Builder.class);
+ parseMethod.setAccessible(true);
+
+ parseMethod.invoke(httpCollectImpl, prometheusData,
Lists.newArrayList("cluster_id", "value"), new HttpProtocol(), builder);
+
+ // Verify the results
+ assertEquals(1, capturedRows.size());
+ CollectRep.ValueRow firstRow = capturedRows.get(0);
+ assertEquals("590779086215866783", firstRow.getColumns(0));
+ assertEquals("1", firstRow.getColumns(1));
+ }
+
@Test
void testParsePrometheusLabelValue() throws Exception {
// Create Prometheus format test data
diff --git
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/util/CollectUtil.java
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/util/CollectUtil.java
index e8c65a055..4697b2295 100644
---
a/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/util/CollectUtil.java
+++
b/hertzbeat-collector/hertzbeat-collector-common/src/main/java/org/apache/hertzbeat/collector/util/CollectUtil.java
@@ -171,7 +171,16 @@ public final class CollectUtil {
* assert prom field
*/
public static Boolean assertPromRequireField(String aliasField) {
- return CommonConstants.PROM_TIME.equals(aliasField) ||
CommonConstants.PROM_VALUE.equals(aliasField);
+ return CommonConstants.PROM_TIME.equals(aliasField)
+ || CommonConstants.PROM_VALUE.equals(aliasField)
+ || CommonConstants.PROM_METRIC_VALUE.equals(aliasField);
+ }
+
+ /**
+ * Check if "value" field should be treated as a label instead of special
field
+ */
+ public static Boolean isValueAsLabel(String aliasField, JsonObject metric)
{
+ return CommonConstants.PROM_VALUE.equals(aliasField) && null != metric
&& metric.has(aliasField);
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]