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: * * * 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: * * * @@ -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