diff --git a/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/MetricsStore.cs b/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/MetricsStore.cs index 5d3b01425cd..acb0ca8bebe 100644 --- a/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/MetricsStore.cs +++ b/src/Microsoft.Diagnostics.Monitoring.WebApi/Metrics/MetricsStore.cs @@ -202,6 +202,7 @@ private static string GetMetricType(EventType eventType) { // In Prometheus, rates are treated as gauges due to their non-monotonic nature case EventType.Rate: + case EventType.UpDownCounter: case EventType.Gauge: return "gauge"; case EventType.Histogram: diff --git a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/MetricsFormattingTests.cs b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/MetricsFormattingTests.cs index ae4712896c1..532f9596567 100644 --- a/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/MetricsFormattingTests.cs +++ b/src/Tests/Microsoft.Diagnostics.Monitoring.Tool.UnitTests/MetricsFormattingTests.cs @@ -49,8 +49,6 @@ public async Task HistogramFormat_Test() using MemoryStream stream = await GetMetrics(payload); List lines = ReadStream(stream); - // Question - this is manually recreating what PrometheusDataModel.GetPrometheusNormalizedName does to get the metric name; - // should we call this method, or should this also be implicitly testing its behavior by having this hard-coded? string metricName = $"{MeterName.ToLowerInvariant()}_{payload[0].Name}"; const string quantile_50 = "{quantile=\"0.5\"}"; @@ -74,8 +72,6 @@ public async Task GaugeFormat_Test() List lines = ReadStream(stream); - // Question - this is manually recreating what PrometheusDataModel.GetPrometheusNormalizedName does to get the metric name; - // should we call this method, or should this also be implicitly testing its behavior by having this hard-coded? string metricName = $"{MeterName.ToLowerInvariant()}_{payload.Name}"; Assert.Equal(3, lines.Count); @@ -93,8 +89,6 @@ public async Task CounterFormat_Test() List lines = ReadStream(stream); - // Question - this is manually recreating what PrometheusDataModel.GetPrometheusNormalizedName does to get the metric name; - // should we call this method, or should this also be implicitly testing its behavior by having this hard-coded? string metricName = $"{MeterName.ToLowerInvariant()}_{payload.Name}"; Assert.Equal(3, lines.Count); @@ -103,6 +97,23 @@ public async Task CounterFormat_Test() Assert.Equal($"{metricName} {payload.Value} {new DateTimeOffset(payload.Timestamp).ToUnixTimeMilliseconds()}", lines[2]); } + [Fact] + public async Task UpDownCounterFormat_Test() + { + ICounterPayload payload = new UpDownCounterPayload(MeterName, InstrumentName, "DisplayName", "", null, Value1, Timestamp); + + MemoryStream stream = await GetMetrics(new() { payload }); + + List lines = ReadStream(stream); + + string metricName = $"{MeterName.ToLowerInvariant()}_{payload.Name}"; + + Assert.Equal(3, lines.Count); + Assert.Equal(FormattableString.Invariant($"# HELP {metricName}{payload.Unit} {payload.DisplayName}"), lines[0]); + Assert.Equal(FormattableString.Invariant($"# TYPE {metricName} gauge"), lines[1]); + Assert.Equal(FormattableString.Invariant($"{metricName} {payload.Value} {new DateTimeOffset(payload.Timestamp).ToUnixTimeMilliseconds()}"), lines[2]); + } + private async Task GetMetrics(List payloads) { IMetricsStore metricsStore = new MetricsStore(_logger, MetricCount);