From 5c324314fb2220fbcff9fe31c8571722f782cc65 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Wed, 1 Apr 2026 15:35:10 -0700 Subject: [PATCH 01/13] sanitize the unit to remove unallowed characters, add and fix tests --- .../Internal/PrometheusMetric.cs | 36 ++++++++++++++- .../PrometheusMetricTests.cs | 44 ++++++++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index df1632ca467..de442fa3573 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -77,6 +77,40 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa public static PrometheusMetric Create(Metric metric, bool disableTotalNameSuffixForCounters) => new(metric.Name, metric.Unit, GetPrometheusType(metric.MetricType), disableTotalNameSuffixForCounters); + internal static string SanitizeMetricUnit(string metricUnit) + { + StringBuilder? sb = null; + var lastCharUnderscore = false; + + for (var i = 0; i < metricUnit.Length; i++) + { + var c = metricUnit[i]; + + if (!char.IsLetterOrDigit(c) && c != ':') + { + if (!lastCharUnderscore) + { + lastCharUnderscore = true; + sb ??= CreateStringBuilder(metricUnit); + sb.Append('_'); + } + } + else + { + sb ??= CreateStringBuilder(metricUnit); + sb.Append(c); + lastCharUnderscore = false; + } + } + + return sb?.ToString() ?? metricUnit; + + static StringBuilder CreateStringBuilder(string unit) + { + return new(unit.Length); + } + } + internal static string SanitizeMetricName(string metricName) { StringBuilder? sb = null; @@ -208,7 +242,7 @@ private static string GetUnit(string unit) updatedUnit = MapUnit(updatedUnit.AsSpan()); } - return updatedUnit; + return SanitizeMetricUnit(updatedUnit); } private static bool TryProcessRateUnits(string updatedUnit, [NotNullWhen(true)] out string? updatedPerUnit) diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs index 5e8856f4843..529f1508dd3 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs @@ -361,7 +361,43 @@ public void GetPrometheusType_HistogramVariants_ReturnsHistogram(int metricTypeV [Fact] public void Name_MultipleSlashesInUnit_FirstSlashProcessed() - => AssertName("metric", "req/s/extra", PrometheusType.Gauge, false, "metric_req_per_s/extra"); // // Multiple slashes + => AssertName("metric", "req/s/extra", PrometheusType.Gauge, false, "metric_req_per_s_extra"); // // Multiple slashes + + [Fact] + public void SanitizeMetricUnit_Valid() + => AssertSanitizeMetricUnit("requests", "requests"); + + [Fact] + public void SanitizeMetricUnit_RemoveConsecutiveUnderscores() + => AssertSanitizeMetricUnit("req__per__s", "req_per_s"); + + [Fact] + public void SanitizeMetricUnit_RemoveUnsupportedCharacters() + => AssertSanitizeMetricUnit("# RU", "_RU"); + + [Fact] + public void SanitizeMetricUnit_RemoveWhitespace() + => AssertSanitizeMetricUnit("req s", "req_s"); + + [Fact] + public void SanitizeMetricUnit_LeadingNumberAllowed() + => AssertSanitizeMetricUnit("2", "2"); + + [Fact] + public void SanitizeMetricUnit_RemoveMultipleUnsupportedCharacters() + => AssertSanitizeMetricUnit("##/RU!", "_RU_"); + + [Fact] + public void Name_UnitWithHash_Sanitized() + => AssertName("azure_cosmosdb_client_operation_request_charge", "# RU", PrometheusType.Histogram, false, "azure_cosmosdb_client_operation_request_charge__RU"); + + [Fact] + public void Name_UnitWithSpace_Sanitized() + => AssertName("metric", "req s", PrometheusType.Gauge, false, "metric_req_s"); + + [Fact] + public void Name_UnitWithSpecialChars_Sanitized() + => AssertName("metric", "req!", PrometheusType.Gauge, false, "metric_req_"); [Theory] [InlineData(PrometheusType.Counter)] @@ -375,6 +411,12 @@ internal void Constructor_AllPrometheusTypes_Work(PrometheusType type) Assert.Equal(type, metric.Type); } + private static void AssertSanitizeMetricUnit(string unit, string expected) + { + var sanitizedUnit = PrometheusMetric.SanitizeMetricUnit(unit); + Assert.Equal(expected, sanitizedUnit); + } + private static void AssertName( string name, string unit, PrometheusType type, bool disableTotalNameSuffixForCounters, string expected) { From 10ce15cb028ea709f8b992ac2dbf086e8f909908 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Wed, 1 Apr 2026 17:38:24 -0700 Subject: [PATCH 02/13] [OTLP/6187] static string builder needs to be re-used now --- .../Internal/PrometheusMetric.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index de442fa3573..a79b2d355c3 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -77,6 +77,11 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa public static PrometheusMetric Create(Metric metric, bool disableTotalNameSuffixForCounters) => new(metric.Name, metric.Unit, GetPrometheusType(metric.MetricType), disableTotalNameSuffixForCounters); + internal static StringBuilder CreateStringBuilder(string unit) + { + return new(unit.Length); + } + internal static string SanitizeMetricUnit(string metricUnit) { StringBuilder? sb = null; @@ -104,11 +109,6 @@ internal static string SanitizeMetricUnit(string metricUnit) } return sb?.ToString() ?? metricUnit; - - static StringBuilder CreateStringBuilder(string unit) - { - return new(unit.Length); - } } internal static string SanitizeMetricName(string metricName) @@ -146,11 +146,6 @@ internal static string SanitizeMetricName(string metricName) } return sb?.ToString() ?? metricName; - - static StringBuilder CreateStringBuilder(string name) - { - return new(name.Length); - } } internal static string RemoveAnnotations(string unit) From 78727a1f77119507e1bafb9edbba92418024dae3 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Wed, 1 Apr 2026 17:46:52 -0700 Subject: [PATCH 03/13] [OTLP/6187] Changelog updated, test case more clear --- .../CHANGELOG.md | 5 +++++ .../PrometheusMetricTests.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index b235ebff524..8f5925f024d 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -7,6 +7,11 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Fixed metric unit strings containing invalid Prometheus characters (e.g. `# RU`) + not being sanitized, resulting in malformed metric names + ([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6187)) + + ## 1.15.0-beta.1 Released 2026-Jan-21 diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs index 529f1508dd3..a14c2d585b8 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs @@ -381,7 +381,7 @@ public void SanitizeMetricUnit_RemoveWhitespace() [Fact] public void SanitizeMetricUnit_LeadingNumberAllowed() - => AssertSanitizeMetricUnit("2", "2"); + => AssertSanitizeMetricUnit("2_unitname", "2_unitname"); [Fact] public void SanitizeMetricUnit_RemoveMultipleUnsupportedCharacters() From aa6acce8f548a78c15404629944e5f35345ccbcb Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Thu, 9 Apr 2026 11:16:17 -0700 Subject: [PATCH 04/13] Changelog entry for all required packages --- src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 8e5165632ee..319bca710f1 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -7,6 +7,10 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* Fixed metric unit strings containing invalid Prometheus characters (e.g. `# RU`) + not being sanitized, resulting in malformed metric names + ([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6187)) + ## 1.15.1-beta.1 Released 2026-Mar-27 From aed8d7b7ba7ffe31982afa6845be097255ed7ec5 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Thu, 9 Apr 2026 11:18:50 -0700 Subject: [PATCH 05/13] lint --- src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | 2 +- src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 032aff308bb..649995252a7 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -10,7 +10,7 @@ Notes](../../RELEASENOTES.md). * Fixed metric unit strings containing invalid Prometheus characters (e.g. `# RU`) not being sanitized, resulting in malformed metric names ([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6187)) - + ## 1.15.2-beta.1 Released 2026-Apr-08 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 0acfc067f12..9e429d2e872 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -10,7 +10,7 @@ Notes](../../RELEASENOTES.md). * Fixed metric unit strings containing invalid Prometheus characters (e.g. `# RU`) not being sanitized, resulting in malformed metric names ([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6187)) - + ## 1.15.2-beta.1 Released 2026-Apr-08 From 46d0463c9c216316f31980fc315cecdddd5087dd Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Thu, 9 Apr 2026 11:21:28 -0700 Subject: [PATCH 06/13] Apply suggestion from @martincostello Co-authored-by: Martin Costello --- src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 9e429d2e872..1c19651dc39 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -8,7 +8,7 @@ Notes](../../RELEASENOTES.md). ## Unreleased * Fixed metric unit strings containing invalid Prometheus characters (e.g. `# RU`) - not being sanitized, resulting in malformed metric names + not being sanitized, resulting in malformed metric names. ([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6187)) ## 1.15.2-beta.1 From 796411739321357d5ad0372077d0bbcd0938eef1 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Fri, 10 Apr 2026 10:53:39 -0700 Subject: [PATCH 07/13] Update src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 649995252a7..b89aadb1915 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -8,7 +8,7 @@ Notes](../../RELEASENOTES.md). ## Unreleased * Fixed metric unit strings containing invalid Prometheus characters (e.g. `# RU`) - not being sanitized, resulting in malformed metric names + not being sanitized, resulting in malformed metric names. ([#6187](https://github.com/open-telemetry/opentelemetry-dotnet/issues/6187)) ## 1.15.2-beta.1 From 85867eea4b8ebcd5c81092e8d107885a75610995 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Fri, 10 Apr 2026 11:39:57 -0700 Subject: [PATCH 08/13] remove underscore at index 0 in unit if exists and remove extra SB allocation --- .../Internal/PrometheusMetric.cs | 14 ++++++++++---- .../PrometheusMetricTests.cs | 6 +++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index a79b2d355c3..3a0bbf347fb 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -96,19 +96,25 @@ internal static string SanitizeMetricUnit(string metricUnit) if (!lastCharUnderscore) { lastCharUnderscore = true; - sb ??= CreateStringBuilder(metricUnit); + sb ??= new StringBuilder(metricUnit, 0, i, metricUnit.Length); sb.Append('_'); } } else { - sb ??= CreateStringBuilder(metricUnit); - sb.Append(c); + if (sb != null) + { + sb.Append(c); + } lastCharUnderscore = false; } } - return sb?.ToString() ?? metricUnit; + var result = sb?.ToString() ?? metricUnit; + + return result.Length > 0 && result[0] == '_' + ? result.Substring(1) + : result; } internal static string SanitizeMetricName(string metricName) diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs index a14c2d585b8..3a9d177ec2d 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs @@ -373,7 +373,7 @@ public void SanitizeMetricUnit_RemoveConsecutiveUnderscores() [Fact] public void SanitizeMetricUnit_RemoveUnsupportedCharacters() - => AssertSanitizeMetricUnit("# RU", "_RU"); + => AssertSanitizeMetricUnit("# RU", "RU"); [Fact] public void SanitizeMetricUnit_RemoveWhitespace() @@ -385,11 +385,11 @@ public void SanitizeMetricUnit_LeadingNumberAllowed() [Fact] public void SanitizeMetricUnit_RemoveMultipleUnsupportedCharacters() - => AssertSanitizeMetricUnit("##/RU!", "_RU_"); + => AssertSanitizeMetricUnit("##/RU!", "RU_"); [Fact] public void Name_UnitWithHash_Sanitized() - => AssertName("azure_cosmosdb_client_operation_request_charge", "# RU", PrometheusType.Histogram, false, "azure_cosmosdb_client_operation_request_charge__RU"); + => AssertName("azure_cosmosdb_client_operation_request_charge", "# RU", PrometheusType.Histogram, false, "azure_cosmosdb_client_operation_request_charge_RU"); [Fact] public void Name_UnitWithSpace_Sanitized() From 1893ea940d57bc38bacb735ae8b11188d25cc155 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Fri, 10 Apr 2026 11:40:52 -0700 Subject: [PATCH 09/13] Update src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Internal/PrometheusMetric.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index 3a0bbf347fb..ac45d85420d 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -77,9 +77,9 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa public static PrometheusMetric Create(Metric metric, bool disableTotalNameSuffixForCounters) => new(metric.Name, metric.Unit, GetPrometheusType(metric.MetricType), disableTotalNameSuffixForCounters); - internal static StringBuilder CreateStringBuilder(string unit) + private static StringBuilder CreateStringBuilder(string value) { - return new(unit.Length); + return new(value.Length); } internal static string SanitizeMetricUnit(string metricUnit) From 02cb3eeaecfd2c60144b9c77d6a84a96816100bf Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Fri, 10 Apr 2026 11:45:05 -0700 Subject: [PATCH 10/13] internal members before private members --- .../Internal/PrometheusMetric.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index ac45d85420d..c743824c4df 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -77,11 +77,6 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa public static PrometheusMetric Create(Metric metric, bool disableTotalNameSuffixForCounters) => new(metric.Name, metric.Unit, GetPrometheusType(metric.MetricType), disableTotalNameSuffixForCounters); - private static StringBuilder CreateStringBuilder(string value) - { - return new(value.Length); - } - internal static string SanitizeMetricUnit(string metricUnit) { StringBuilder? sb = null; @@ -221,6 +216,11 @@ UpDownCounter becomes gauge }; } + private static StringBuilder CreateStringBuilder(string value) + { + return new(value.Length); + } + private static string SanitizeOpenMetricsName(string metricName) => metricName.EndsWith("_total", StringComparison.Ordinal) ? metricName.Substring(0, metricName.Length - 6) : metricName; From 0a05c63e3ee4064f2675928a39bbfb13637a15a2 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Fri, 10 Apr 2026 12:39:15 -0700 Subject: [PATCH 11/13] lint issues --- .../Internal/PrometheusMetric.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index c743824c4df..263f6b8c734 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -101,6 +101,7 @@ internal static string SanitizeMetricUnit(string metricUnit) { sb.Append(c); } + lastCharUnderscore = false; } } From 25ac46dde81bf63597da539e1462a0e4f199be1d Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Fri, 10 Apr 2026 12:41:59 -0700 Subject: [PATCH 12/13] Update src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs Co-authored-by: Martin Costello --- .../Internal/PrometheusMetric.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index 263f6b8c734..8628b3077fa 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -109,8 +109,8 @@ internal static string SanitizeMetricUnit(string metricUnit) var result = sb?.ToString() ?? metricUnit; return result.Length > 0 && result[0] == '_' - ? result.Substring(1) - : result; + ? result.Substring(1) + : result; } internal static string SanitizeMetricName(string metricName) From b73103f7674136656938b805def5f9f9db90f4d6 Mon Sep 17 00:00:00 2001 From: Navya Sharma Date: Mon, 13 Apr 2026 15:39:49 -0700 Subject: [PATCH 13/13] Remove trailing underscores Co-authored-by: @Nik-Reddy --- .../Internal/PrometheusMetric.cs | 5 +---- .../PrometheusMetricTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs index 8628b3077fa..73665c7a75a 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs @@ -107,10 +107,7 @@ internal static string SanitizeMetricUnit(string metricUnit) } var result = sb?.ToString() ?? metricUnit; - - return result.Length > 0 && result[0] == '_' - ? result.Substring(1) - : result; + return result.Trim('_'); } internal static string SanitizeMetricName(string metricName) diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs index 3a9d177ec2d..785253c25a2 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs @@ -385,7 +385,7 @@ public void SanitizeMetricUnit_LeadingNumberAllowed() [Fact] public void SanitizeMetricUnit_RemoveMultipleUnsupportedCharacters() - => AssertSanitizeMetricUnit("##/RU!", "RU_"); + => AssertSanitizeMetricUnit("##/RU!", "RU"); [Fact] public void Name_UnitWithHash_Sanitized() @@ -397,7 +397,7 @@ public void Name_UnitWithSpace_Sanitized() [Fact] public void Name_UnitWithSpecialChars_Sanitized() - => AssertName("metric", "req!", PrometheusType.Gauge, false, "metric_req_"); + => AssertName("metric", "req!", PrometheusType.Gauge, false, "metric_req"); [Theory] [InlineData(PrometheusType.Counter)]