From c0482d27489e8e7429b634531f41fb5df784a8ed Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 4 Nov 2025 09:30:08 +0000
Subject: [PATCH 1/7] Initial plan
From 885dcab4ca7ed72267746c823791474ab0dd656d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 4 Nov 2025 09:49:26 +0000
Subject: [PATCH 2/7] Optimize isValidLegacyLabelName and
isValidLegacyMetricName to use character-by-character validation instead of
regex
Co-authored-by: zeitlinger <2832627+zeitlinger@users.noreply.github.com>
---
.../model/snapshots/PrometheusNaming.java | 59 ++++++++++++++++++-
1 file changed, 56 insertions(+), 3 deletions(-)
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
index e79b0d4d8..3f293271d 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
@@ -18,9 +18,22 @@
*/
public class PrometheusNaming {
+ /**
+ * @deprecated Not used anymore. Kept for backward compatibility. The validation is now done
+ * without regex for better performance.
+ */
+ @Deprecated
+ @SuppressWarnings("UnusedVariable")
private static final Pattern METRIC_NAME_PATTERN = Pattern.compile("^[a-zA-Z_:][a-zA-Z0-9_:]*$");
- /** Legal characters for label names. */
+ /**
+ * Legal characters for label names.
+ *
+ * @deprecated Not used anymore. Kept for backward compatibility. The validation is now done
+ * without regex for better performance.
+ */
+ @Deprecated
+ @SuppressWarnings("UnusedVariable")
private static final Pattern LEGACY_LABEL_NAME_PATTERN =
Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*$");
@@ -90,7 +103,29 @@ public static String validateMetricName(String name) {
}
public static boolean isValidLegacyMetricName(String name) {
- return METRIC_NAME_PATTERN.matcher(name).matches();
+ if (name.isEmpty()) {
+ return false;
+ }
+ // First character must be [a-zA-Z_:]
+ char first = name.charAt(0);
+ if (!((first >= 'a' && first <= 'z')
+ || (first >= 'A' && first <= 'Z')
+ || first == '_'
+ || first == ':')) {
+ return false;
+ }
+ // Remaining characters must be [a-zA-Z0-9_:]
+ for (int i = 1; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if (!((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9')
+ || c == '_'
+ || c == ':')) {
+ return false;
+ }
+ }
+ return true;
}
public static boolean isValidLabelName(String name) {
@@ -106,7 +141,25 @@ private static boolean isValidUtf8(String name) {
}
public static boolean isValidLegacyLabelName(String name) {
- return LEGACY_LABEL_NAME_PATTERN.matcher(name).matches();
+ if (name.isEmpty()) {
+ return false;
+ }
+ // First character must be [a-zA-Z_]
+ char first = name.charAt(0);
+ if (!((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z') || first == '_')) {
+ return false;
+ }
+ // Remaining characters must be [a-zA-Z0-9_]
+ for (int i = 1; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if (!((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9')
+ || c == '_')) {
+ return false;
+ }
+ }
+ return true;
}
/**
From 2f8aa42863fd148c0b2ac1b1222682fb0aad4505 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 4 Nov 2025 09:56:19 +0000
Subject: [PATCH 3/7] Address code review: improve formatting consistency
Co-authored-by: zeitlinger <2832627+zeitlinger@users.noreply.github.com>
---
.../prometheus/metrics/model/snapshots/PrometheusNaming.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
index 3f293271d..377f0eba1 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
@@ -146,7 +146,9 @@ public static boolean isValidLegacyLabelName(String name) {
}
// First character must be [a-zA-Z_]
char first = name.charAt(0);
- if (!((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z') || first == '_')) {
+ if (!((first >= 'a' && first <= 'z')
+ || (first >= 'A' && first <= 'Z')
+ || first == '_')) {
return false;
}
// Remaining characters must be [a-zA-Z0-9_]
From 5266417620ec620dd045e253e0f7aaa8591a2a59 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 4 Nov 2025 10:02:48 +0000
Subject: [PATCH 4/7] Update JavaDoc to reflect current validation approach
Co-authored-by: zeitlinger <2832627+zeitlinger@users.noreply.github.com>
---
.../io/prometheus/metrics/model/snapshots/PrometheusNaming.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
index 377f0eba1..131670dd1 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
@@ -64,7 +64,7 @@ public class PrometheusNaming {
* Test if a metric name is valid. Rules:
*
*
- * - The name must match {@link #METRIC_NAME_PATTERN}.
+ *
- The name must be valid UTF-8.
*
- The name MUST NOT end with one of the {@link #RESERVED_METRIC_NAME_SUFFIXES}.
*
*
From 490aa6d4b70c885972bd53818121adea0a5c325d Mon Sep 17 00:00:00 2001
From: Gregor Zeitlinger
Date: Tue, 4 Nov 2025 11:30:25 +0100
Subject: [PATCH 5/7] format
Signed-off-by: Gregor Zeitlinger
---
.../model/snapshots/PrometheusNaming.java | 27 +++----------------
1 file changed, 4 insertions(+), 23 deletions(-)
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
index 131670dd1..6d6c7780d 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
@@ -18,25 +18,6 @@
*/
public class PrometheusNaming {
- /**
- * @deprecated Not used anymore. Kept for backward compatibility. The validation is now done
- * without regex for better performance.
- */
- @Deprecated
- @SuppressWarnings("UnusedVariable")
- private static final Pattern METRIC_NAME_PATTERN = Pattern.compile("^[a-zA-Z_:][a-zA-Z0-9_:]*$");
-
- /**
- * Legal characters for label names.
- *
- * @deprecated Not used anymore. Kept for backward compatibility. The validation is now done
- * without regex for better performance.
- */
- @Deprecated
- @SuppressWarnings("UnusedVariable")
- private static final Pattern LEGACY_LABEL_NAME_PATTERN =
- Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*$");
-
/** Legal characters for unit names, including dot. */
private static final Pattern UNIT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_.:]+$");
@@ -64,7 +45,9 @@ public class PrometheusNaming {
* Test if a metric name is valid. Rules:
*
*
- * - The name must be valid UTF-8.
+ *
- The name must match Metric
+ * names.
*
- The name MUST NOT end with one of the {@link #RESERVED_METRIC_NAME_SUFFIXES}.
*
*
@@ -146,9 +129,7 @@ public static boolean isValidLegacyLabelName(String name) {
}
// First character must be [a-zA-Z_]
char first = name.charAt(0);
- if (!((first >= 'a' && first <= 'z')
- || (first >= 'A' && first <= 'Z')
- || first == '_')) {
+ if (!((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z') || first == '_')) {
return false;
}
// Remaining characters must be [a-zA-Z0-9_]
From a48d2007efe61181ba7826c6273f421261d813f8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 4 Nov 2025 11:57:05 +0000
Subject: [PATCH 6/7] Replace UNIT_NAME_PATTERN with manual check for
consistency
Co-authored-by: zeitlinger <2832627+zeitlinger@users.noreply.github.com>
---
.../model/snapshots/PrometheusNaming.java | 24 +++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
index 6d6c7780d..3de144ec2 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
@@ -18,7 +18,14 @@
*/
public class PrometheusNaming {
- /** Legal characters for unit names, including dot. */
+ /**
+ * Legal characters for unit names, including dot.
+ *
+ * @deprecated Not used anymore. Kept for backward compatibility. The validation is now done
+ * without regex for better performance.
+ */
+ @Deprecated
+ @SuppressWarnings("UnusedVariable")
private static final Pattern UNIT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_.:]+$");
/**
@@ -165,8 +172,17 @@ public static String validateUnitName(String name) {
return suffixName + " is a reserved suffix in Prometheus";
}
}
- if (!UNIT_NAME_PATTERN.matcher(name).matches()) {
- return "The unit name contains unsupported characters";
+ // Check if all characters are [a-zA-Z0-9_.:]+
+ for (int i = 0; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if (!((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9')
+ || c == '_'
+ || c == '.'
+ || c == ':')) {
+ return "The unit name contains unsupported characters";
+ }
}
return null;
}
@@ -282,7 +298,7 @@ public static String sanitizeUnitName(String unitName) {
return sanitizedName;
}
- /** Returns a string that matches {@link #UNIT_NAME_PATTERN}. */
+ /** Returns a string with only valid unit name characters [a-zA-Z0-9_.:]. */
private static String replaceIllegalCharsInUnitName(String name) {
int length = name.length();
char[] sanitized = new char[length];
From 5d52ebf97b91a4bb67dda48f77af28f4f64c2c3a Mon Sep 17 00:00:00 2001
From: Gregor Zeitlinger
Date: Tue, 4 Nov 2025 13:01:54 +0100
Subject: [PATCH 7/7] format
Signed-off-by: Gregor Zeitlinger
---
.../metrics/model/snapshots/PrometheusNaming.java | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
index 3de144ec2..71de5d0b4 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java
@@ -6,7 +6,6 @@
import io.prometheus.metrics.config.EscapingScheme;
import java.nio.charset.StandardCharsets;
-import java.util.regex.Pattern;
import javax.annotation.Nullable;
/**
@@ -18,16 +17,6 @@
*/
public class PrometheusNaming {
- /**
- * Legal characters for unit names, including dot.
- *
- * @deprecated Not used anymore. Kept for backward compatibility. The validation is now done
- * without regex for better performance.
- */
- @Deprecated
- @SuppressWarnings("UnusedVariable")
- private static final Pattern UNIT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_.:]+$");
-
/**
* According to OpenMetrics {@code _count} and {@code _sum} (and {@code _gcount}, {@code _gsum})
* should also be reserved metric name suffixes. However, popular instrumentation libraries have