Skip to content

Commit

Permalink
use targeted exception time for missing dimension + add basic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hkfgo committed Jul 14, 2023
1 parent b0f687b commit 00feaf6
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 3 deletions.
2 changes: 1 addition & 1 deletion changelog/content/experimental/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ version:

#### Scraper

- {{% tag fixed %}} Improve handling of time series with missing dimensions that are requested ([#2331](https:/tomkerkhove/promitor/issues/2331))
- {{% tag changed %}} Switch to Mariner distroless base images
- {{% tag security %}} Patch for [CVE-2023-29331](https:/advisories/GHSA-555c-2p6r-68mm) (High)
- {{% tag fixed %}} Better handle time series missing requested dimension in AzureMonitorClient [#2331](https:/tomkerkhove/promitor/issues/2331))

#### Resource Discovery

Expand Down
24 changes: 24 additions & 0 deletions src/Promitor.Core/Metrics/Exceptions/MissingDimensionException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using GuardNet;

namespace Promitor.Core.Metrics.Exceptions
{
public class MissingDimensionException : Exception
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="metricName">Name of the dimension</param>
public MissingDimensionException(string dimensionName) : base($"No value found for dimension '{dimensionName}'")
{
Guard.NotNullOrWhitespace(dimensionName, nameof(dimensionName));

DimensionName = dimensionName;
}

/// <summary>
/// Name of the dimension
/// </summary>
public string DimensionName { get; }
}
}
6 changes: 5 additions & 1 deletion src/Promitor.Core/Metrics/MeasuredMetric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using GuardNet;
using Microsoft.Azure.Management.Monitor.Fluent.Models;
using Promitor.Core.Metrics.Exceptions;

namespace Promitor.Core.Metrics
{
Expand Down Expand Up @@ -65,7 +66,10 @@ public static MeasuredMetric CreateForDimension(double? value, string dimensionN
Guard.NotNull(timeseries, nameof(timeseries));

var dimensionMetadataValue = timeseries.Metadatavalues.Where(metadataValue => metadataValue.Name?.Value.Equals(dimensionName, StringComparison.InvariantCultureIgnoreCase) == true);
Guard.For<ArgumentException>(() => dimensionMetadataValue.Count() == 0);
if(!dimensionMetadataValue.Any())
{
throw new MissingDimensionException(dimensionName);
}

var dimensionValue = dimensionMetadataValue.First();
return CreateForDimension(value, dimensionName, dimensionValue.Value);
Expand Down
3 changes: 2 additions & 1 deletion src/Promitor.Integrations.AzureMonitor/AzureMonitorClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using Promitor.Integrations.AzureMonitor.Logging;
using Promitor.Integrations.AzureMonitor.RequestHandlers;
using Promitor.Integrations.Azure.Authentication;
using Promitor.Core.Metrics.Exceptions;

namespace Promitor.Integrations.AzureMonitor
{
Expand Down Expand Up @@ -114,7 +115,7 @@ public async Task<List<MeasuredMetric>> QueryMetricAsync(string metricName, stri
var measuredMetric = string.IsNullOrWhiteSpace(metricDimension) ? MeasuredMetric.CreateWithoutDimension(requestedMetricAggregate) : MeasuredMetric.CreateForDimension(requestedMetricAggregate, metricDimension, timeseries);
measuredMetrics.Add(measuredMetric);
}
catch (ArgumentException)
catch (MissingDimensionException)
{
_logger.LogWarning("{MetricName} has return a time series with empty value for {Dimension} and the measurements will be dropped", metricName, metricDimension);
_logger.LogDebug("The violating time series has content {TimeSeriesJson}}", JsonConvert.SerializeObject(timeseries));
Expand Down
35 changes: 35 additions & 0 deletions src/Promitor.Tests.Unit/Metrics/MeasuredMetricTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.ComponentModel;
using Promitor.Core.Metrics;
using Microsoft.Azure.Management.Monitor.Fluent.Models;
using Xunit;
using Promitor.Core.Metrics.Exceptions;

namespace Promitor.Tests.Unit.Metrics
{
[Category("Unit")]
public class MeasuredMeticTest : UnitTest
{
[Fact]
public void Create_MeasuredMetric_With_Dimension_HappyPath_Succeeds()
{
var dimensionName = "dimTest";
var dimensionValue = "dimTest1";
var timeSeries = new TimeSeriesElement(new List<MetadataValue> { new(name: new LocalizableString(dimensionName), value: dimensionValue)});
var measuredMetric = MeasuredMetric.CreateForDimension(1, dimensionName, timeSeries);
Assert.Equal(measuredMetric.DimensionName, dimensionName);
Assert.Equal(measuredMetric.DimensionValue, dimensionValue);
Assert.Equal(measuredMetric.Value, 1);
}

[Fact]
public void Create_MeasuredMetric_Missing_Dimension_Throws_Targeted_Exception()
{
var dimensionName = "dimTest";
var timeSeries = new TimeSeriesElement(new List<MetadataValue> {});
MissingDimensionException ex = Assert.Throws<MissingDimensionException>(() => MeasuredMetric.CreateForDimension(1, dimensionName, timeSeries));
Assert.Equal(ex.DimensionName, dimensionName)
}
}

}

0 comments on commit 00feaf6

Please sign in to comment.