This is an automated email from the ASF dual-hosted git repository.
mchades pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 1ba2633891 [#8750] Bugfix(metrics): sanitize gravitino-catalog metrics
(#8751)
1ba2633891 is described below
commit 1ba263389168ba623d5b16b4644a176f0b55e8d3
Author: Junda Yang <[email protected]>
AuthorDate: Wed Oct 8 20:15:01 2025 -0700
[#8750] Bugfix(metrics): sanitize gravitino-catalog metrics (#8751)
### What changes were proposed in this pull request?
Santinize all gravitino-catalog metrics
### Why are the changes needed?
Example gravitino-catalog metric from /prometheus/metrics endpoint:
```
# TYPE gravitino-catalog_fileset-cache_loads-success summary
gravitino-catalog_fileset-cache_loads-success{provider="fileset",metalake="uber",catalog="ma",quantile="0.5",}
0.015295218000000001
```
which contains hyphen (-).
It does not conform prometheus standard -
https://github.com/apache/gravitino/blob/caee8d20f5129dc22b7b3e7290091f619f590cbc/core/src/main/java/org/apache/gravitino/metrics/MetricsSystem.java#L189-L195
It causes errors when we parse the metrics from the endpoint.
Fix: #8750
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
Unit test added
---
.../gravitino/metrics/GravitinoSampleBuilder.java | 8 +-
.../metrics/TestGravitinoSampleBuilder.java | 115 ++++++++++++++++++++-
2 files changed, 115 insertions(+), 8 deletions(-)
diff --git
a/core/src/main/java/org/apache/gravitino/metrics/GravitinoSampleBuilder.java
b/core/src/main/java/org/apache/gravitino/metrics/GravitinoSampleBuilder.java
index 5f4b7f7982..54420913f3 100644
---
a/core/src/main/java/org/apache/gravitino/metrics/GravitinoSampleBuilder.java
+++
b/core/src/main/java/org/apache/gravitino/metrics/GravitinoSampleBuilder.java
@@ -82,10 +82,10 @@ public class GravitinoSampleBuilder extends
CustomMappingSampleBuilder {
String provider = matcher.group(1);
String metalake = matcher.group(2);
String catalog = matcher.group(3);
- // Replace '.' with '_' in the remaining part to conform to Prometheus
naming conventions
- String metricNameRest = matcher.group(4).replace('.', '_');
-
- String prometheusName = GRAVITINO_CATALOG_METRIC_PREFIX + "_" +
metricNameRest;
+ // Use Prometheus client's sanitization to conform to naming conventions
+ String metricNameRest = Collector.sanitizeMetricName(matcher.group(4));
+ String sanitizedPrefix =
Collector.sanitizeMetricName(GRAVITINO_CATALOG_METRIC_PREFIX);
+ String prometheusName = sanitizedPrefix + "_" + metricNameRest;
List<String> labelNames = new ArrayList<>();
labelNames.add("provider");
diff --git
a/core/src/test/java/org/apache/gravitino/metrics/TestGravitinoSampleBuilder.java
b/core/src/test/java/org/apache/gravitino/metrics/TestGravitinoSampleBuilder.java
index 0adc3772d9..3a6941fe17 100644
---
a/core/src/test/java/org/apache/gravitino/metrics/TestGravitinoSampleBuilder.java
+++
b/core/src/test/java/org/apache/gravitino/metrics/TestGravitinoSampleBuilder.java
@@ -18,8 +18,6 @@
*/
package org.apache.gravitino.metrics;
-import static
org.apache.gravitino.metrics.source.MetricsSource.GRAVITINO_CATALOG_METRIC_PREFIX;
-
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.prometheus.client.Collector;
@@ -52,7 +50,7 @@ public class TestGravitinoSampleBuilder {
sampleBuilder.createSample(
dropwizardName, "", Collections.emptyList(),
Collections.emptyList(), value);
- Assertions.assertEquals(GRAVITINO_CATALOG_METRIC_PREFIX +
"_some_metric_count", sample.name);
+ Assertions.assertEquals("gravitino_catalog_some_metric_count",
sample.name);
Assertions.assertEquals(ImmutableList.of("provider", "metalake",
"catalog"), sample.labelNames);
Assertions.assertEquals(ImmutableList.of("hive", "metalake1", "catalog1"),
sample.labelValues);
Assertions.assertEquals(value, sample.value);
@@ -69,7 +67,7 @@ public class TestGravitinoSampleBuilder {
sampleBuilder.createSample(
dropwizardName, "", additionalLabelNames, additionalLabelValues,
value);
- Assertions.assertEquals(GRAVITINO_CATALOG_METRIC_PREFIX +
"_another_metric", sample.name);
+ Assertions.assertEquals("gravitino_catalog_another_metric", sample.name);
Assertions.assertEquals(
ImmutableList.of("provider", "metalake", "catalog", "type"),
sample.labelNames);
Assertions.assertEquals(
@@ -106,4 +104,113 @@ public class TestGravitinoSampleBuilder {
Assertions.assertTrue(sample.labelValues.isEmpty());
Assertions.assertEquals(value, sample.value);
}
+
+ @Test
+ public void testCreateSampleWithHyphensInMetricNameRest() {
+ String dropwizardName =
"gravitino-catalog.fileset.metalake1.catalog1.schema-cache.hit-count";
+ double value = 50.0;
+
+ Collector.MetricFamilySamples.Sample sample =
+ sampleBuilder.createSample(
+ dropwizardName, "", Collections.emptyList(),
Collections.emptyList(), value);
+
+ // Both prefix and metricNameRest should have hyphens converted to
underscores
+ Assertions.assertEquals("gravitino_catalog_schema_cache_hit_count",
sample.name);
+ Assertions.assertEquals(ImmutableList.of("provider", "metalake",
"catalog"), sample.labelNames);
+ Assertions.assertEquals(
+ ImmutableList.of("fileset", "metalake1", "catalog1"),
sample.labelValues);
+ Assertions.assertEquals(value, sample.value);
+ }
+
+ @Test
+ public void testCreateSampleWithFilesetCacheMetric() {
+ String dropwizardName =
+
"gravitino-catalog.fileset.test-metalake.test-catalog.fileset-cache.miss-count";
+ double value = 15.0;
+
+ Collector.MetricFamilySamples.Sample sample =
+ sampleBuilder.createSample(
+ dropwizardName, "", Collections.emptyList(),
Collections.emptyList(), value);
+
+ // All hyphens should be converted to underscores
+ Assertions.assertEquals("gravitino_catalog_fileset_cache_miss_count",
sample.name);
+ Assertions.assertEquals(ImmutableList.of("provider", "metalake",
"catalog"), sample.labelNames);
+ Assertions.assertEquals(
+ ImmutableList.of("fileset", "test-metalake", "test-catalog"),
sample.labelValues);
+ Assertions.assertEquals(value, sample.value);
+ }
+
+ @Test
+ public void testCreateSampleWithMultipleHyphensAndDots() {
+ String dropwizardName =
+
"gravitino-catalog.hive.my-metalake.my-catalog.complex-metric-name.sub-component.total";
+ double value = 100.0;
+
+ Collector.MetricFamilySamples.Sample sample =
+ sampleBuilder.createSample(
+ dropwizardName, "", Collections.emptyList(),
Collections.emptyList(), value);
+
+ // All dots and hyphens in metricNameRest should be converted to
underscores
+ Assertions.assertEquals(
+ "gravitino_catalog_complex_metric_name_sub_component_total",
sample.name);
+ Assertions.assertEquals(ImmutableList.of("provider", "metalake",
"catalog"), sample.labelNames);
+ Assertions.assertEquals(
+ ImmutableList.of("hive", "my-metalake", "my-catalog"),
sample.labelValues);
+ Assertions.assertEquals(value, sample.value);
+ }
+
+ @Test
+ public void testCreateSampleWithOnlyHyphensInMetricName() {
+ String dropwizardName =
"gravitino-catalog.jdbc.metalake.catalog.http-request-duration";
+ double value = 0.5;
+
+ Collector.MetricFamilySamples.Sample sample =
+ sampleBuilder.createSample(
+ dropwizardName, "", Collections.emptyList(),
Collections.emptyList(), value);
+
+ // Hyphens in metricNameRest should be converted to underscores
+ Assertions.assertEquals("gravitino_catalog_http_request_duration",
sample.name);
+ Assertions.assertEquals(ImmutableList.of("provider", "metalake",
"catalog"), sample.labelNames);
+ Assertions.assertEquals(ImmutableList.of("jdbc", "metalake", "catalog"),
sample.labelValues);
+ Assertions.assertEquals(value, sample.value);
+ }
+
+ @Test
+ public void testCreateSampleWithMixedSpecialCharacters() {
+ String dropwizardName =
"gravitino-catalog.model.test.example.cache-stats.hit-ratio.avg";
+ double value = 0.85;
+
+ Collector.MetricFamilySamples.Sample sample =
+ sampleBuilder.createSample(
+ dropwizardName, "", Collections.emptyList(),
Collections.emptyList(), value);
+
+ // Both dots and hyphens should be converted to underscores
+ Assertions.assertEquals("gravitino_catalog_cache_stats_hit_ratio_avg",
sample.name);
+ Assertions.assertEquals(ImmutableList.of("provider", "metalake",
"catalog"), sample.labelNames);
+ Assertions.assertEquals(ImmutableList.of("model", "test", "example"),
sample.labelValues);
+ Assertions.assertEquals(value, sample.value);
+ }
+
+ @Test
+ public void testCreateSampleWithAdditionalLabelsAndHyphens() {
+ String dropwizardName =
+
"gravitino-catalog.fileset.prod-metalake.main-catalog.schema-cache.eviction-count";
+ double value = 25.0;
+ List<String> additionalLabelNames = ImmutableList.of("cache-type",
"operation-mode");
+ List<String> additionalLabelValues = ImmutableList.of("lru", "async");
+
+ Collector.MetricFamilySamples.Sample sample =
+ sampleBuilder.createSample(
+ dropwizardName, "", additionalLabelNames, additionalLabelValues,
value);
+
+ // Metric name should have all hyphens converted to underscores
+ Assertions.assertEquals("gravitino_catalog_schema_cache_eviction_count",
sample.name);
+ Assertions.assertEquals(
+ ImmutableList.of("provider", "metalake", "catalog", "cache-type",
"operation-mode"),
+ sample.labelNames);
+ Assertions.assertEquals(
+ ImmutableList.of("fileset", "prod-metalake", "main-catalog", "lru",
"async"),
+ sample.labelValues);
+ Assertions.assertEquals(value, sample.value);
+ }
}