Skip to content

Commit 2a588a0

Browse files
[Exporter.Prometheus] Address feedback
- Fix escaping behaviour for unit suffixes. - Fix incorrect label escaping for `:`.
1 parent 0f44b44 commit 2a588a0

4 files changed

Lines changed: 16 additions & 11 deletions

File tree

src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa
1717
// consecutive `_` characters MUST be replaced with a single `_` character.
1818
// https://github.com/open-telemetry/opentelemetry-specification/blob/b2f923fb1650dde1f061507908b834035506a796/specification/compatibility/prometheus_and_openmetrics.md#L230-L233
1919
var sanitizedName = SanitizeMetricName(name);
20-
var openMetricsName = EscapeOpenMetricsName(RemoveOpenMetricsCounterNameSuffix(name));
20+
var openMetricsName = RemoveOpenMetricsCounterNameSuffix(name);
2121

2222
string? sanitizedUnit = null;
2323
if (!string.IsNullOrEmpty(unit))
2424
{
2525
sanitizedUnit = GetUnit(unit);
26-
var openMetricsUnitSuffix = EscapeOpenMetricsName(sanitizedUnit);
2726

2827
// The resulting unit SHOULD be added to the metric as
2928
// [OpenMetrics UNIT metadata](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#metricfamily)
@@ -32,10 +31,12 @@ public PrometheusMetric(string name, string unit, PrometheusType type, bool disa
3231
if (!sanitizedName.EndsWith(sanitizedUnit, StringComparison.Ordinal))
3332
{
3433
sanitizedName += $"_{sanitizedUnit}";
35-
openMetricsName += $"_{openMetricsUnitSuffix}";
34+
openMetricsName += $"_{sanitizedUnit}";
3635
}
3736
}
3837

38+
openMetricsName = EscapeOpenMetricsName(openMetricsName);
39+
3940
// If the metric name for monotonic Sum metric points does not end in a suffix of `_total` a suffix of `_total` MUST be added by default, otherwise the name MUST remain unchanged.
4041
// Exporters SHOULD provide a configuration option to disable the addition of `_total` suffixes.
4142
// https://github.com/open-telemetry/opentelemetry-specification/blob/b2f923fb1650dde1f061507908b834035506a796/specification/compatibility/prometheus_and_openmetrics.md#L286

src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,12 @@ public static int WriteTargetInfo(byte[] buffer, int cursor, Resource resource,
527527
}
528528

529529
private static int WritePrometheusLabelKey(byte[] buffer, int cursor, string value)
530-
=> WriteNormalizedLabelKey(buffer, cursor, value, isOpenMetrics: false);
530+
=> WriteNormalizedLabelKey(buffer, cursor, value);
531531

532532
private static int WriteOpenMetricsLabelKey(byte[] buffer, int cursor, string value)
533-
=> WriteNormalizedLabelKey(buffer, cursor, value, isOpenMetrics: true);
533+
=> WriteNormalizedLabelKey(buffer, cursor, value);
534534

535-
private static int WriteNormalizedLabelKey(byte[] buffer, int cursor, string value, bool isOpenMetrics)
535+
private static int WriteNormalizedLabelKey(byte[] buffer, int cursor, string value)
536536
{
537537
var lastCharUnderscore = false;
538538

@@ -549,7 +549,7 @@ private static int WriteNormalizedLabelKey(byte[] buffer, int cursor, string val
549549
}
550550
}
551551

552-
if (!IsAllowedMetricsLabelCharacter(ch, isOpenMetrics))
552+
if (!IsAllowedMetricsLabelCharacter(ch))
553553
{
554554
if (!lastCharUnderscore)
555555
{
@@ -568,8 +568,8 @@ private static int WriteNormalizedLabelKey(byte[] buffer, int cursor, string val
568568
}
569569

570570
[MethodImpl(MethodImplOptions.AggressiveInlining)]
571-
private static bool IsAllowedMetricsLabelCharacter(char value, bool isOpenMetrics) =>
572-
char.IsAsciiLetterOrDigit(value) || value is '_' || (isOpenMetrics && value == ':');
571+
private static bool IsAllowedMetricsLabelCharacter(char value) =>
572+
char.IsAsciiLetterOrDigit(value) || value is '_';
573573

574574
[MethodImpl(MethodImplOptions.AggressiveInlining)]
575575
private static int WriteUnicodeScalar(byte[] buffer, int cursor, string value, ref int index)

test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ public void OpenMetricsName_CollapsesConsecutiveUnderscores()
168168
public void OpenMetricsName_PreserveLeadingNumber()
169169
=> AssertOpenMetricsName("2_metric_name", "By", PrometheusType.Gauge, false, "_2_metric_name_bytes");
170170

171+
[Fact]
172+
public void OpenMetricsName_UnitStartingWithNumber_DoesNotAddExtraSeparator()
173+
=> AssertOpenMetricsName("metric", "2", PrometheusType.Gauge, false, "metric_2");
174+
171175
[Fact]
172176
public void OpenMetricsName_CollapsesConsecutiveUnsupportedCharacters()
173177
=> AssertOpenMetricsName("s%%ple", "%/m", PrometheusType.Summary, false, "s_ple_percent_per_minute");

test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusSerializerTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,13 @@ public void WriteLabelKeyPrefixesLeadingDigits(bool openMetricsRequested)
293293
}
294294

295295
[Fact]
296-
public void WriteLabelKeyPreservesOpenMetricsLegacyValidCharacters()
296+
public void WriteLabelKeyNormalizesOpenMetricsLabelNames()
297297
{
298298
var buffer = new byte[32];
299299

300300
var cursor = PrometheusSerializer.WriteLabelKey(buffer, 0, "a_b:c", openMetricsRequested: true);
301301

302-
Assert.Equal("a_b:c", Encoding.UTF8.GetString(buffer, 0, cursor));
302+
Assert.Equal("a_b_c", Encoding.UTF8.GetString(buffer, 0, cursor));
303303
}
304304

305305
[Fact]

0 commit comments

Comments
 (0)