awslabs / aws-embedded-metrics-dotnet

Amazon CloudWatch Embedded Metric Format Client Library
Apache License 2.0
22 stars 14 forks source link

Disallow duplicate dimension sets #31

Closed markkuhn closed 2 years ago

markkuhn commented 2 years ago

Related issues:

Currently duplicate dimension set are being allowed: Example:

var ds1 = new DimensionSet();
ds1.AddDimension("Region", "us-west-1");
var ds2 = new DimensionSet();
ds2.AddDimension("Region", "us-west-2");

metrics.SetDimensions(ds1);
metrics.PutDimensions(ds2);

metrics.PutMetric("Metric1", 1.0);
metrics.Flush();

This creates

{
  "_aws": {
    "Timestamp": 1660330702000,
    "CloudWatchMetrics": [
      {
        "Namespace": "aws-embedded-metrics",
        "Metrics": [
          {
            "Name": "Metric1",
            "Unit": "None"
          }
        ],
        "Dimensions": [
          [
            "Region"
          ],
          [
            "Region"
          ]
        ]
      }
    ],
    "LogGroupName": "DemoApp"
  },
  "Region": "us-west-1",
  "LogGroupName": "DemoApp",
  "Metric1": 1
}

Instead of:


{
  "_aws": {
    "Timestamp": 1660330702000,
    "CloudWatchMetrics": [
      {
        "Namespace": "aws-embedded-metrics",
        "Metrics": [
          {
            "Name": "Metric1",
            "Unit": "None"
          }
        ],
        "Dimensions": [
          [
            "Region"
          ]
        ]
      }
    ],
    "LogGroupName": "DemoApp"
  },
  "Region": "us-west-2",
  "LogGroupName": "DemoApp",
  "Metric1": 1
}
gordonpn commented 2 years ago

Ran two tests:

Test 1:

private static void EmitMetric(ILogger logger, IMetricsLogger metrics)
{

    var ds1 = new DimensionSet();
    ds1.AddDimension("D1", "d1.1");
    var ds2 = new DimensionSet();
    ds2.AddDimension("D1", "d1.2");

    var ds3 = new DimensionSet();
    ds3.AddDimension("D3", "d3.1");
    ds3.AddDimension("D4", "d4.1");

    var ds4 = new DimensionSet();
    ds4.AddDimension("D3", "d3.2");
    ds4.AddDimension("D4", "d4.2");

    metrics.PutDimensions(ds1); // only this line is different
    metrics.PutDimensions(ds2);
    metrics.PutDimensions(ds3);
    metrics.PutDimensions(ds4);

    metrics.PutMetric("Metric1", 1.0);

    metrics.Flush();
}

Test 2:

private static void EmitMetric(ILogger logger, IMetricsLogger metrics)
{

    var ds1 = new DimensionSet();
    ds1.AddDimension("D1", "d1.1");
    var ds2 = new DimensionSet();
    ds2.AddDimension("D1", "d1.2");

    var ds3 = new DimensionSet();
    ds3.AddDimension("D3", "d3.1");
    ds3.AddDimension("D4", "d4.1");

    var ds4 = new DimensionSet();
    ds4.AddDimension("D3", "d3.2");
    ds4.AddDimension("D4", "d4.2");

    metrics.SetDimensions(ds1); // only this line is different
    metrics.PutDimensions(ds2);
    metrics.PutDimensions(ds3);
    metrics.PutDimensions(ds4);

    metrics.PutMetric("Metric1", 1.0);

    metrics.Flush();
}

Output of test 1:

{
  "_aws": {
    "Timestamp": 1660331033988,
    "CloudWatchMetrics": [
      {
        "Namespace": "aws-embedded-metrics",
        "Metrics": [
          {
            "Name": "Metric1",
            "Unit": "None"
          }
        ],
        "Dimensions": [
          [
            "ServiceName",
            "ServiceType",
            "D1",
            "D3",
            "D4"
          ]
        ]
      }
    ],
    "LogGroupName": "DemoApp"
  },
  "ServiceName": "DemoApp",
  "ServiceType": "ConsoleApp",
  "D1": "d1.2",
  "D3": "d3.2",
  "D4": "d4.2",
  "LogGroupName": "DemoApp",
  "Metric1": 1
}

Output of test 2:

{
  "_aws": {
    "Timestamp": 1660331043355,
    "CloudWatchMetrics": [
      {
        "Namespace": "aws-embedded-metrics",
        "Metrics": [
          {
            "Name": "Metric1",
            "Unit": "None"
          }
        ],
        "Dimensions": [
          [
            "D1"
          ],
          [
            "D1"
          ],
          [
            "D3",
            "D4"
          ],
          [
            "D3",
            "D4"
          ]
        ]
      }
    ],
    "LogGroupName": "DemoApp"
  },
  "D1": "d1.1",
  "D3": "d3.1",
  "D4": "d4.1",
  "LogGroupName": "DemoApp",
  "Metric1": 1
}

It seems like when SetDimensions is called first, there is a bug that allows duplicates and does not record the values of the most recent key inserted.