Skip to content

Commit

Permalink
Fix: prevent duplicate dimensions (awslabs#32)
Browse files Browse the repository at this point in the history
* fix: prevent duplicate dimensions

Co-authored-by: Mark Kuhn <[email protected]>
  • Loading branch information
markkuhn and Mark Kuhn authored Aug 17, 2022
1 parent 2b07c2d commit 709654b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
19 changes: 19 additions & 0 deletions src/Amazon.CloudWatch.EMF/Model/MetricDirective.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,25 @@ internal List<List<string>> AllDimensionKeys
}
}

internal void PutDimension(DimensionSet dimensionSet)
{
// Duplicate dimensions sets are removed before being added to the end of the collection.
// This ensures the latest dimension key-value is used as a target member on the root EMF node.
// This operation is O(n^2), but acceptable given sets are capped at 30 dimensions
List<string> incomingDimensionSetKeys = dimensionSet.DimensionKeys;
CustomDimensionSets = CustomDimensionSets.Where(existingDimensionSet =>
{
if (existingDimensionSet.DimensionKeys.Count != incomingDimensionSetKeys.Count)
{
return true;
}
return !existingDimensionSet.DimensionKeys.All(existingDimensionSetKey => incomingDimensionSetKeys.Contains(existingDimensionSetKey));
}).ToList();

CustomDimensionSets.Add(dimensionSet);
}

/// <summary>
/// Overrides all existing dimensions, including suppressing any default dimensions.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Amazon.CloudWatch.EMF/Model/MetricsContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public object GetProperty(string name)
/// <param name="dimensionSet">the dimensions set to add.</param>
public void PutDimension(DimensionSet dimensionSet)
{
_metricDirective.CustomDimensionSets.Add(dimensionSet);
_metricDirective.PutDimension(dimensionSet);
}

/// <summary>
Expand All @@ -166,7 +166,7 @@ public void PutDimension(string dimension, string value)
{
var dimensionSet = new DimensionSet();
dimensionSet.AddDimension(dimension, value);
_metricDirective.CustomDimensionSets.Add(dimensionSet);
_metricDirective.PutDimension(dimensionSet);
}

/// <summary>
Expand Down
44 changes: 44 additions & 0 deletions tests/Amazon.CloudWatch.EMF.Tests/Logger/MetricsLoggerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,50 @@ public void TestOverridePreviousDimensions()
Assert.Equal(dimensionValue, _sink.MetricsContext.GetAllDimensionSets()[0].GetDimensionValue(dimensionName));
}

[Fact]
public void TestPutDuplicateDimensions()
{
string dimensionName1 = "dim1";
string dimensionName2 = "dim2";
string dimensionValue1 = "dimValue1";
string dimensionValue2 = "dimValue2";
string dimensionValue3 = "dimValue3";
string dimensionValue4 = "dimValue4";

_metricsLogger.PutDimensions(new DimensionSet(dimensionName1, dimensionValue1));
_metricsLogger.PutDimensions(new DimensionSet(dimensionName2, dimensionValue2));
_metricsLogger.PutDimensions(new DimensionSet(dimensionName1, dimensionValue3));
_metricsLogger.PutDimensions(new DimensionSet(dimensionName2, dimensionValue4));
_metricsLogger.Flush();

Assert.Equal(4, _sink.MetricsContext.GetAllDimensionSets()[0].DimensionKeys.Count);
Assert.Equal(dimensionValue3, _sink.MetricsContext.GetAllDimensionSets()[0].GetDimensionValue(dimensionName1));
Assert.Equal(dimensionValue4, _sink.MetricsContext.GetAllDimensionSets()[0].GetDimensionValue(dimensionName2));
}

[Fact]
public void TestSetPutDuplicateDimensions()
{
string dimensionName1 = "dim1";
string dimensionName2 = "dim2";
string dimensionName3 = "dim3";
string dimensionValue1 = "dimValue1";
string dimensionValue2 = "dimValue2";
string dimensionValue3 = "dimValue3";
string dimensionValue4 = "dimValue4";

_metricsLogger.PutDimensions(new DimensionSet(dimensionName1, dimensionValue1));
_metricsLogger.SetDimensions(new DimensionSet(dimensionName2, dimensionValue1));
_metricsLogger.PutDimensions(new DimensionSet(dimensionName3, dimensionValue2));
_metricsLogger.PutDimensions(new DimensionSet(dimensionName2, dimensionValue3));
_metricsLogger.PutDimensions(new DimensionSet(dimensionName3, dimensionValue4));
_metricsLogger.Flush();

Assert.Equal(2, _sink.MetricsContext.GetAllDimensionSets().Count);
Assert.Equal(dimensionValue3, _sink.MetricsContext.GetAllDimensionSets()[0].GetDimensionValue(dimensionName2));
Assert.Equal(dimensionValue4, _sink.MetricsContext.GetAllDimensionSets()[1].GetDimensionValue(dimensionName3));
}

[Fact]
public void TestSetNameSpace()
{
Expand Down

0 comments on commit 709654b

Please sign in to comment.