diff --git a/.gitignore b/.gitignore
index 3e593c9a..a927f64f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@ AWS.Lambda.Powertools.sln.DotSettings.user
[Oo]bj/**
[Bb]in/**
.DS_Store
+.cache
dist/
site/
diff --git a/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs b/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs
index 51b86e37..2ddbc539 100644
--- a/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs
@@ -1,12 +1,12 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
- *
+ *
* http://aws.amazon.com/apache2.0
- *
+ *
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
@@ -31,7 +31,7 @@ public class Metrics : IMetrics, IDisposable
/// The instance
///
private static IMetrics _instance;
-
+
///
/// The context
///
@@ -46,7 +46,7 @@ public class Metrics : IMetrics, IDisposable
/// If true, Powertools for AWS Lambda (.NET) will throw an exception on empty metrics when trying to flush
///
private readonly bool _raiseOnEmptyMetrics;
-
+
///
/// The capture cold start enabled
///
@@ -76,9 +76,8 @@ internal Metrics(IPowertoolsConfigurations powertoolsConfigurations, string name
_raiseOnEmptyMetrics = raiseOnEmptyMetrics;
_captureColdStartEnabled = captureColdStartEnabled;
_context = InitializeContext(nameSpace, service, null);
-
+
_powertoolsConfigurations.SetExecutionEnvironment(this);
-
}
///
@@ -96,9 +95,11 @@ void IMetrics.AddMetric(string key, double value, MetricUnit unit, MetricResolut
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(
- nameof(key), "'AddMetric' method requires a valid metrics key. 'Null' or empty values are not allowed.");
-
- if (value < 0) {
+ nameof(key),
+ "'AddMetric' method requires a valid metrics key. 'Null' or empty values are not allowed.");
+
+ if (value < 0)
+ {
throw new ArgumentException(
"'AddMetric' method requires a valid metrics value. Value must be >= 0.", nameof(value));
}
@@ -106,8 +107,8 @@ void IMetrics.AddMetric(string key, double value, MetricUnit unit, MetricResolut
lock (_lockObj)
{
var metrics = _context.GetMetrics();
-
- if (metrics.Count > 0 &&
+
+ if (metrics.Count > 0 &&
(metrics.Count == PowertoolsConfigurations.MaxMetrics ||
metrics.FirstOrDefault(x => x.Name == key)
?.Values.Count == PowertoolsConfigurations.MaxMetrics))
@@ -134,7 +135,14 @@ void IMetrics.SetNamespace(string nameSpace)
/// Namespace identifier
string IMetrics.GetNamespace()
{
- return _context.GetNamespace();
+ try
+ {
+ return _context.GetNamespace();
+ }
+ catch
+ {
+ return null;
+ }
}
///
@@ -143,7 +151,14 @@ string IMetrics.GetNamespace()
/// System.String.
string IMetrics.GetService()
{
- return _context.GetService();
+ try
+ {
+ return _context.GetService();
+ }
+ catch
+ {
+ return null;
+ }
}
///
@@ -226,7 +241,7 @@ void IMetrics.Flush(bool metricsOverflow)
{
if (!_captureColdStartEnabled)
Console.WriteLine(
- "##WARNING## Metrics and Metadata have not been specified. No data will be sent to Cloudwatch Metrics.");
+ "##User-WARNING## No application metrics to publish. The cold-start metric may be published if enabled. If application metrics should never be empty, consider using 'RaiseOnEmptyMetrics = true'");
}
}
@@ -283,7 +298,7 @@ public void Dispose()
Dispose(true);
GC.SuppressFinalize(this);
}
-
+
///
///
///
@@ -356,7 +371,7 @@ public static void SetDefaultDimensions(Dictionary defaultDimens
{
_instance.SetDefaultDimensions(defaultDimensions);
}
-
+
///
/// Clears both default dimensions and dimensions lists
///
@@ -389,14 +404,14 @@ private void Flush(MetricsContext context)
/// Default dimensions list
/// Metrics resolution
public static void PushSingleMetric(string metricName, double value, MetricUnit unit, string nameSpace = null,
- string service = null, Dictionary defaultDimensions = null, MetricResolution metricResolution = MetricResolution.Default)
+ string service = null, Dictionary defaultDimensions = null,
+ MetricResolution metricResolution = MetricResolution.Default)
{
_instance.PushSingleMetric(metricName, value, unit, nameSpace, service, defaultDimensions, metricResolution);
}
///
- /// Sets global namespace, service name and default dimensions list. Service name is automatically added as a default
- /// dimension
+ /// Sets global namespace, service name and default dimensions list.
///
/// Metrics namespace
/// Service Name
@@ -406,19 +421,26 @@ private MetricsContext InitializeContext(string nameSpace, string service,
Dictionary defaultDimensions)
{
var context = new MetricsContext();
+ var defaultDimensionsList = DictionaryToList(defaultDimensions);
context.SetNamespace(!string.IsNullOrWhiteSpace(nameSpace)
? nameSpace
- : _powertoolsConfigurations.MetricsNamespace);
+ : _instance.GetNamespace() ?? _powertoolsConfigurations.MetricsNamespace);
- context.SetService(!string.IsNullOrWhiteSpace(service)
+ // this needs to check if service is set through code or env variables
+ // the default value service_undefined has to be ignored and return null so it is not added as default
+ // TODO: Check if there is a way to get the default dimensions and if it makes sense
+ var parsedService = !string.IsNullOrWhiteSpace(service)
? service
- : _powertoolsConfigurations.Service);
-
- var defaultDimensionsList = DictionaryToList(defaultDimensions);
+ : _powertoolsConfigurations.Service == "service_undefined"
+ ? null
+ : _powertoolsConfigurations.Service;
- // Add service as a default dimension
- defaultDimensionsList.Add(new DimensionSet("Service", context.GetService()));
+ if (parsedService != null)
+ {
+ context.SetService(parsedService);
+ defaultDimensionsList.Add(new DimensionSet("Service", context.GetService()));
+ }
context.SetDefaultDimensions(defaultDimensionsList);
@@ -447,4 +469,4 @@ internal static void ResetForTest()
{
_instance = null;
}
-}
+}
\ No newline at end of file
diff --git a/libraries/src/AWS.Lambda.Powertools.Metrics/MetricsAttribute.cs b/libraries/src/AWS.Lambda.Powertools.Metrics/MetricsAttribute.cs
index 761bf7bd..0033f560 100644
--- a/libraries/src/AWS.Lambda.Powertools.Metrics/MetricsAttribute.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Metrics/MetricsAttribute.cs
@@ -66,7 +66,7 @@ namespace AWS.Lambda.Powertools.Metrics;
///
/// -
/// Service
-/// string, service name is used for metric dimension across all metrics, by default service_undefined
+/// string, service name is used for metric dimension
///
/// -
/// Namespace
diff --git a/libraries/src/AWS.Lambda.Powertools.Metrics/Model/MetricDirective.cs b/libraries/src/AWS.Lambda.Powertools.Metrics/Model/MetricDirective.cs
index f8ccad76..111f417f 100644
--- a/libraries/src/AWS.Lambda.Powertools.Metrics/Model/MetricDirective.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Metrics/Model/MetricDirective.cs
@@ -105,7 +105,7 @@ private MetricDirective(string nameSpace, List metrics, List
/// All dimension keys.
[JsonPropertyName("Dimensions")]
- public List AllDimensionKeys
+ public List
> AllDimensionKeys
{
get
{
@@ -123,7 +123,8 @@ public List AllDimensionKeys
if (defaultKeys.Count == 0) defaultKeys = new List();
- return defaultKeys;
+ // Wrap the list of strings in another list
+ return new List> { defaultKeys };
}
}
diff --git a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/ClearDimensionsTests.cs b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/ClearDimensionsTests.cs
index 1ac09fbe..0a46d6fd 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/ClearDimensionsTests.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/ClearDimensionsTests.cs
@@ -22,7 +22,7 @@ public void WhenClearAllDimensions_NoDimensionsInOutput()
var metricsOutput = consoleOut.ToString();
// Assert
- Assert.Contains("{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name\",\"Unit\":\"Count\"}],\"Dimensions\":[]", metricsOutput);
+ Assert.Contains("{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name\",\"Unit\":\"Count\"}],\"Dimensions\":[[]]", metricsOutput);
// Reset
MetricsAspect.ResetForTest();
diff --git a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs
index 79c275ae..0be19d3b 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs
@@ -79,12 +79,12 @@ public void WhenMaxMetricsAreAdded_FlushAutomatically()
// flush when it reaches MaxMetrics
Assert.Contains(
- "{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name 1\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 2\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 3\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 4\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 5\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 6\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 7\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 8\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 9\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 10\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 11\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 12\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 13\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 14\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 15\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 16\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 17\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 18\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 19\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 20\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 21\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 22\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 23\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 24\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 25\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 26\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 27\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 28\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 29\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 30\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 31\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 32\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 33\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 34\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 35\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 36\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 37\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 38\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 39\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 40\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 41\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 42\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 43\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 44\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 45\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 46\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 47\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 48\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 49\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 50\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 51\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 52\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 53\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 54\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 55\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 56\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 57\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 58\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 59\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 60\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 61\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 62\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 63\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 64\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 65\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 66\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 67\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 68\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 69\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 70\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 71\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 72\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 73\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 74\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 75\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 76\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 77\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 78\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 79\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 80\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 81\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 82\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 83\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 84\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 85\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 86\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 87\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 88\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 89\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 90\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 91\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 92\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 93\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 94\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 95\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 96\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 97\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 98\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 99\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 100\",\"Unit\":\"Count\"}],\"Dimensions\":[\"Service\"]",
+ "{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name 1\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 2\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 3\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 4\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 5\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 6\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 7\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 8\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 9\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 10\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 11\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 12\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 13\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 14\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 15\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 16\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 17\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 18\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 19\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 20\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 21\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 22\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 23\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 24\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 25\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 26\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 27\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 28\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 29\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 30\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 31\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 32\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 33\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 34\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 35\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 36\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 37\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 38\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 39\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 40\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 41\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 42\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 43\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 44\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 45\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 46\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 47\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 48\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 49\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 50\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 51\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 52\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 53\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 54\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 55\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 56\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 57\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 58\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 59\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 60\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 61\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 62\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 63\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 64\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 65\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 66\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 67\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 68\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 69\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 70\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 71\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 72\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 73\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 74\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 75\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 76\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 77\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 78\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 79\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 80\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 81\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 82\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 83\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 84\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 85\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 86\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 87\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 88\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 89\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 90\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 91\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 92\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 93\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 94\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 95\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 96\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 97\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 98\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 99\",\"Unit\":\"Count\"},{\"Name\":\"Metric Name 100\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\"]]",
metricsOutput[0]);
// flush the (MaxMetrics + 1) item only
Assert.Contains(
- "{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name 101\",\"Unit\":\"Count\"}],\"Dimensions\":[\"Service\"]",
+ "{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name 101\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\"]]",
metricsOutput[1]);
}
@@ -105,7 +105,7 @@ public void WhenMaxDataPointsAreAddedToTheSameMetric_FlushAutomatically()
metricsOutput[0]);
// flush the (MaxMetrics + 1) item only
- Assert.Contains("[\"Service\"]}]},\"Service\":\"testService\",\"Metric Name\":100}", metricsOutput[1]);
+ Assert.Contains("\"Dimensions\":[[\"Service\"]]}]},\"Service\":\"testService\",\"Metric Name\":100}", metricsOutput[1]);
}
[Trait("Category", "EMFLimits")]
@@ -141,7 +141,7 @@ public void WhenDimensionsAreAdded_MustExistAsMembers()
var metricsOutput = _consoleOut.ToString();
// Assert
- Assert.Contains("\"Dimensions\":[\"Service\",\"functionVersion\"]"
+ Assert.Contains("\"Dimensions\":[[\"Service\",\"functionVersion\"]]"
, metricsOutput);
Assert.Contains("\"Service\":\"testService\",\"functionVersion\":\"$LATEST\""
, metricsOutput);
@@ -157,11 +157,39 @@ public void When_Multiple_DimensionsAreAdded_MustExistAsMembers()
var metricsOutput = _consoleOut.ToString();
// Assert
- Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"ns1\",\"Metrics\":[{\"Name\":\"Lambda Execute\",\"Unit\":\"Count\",\"StorageResolution\":1}],\"Dimensions\":[\"Type\",\"Service\"]}]},\"Type\":\"Start\",\"Service\":\"service_undefined\",\"Lambda Execute\":1}", metricsOutput);
-
- Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"ns2\",\"Metrics\":[{\"Name\":\"Lambda Execute\",\"Unit\":\"Count\",\"StorageResolution\":1}],\"Dimensions\":[\"Type\",\"SessionId\",\"Service\"]}]},\"Type\":\"Start\",\"SessionId\":\"Unset\",\"Service\":\"service_undefined\",\"Lambda Execute\":1}", metricsOutput);
+ Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\"]]}]},\"Service\":\"ServiceName\",\"ColdStart\":1}", metricsOutput);
+ Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"SingleMetric1\",\"Unit\":\"Count\",\"StorageResolution\":1}],\"Dimensions\":[[\"Default1\"]]}]},\"Default1\":\"SingleMetric1\",\"SingleMetric1\":1}", metricsOutput);
+ Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"ns2\",\"Metrics\":[{\"Name\":\"SingleMetric2\",\"Unit\":\"Count\",\"StorageResolution\":1}],\"Dimensions\":[[\"Default1\",\"Default2\"]]}]},\"Default1\":\"SingleMetric2\",\"Default2\":\"SingleMetric2\",\"SingleMetric2\":1}", metricsOutput);
+ Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"AddMetric\",\"Unit\":\"Count\",\"StorageResolution\":1},{\"Name\":\"AddMetric2\",\"Unit\":\"Count\",\"StorageResolution\":1}],\"Dimensions\":[[\"Service\"]]}]},\"Service\":\"ServiceName\",\"AddMetric\":1,\"AddMetric2\":1}", metricsOutput);
+ }
+
+ [Trait("Category", "SchemaValidation")]
+ [Fact]
+ public void When_PushSingleMetric_With_Namespace()
+ {
+ // Act
+ _handler.PushSingleMetricWithNamespace();
+
+ var metricsOutput = _consoleOut.ToString();
+
+ // Assert
+ Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"ExampleApplication\",\"Metrics\":[{\"Name\":\"SingleMetric\",\"Unit\":\"Count\",\"StorageResolution\":1}],\"Dimensions\":[[\"Default\"]]}]},\"Default\":\"SingleMetric\",\"SingleMetric\":1}", metricsOutput);
+ }
+
+ [Trait("Category", "SchemaValidation")]
+ [Fact]
+ public void When_PushSingleMetric_With_Env_Namespace()
+ {
+ // Arrange
+ Environment.SetEnvironmentVariable("POWERTOOLS_METRICS_NAMESPACE", "EnvNamespace");
- Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Lambda Execute\",\"Unit\":\"Count\",\"StorageResolution\":1}],\"Dimensions\":[\"Service\",\"Default\",\"SessionId\",\"Type\"]}]},\"Service\":\"testService\",\"Default\":\"Initial\",\"SessionId\":\"MySessionId\",\"Type\":\"Start\",\"Lambda Execute\":1}", metricsOutput);
+ // Act
+ _handler.PushSingleMetricWithEnvNamespace();
+
+ var metricsOutput = _consoleOut.ToString();
+
+ // Assert
+ Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"EnvNamespace\",\"Metrics\":[{\"Name\":\"SingleMetric\",\"Unit\":\"Count\",\"StorageResolution\":1}],\"Dimensions\":[[\"Default\"]]}]},\"Default\":\"SingleMetric\",\"SingleMetric\":1}", metricsOutput);
}
[Trait("Category", "MetricsImplementation")]
@@ -209,7 +237,7 @@ public void WhenDefaultDimensionsSet_ValidInitialization()
var result = _consoleOut.ToString();
// Assert
- Assert.Contains($"\"Dimensions\":[\"Service\",\"{key}\"]", result);
+ Assert.Contains($"\"Dimensions\":[[\"Service\",\"{key}\"]]", result);
Assert.Contains($"\"CustomDefaultDimension\":\"{value}\"", result);
}
@@ -246,7 +274,7 @@ public void WhenDefaultDimensionSet_IgnoreDuplicates()
var result = _consoleOut.ToString();
// Assert
- Assert.Contains("\"Dimensions\":[\"Service\",\"CustomDefaultDimension\"]", result);
+ Assert.Contains("\"Dimensions\":[[\"Service\",\"CustomDefaultDimension\"]]", result);
Assert.Contains("\"CustomDefaultDimension\":\"CustomDefaultDimensionValue\"", result);
}
@@ -260,7 +288,7 @@ public void WhenMetricsAndMetadataAdded_ValidateOutput()
// Assert
Assert.Contains(
- "CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\"}],\"Dimensions\":[\"Service\",\"functionVersion\"]}]},\"Service\":\"testService\",\"functionVersion\":\"$LATEST\",\"Time\":100.7,\"env\":\"dev\"}"
+ "CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\"}],\"Dimensions\":[[\"Service\",\"functionVersion\"]]}]},\"Service\":\"testService\",\"functionVersion\":\"$LATEST\",\"Time\":100.7,\"env\":\"dev\"}"
, result);
}
@@ -275,7 +303,7 @@ public void When_Metrics_And_Metadata_Added_With_Same_Key_Should_Only_Write_Metr
// Assert
// No Metadata key was added
Assert.Contains(
- "CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\"}],\"Dimensions\":[\"Service\",\"functionVersion\"]}]},\"Service\":\"testService\",\"functionVersion\":\"$LATEST\",\"Time\":100.7}"
+ "CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\"}],\"Dimensions\":[[\"Service\",\"functionVersion\"]]}]},\"Service\":\"testService\",\"functionVersion\":\"$LATEST\",\"Time\":100.7}"
, result);
}
@@ -337,7 +365,7 @@ public async Task WhenMetricsAsyncRaceConditionItemSameKeyExists_ValidateLock()
// Assert
Assert.Contains(
- "{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name\",\"Unit\":\"Count\"}],\"Dimensions\":[\"Service\"]",
+ "{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\"]]",
metricsOutput);
}
@@ -366,6 +394,7 @@ public void Dispose()
{
// need to reset instance after each test
MetricsAspect.ResetForTest();
+ Environment.SetEnvironmentVariable("POWERTOOLS_METRICS_NAMESPACE", null);
}
}
}
\ No newline at end of file
diff --git a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs
index e29e99a9..f00a8c5f 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs
@@ -39,25 +39,39 @@ public void AddDimensions()
Metrics.AddMetric("TestMetric", 1, MetricUnit.Count);
}
- [Metrics(Namespace = "dotnet-powertools-test", Service = "testService")]
+ [Metrics(Namespace = "dotnet-powertools-test", Service = "ServiceName", CaptureColdStart = true)]
public void AddMultipleDimensions()
{
- Metrics.SetDefaultDimensions(new Dictionary {
- { "Default", "Initial" }
- });
- Metrics.PushSingleMetric("Lambda Execute", 1, MetricUnit.Count, metricResolution: MetricResolution.High, nameSpace: "ns1",
+ Metrics.PushSingleMetric("SingleMetric1", 1, MetricUnit.Count, metricResolution: MetricResolution.High,
defaultDimensions: new Dictionary {
- { "Type", "Start" }
+ { "Default1", "SingleMetric1" }
});
- Metrics.PushSingleMetric("Lambda Execute", 1, MetricUnit.Count, metricResolution: MetricResolution.High, nameSpace: "ns2",
+ Metrics.PushSingleMetric("SingleMetric2", 1, MetricUnit.Count, metricResolution: MetricResolution.High, nameSpace: "ns2",
+ defaultDimensions: new Dictionary {
+ { "Default1", "SingleMetric2" },
+ { "Default2", "SingleMetric2" }
+ });
+ Metrics.AddMetric("AddMetric", 1, MetricUnit.Count, MetricResolution.High);
+ Metrics.AddMetric("AddMetric2", 1, MetricUnit.Count, MetricResolution.High);
+ }
+
+ [Metrics(Namespace = "ExampleApplication")]
+ public void PushSingleMetricWithNamespace()
+ {
+ Metrics.PushSingleMetric("SingleMetric", 1, MetricUnit.Count, metricResolution: MetricResolution.High,
+ defaultDimensions: new Dictionary {
+ { "Default", "SingleMetric" }
+ });
+ }
+
+ [Metrics]
+ public void PushSingleMetricWithEnvNamespace()
+ {
+ Metrics.PushSingleMetric("SingleMetric", 1, MetricUnit.Count, metricResolution: MetricResolution.High,
defaultDimensions: new Dictionary {
- { "Type", "Start" },
- { "SessionId", "Unset" }
+ { "Default", "SingleMetric" }
});
- Metrics.AddMetric("Lambda Execute", 1, MetricUnit.Count, MetricResolution.High);
- Metrics.AddDimension("SessionId", "MySessionId");
- Metrics.AddDimension("Type", "Start");
}
[Metrics(Namespace = "dotnet-powertools-test", Service = "testService")]
diff --git a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs
index dd140b40..3469e2e4 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs
@@ -85,7 +85,7 @@ public void When_LambdaContext_Should_Add_FunctioName_Dimension_CaptureColdStart
metricsOutput);
Assert.Contains(
- "\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[\"FunctionName\",\"Service\"]}]}",
+ "\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"FunctionName\",\"Service\"]]}]}",
metricsOutput);
}
@@ -108,7 +108,7 @@ public void When_LambdaContext_And_Parameter_Should_Add_FunctioName_Dimension_Ca
metricsOutput);
Assert.Contains(
- "\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[\"FunctionName\",\"Service\"]}]}",
+ "\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"FunctionName\",\"Service\"]]}]}",
metricsOutput);
}
@@ -125,7 +125,7 @@ public void When_No_LambdaContext_Should_Not_Add_FunctioName_Dimension_CaptureCo
metricsOutput);
Assert.Contains(
- "\"Metrics\":[{\"Name\":\"MyMetric\",\"Unit\":\"None\"}],\"Dimensions\":[\"Service\"]}]},\"Service\":\"svc\",\"MyMetric\":1}",
+ "\"Metrics\":[{\"Name\":\"MyMetric\",\"Unit\":\"None\"}],\"Dimensions\":[[\"Service\"]]}]},\"Service\":\"svc\",\"MyMetric\":1}",
metricsOutput);
}
diff --git a/libraries/tests/e2e/functions/core/metrics/Function/src/Function/TestHelper.cs b/libraries/tests/e2e/functions/core/metrics/Function/src/Function/TestHelper.cs
index b7059a62..750c77ab 100644
--- a/libraries/tests/e2e/functions/core/metrics/Function/src/Function/TestHelper.cs
+++ b/libraries/tests/e2e/functions/core/metrics/Function/src/Function/TestHelper.cs
@@ -17,6 +17,7 @@ public static void TestMethod(APIGatewayProxyRequest apigwProxyEvent, ILambdaCon
Metrics.SetDefaultDimensions(DefaultDimensions);
Metrics.AddMetric("Invocation", 1, MetricUnit.Count);
+ Metrics.AddDimension("FunctionName", context.FunctionName);
Metrics.AddDimension("Memory","MemoryLimitInMB");
Metrics.AddMetric("Memory with Environment dimension", context.MemoryLimitInMB, MetricUnit.Megabytes);
@@ -39,7 +40,7 @@ public static void TestMethod(APIGatewayProxyRequest apigwProxyEvent, ILambdaCon
service: "Test",
defaultDimensions: new Dictionary
{
- {"FunctionContext", "$LATEST"}
+ {"FunctionName", context.FunctionName}
});
}
}
\ No newline at end of file
diff --git a/libraries/tests/e2e/functions/core/metrics/Function/test/Function.Tests/Function.Tests.csproj b/libraries/tests/e2e/functions/core/metrics/Function/test/Function.Tests/Function.Tests.csproj
index 6881f4cb..aa3f3cb8 100644
--- a/libraries/tests/e2e/functions/core/metrics/Function/test/Function.Tests/Function.Tests.csproj
+++ b/libraries/tests/e2e/functions/core/metrics/Function/test/Function.Tests/Function.Tests.csproj
@@ -10,6 +10,7 @@
+
diff --git a/libraries/tests/e2e/functions/core/metrics/Function/test/Function.Tests/FunctionTests.cs b/libraries/tests/e2e/functions/core/metrics/Function/test/Function.Tests/FunctionTests.cs
index 1670dceb..31c91faf 100644
--- a/libraries/tests/e2e/functions/core/metrics/Function/test/Function.Tests/FunctionTests.cs
+++ b/libraries/tests/e2e/functions/core/metrics/Function/test/Function.Tests/FunctionTests.cs
@@ -1,10 +1,14 @@
using System.Text.Json;
+using Amazon.CDK.AWS.CodeDeploy;
+using Amazon.CloudWatch;
+using Amazon.CloudWatch.Model;
using Amazon.Lambda;
using Amazon.Lambda.APIGatewayEvents;
using Xunit;
using Amazon.Lambda.Model;
using TestUtils;
using Xunit.Abstractions;
+using Environment = Amazon.Lambda.Model.Environment;
namespace Function.Tests;
@@ -13,6 +17,7 @@ public class FunctionTests
{
private readonly ITestOutputHelper _testOutputHelper;
private readonly AmazonLambdaClient _lambdaClient;
+ private string? _functionName;
public FunctionTests(ITestOutputHelper testOutputHelper)
{
@@ -26,7 +31,9 @@ public FunctionTests(ITestOutputHelper testOutputHelper)
[InlineData("E2ETestLambda_ARM_AOT_NET8_metrics")]
public async Task AotFunctionTest(string functionName)
{
- await TestFunction(functionName);
+ _functionName = functionName;
+ await ForceColdStart();
+ await TestFunction();
}
[Theory]
@@ -36,61 +43,129 @@ public async Task AotFunctionTest(string functionName)
[InlineData("E2ETestLambda_ARM_NET8_metrics")]
public async Task FunctionTest(string functionName)
{
- await TestFunction(functionName);
+ _functionName = functionName;
+ await ForceColdStart();
+ await TestFunction();
}
- internal async Task TestFunction(string functionName)
+ internal async Task TestFunction()
{
var request = new InvokeRequest
{
- FunctionName = functionName,
+ FunctionName = _functionName,
InvocationType = InvocationType.RequestResponse,
Payload = await File.ReadAllTextAsync("../../../../../../../../payload.json"),
LogType = LogType.Tail
};
- // run twice for cold and warm start
- for (int i = 0; i < 2; i++)
- {
- var response = await _lambdaClient.InvokeAsync(request);
+ // Test cold start
+ var coldStartResponse = await _lambdaClient.InvokeAsync(request);
+ ValidateResponse(coldStartResponse, true);
- if (string.IsNullOrEmpty(response.LogResult))
- {
- Assert.Fail("No LogResult field returned in the response of Lambda invocation.");
- }
+ // Test warm start
+ var warmStartResponse = await _lambdaClient.InvokeAsync(request);
+ ValidateResponse(warmStartResponse, false);
- var payload = System.Text.Encoding.UTF8.GetString(response.Payload.ToArray());
- var parsedPayload = JsonSerializer.Deserialize(payload);
+ // Assert cloudwatch
+ await AssertCloudWatch();
+ }
- if (parsedPayload == null)
- {
- Assert.Fail("Failed to parse payload.");
- }
+ private void ValidateResponse(InvokeResponse response, bool isColdStart)
+ {
+ if (string.IsNullOrEmpty(response.LogResult))
+ {
+ Assert.Fail("No LogResult field returned in the response of Lambda invocation.");
+ }
- Assert.Equal(200, parsedPayload.StatusCode);
- Assert.Equal("HELLO WORLD", parsedPayload.Body);
+ var payload = System.Text.Encoding.UTF8.GetString(response.Payload.ToArray());
+ var parsedPayload = JsonSerializer.Deserialize(payload);
- // Assert Output log from Lambda execution
- AssertOutputLog(response);
+ if (parsedPayload == null)
+ {
+ Assert.Fail("Failed to parse payload.");
}
+
+ Assert.Equal(200, parsedPayload.StatusCode);
+ Assert.Equal("HELLO WORLD", parsedPayload.Body);
+
+ // Assert Output log from Lambda execution
+ AssertOutputLog(response, isColdStart);
}
- private void AssertOutputLog(InvokeResponse response)
+ private void AssertOutputLog(InvokeResponse response, bool expectedColdStart)
{
- // Extract and parse log
var logResult = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(response.LogResult));
_testOutputHelper.WriteLine(logResult);
var output = OutputLogParser.ParseLogSegments(logResult, out var report);
var isColdStart = report.initDuration != "N/A";
- var index = 0;
+
+ Assert.Equal(expectedColdStart, isColdStart);
+
if (isColdStart)
{
- AssertColdStart(output[index]);
- index += 1;
+ AssertColdStart(output[0]);
+ AssertSingleMetric(output[1]);
+ AssertMetricsDimensionsMetadata(output[2]);
}
+ else
+ {
+ AssertSingleMetric(output[0]);
+ AssertMetricsDimensionsMetadata(output[1]);
+ }
+ }
- AssertSingleMetric(output[index]);
- AssertMetricsDimensionsMetadata(output[index + 1]);
+ private async Task AssertCloudWatch()
+ {
+ using var cloudWatchClient = new AmazonCloudWatchClient();
+ var request = new ListMetricsRequest
+ {
+ Namespace = "Test",
+ Dimensions =
+ [
+ new DimensionFilter
+ {
+ Name = "Service",
+ Value = "Test"
+ },
+
+ new DimensionFilter
+ {
+ Name = "FunctionName",
+ Value = _functionName
+ }
+ ]
+ };
+
+ var response = await cloudWatchClient.ListMetricsAsync(request);
+
+ Assert.Equal(7, response.Metrics.Count);
+
+ foreach (var metric in response.Metrics)
+ {
+ Assert.Equal("Test", metric.Namespace);
+
+ switch (metric.MetricName)
+ {
+ case "ColdStart":
+ case "SingleMetric":
+ Assert.Equal(2, metric.Dimensions.Count);
+ Assert.Contains(metric.Dimensions, d => d.Name == "Service" && d.Value == "Test");
+ Assert.Contains(metric.Dimensions, d => d.Name == "FunctionName" && d.Value == _functionName);
+ break;
+ case "Invocation":
+ case "Memory with Environment dimension":
+ case "Standard resolution":
+ case "High resolution":
+ case "Default resolution":
+ Assert.Equal(5, metric.Dimensions.Count);
+ Assert.Contains(metric.Dimensions, d => d.Name == "Service" && d.Value == "Test");
+ Assert.Contains(metric.Dimensions, d => d.Name == "FunctionName" && d.Value == _functionName);
+ Assert.Contains(metric.Dimensions, d => d.Name == "Memory" && d.Value == "MemoryLimitInMB");
+ Assert.Contains(metric.Dimensions, d => d.Name == "Environment" && d.Value == "Prod");
+ Assert.Contains(metric.Dimensions, d => d.Name == "Another" && d.Value == "One");
+ break;
+ }
+ }
}
private void AssertMetricsDimensionsMetadata(string output)
@@ -136,10 +211,11 @@ private void AssertMetricsDimensionsMetadata(string output)
Assert.Equal("Count", unitElement5.GetString());
Assert.True(cloudWatchMetricsElement[0].TryGetProperty("Dimensions", out JsonElement dimensionsElement));
- Assert.Equal("Service", dimensionsElement[0].GetString());
- Assert.Equal("Environment", dimensionsElement[1].GetString());
- Assert.Equal("Another", dimensionsElement[2].GetString());
- Assert.Equal("Memory", dimensionsElement[3].GetString());
+ Assert.Equal("Service", dimensionsElement[0][0].GetString());
+ Assert.Equal("Environment", dimensionsElement[0][1].GetString());
+ Assert.Equal("Another", dimensionsElement[0][2].GetString());
+ Assert.Equal("FunctionName", dimensionsElement[0][3].GetString());
+ Assert.Equal("Memory", dimensionsElement[0][4].GetString());
Assert.True(root.TryGetProperty("Service", out JsonElement serviceElement));
Assert.Equal("Test", serviceElement.GetString());
@@ -150,6 +226,9 @@ private void AssertMetricsDimensionsMetadata(string output)
Assert.True(root.TryGetProperty("Another", out JsonElement anotherElement));
Assert.Equal("One", anotherElement.GetString());
+ Assert.True(root.TryGetProperty("FunctionName", out JsonElement functionNameElement));
+ Assert.Equal(_functionName, functionNameElement.GetString());
+
Assert.True(root.TryGetProperty("Memory", out JsonElement memoryElement));
Assert.Equal("MemoryLimitInMB", memoryElement.GetString());
@@ -191,11 +270,11 @@ private void AssertSingleMetric(string output)
Assert.Equal("Count", unitElement.GetString());
Assert.True(cloudWatchMetricsElement[0].TryGetProperty("Dimensions", out JsonElement dimensionsElement));
- Assert.Equal("FunctionContext", dimensionsElement[0].GetString());
- Assert.Equal("Service", dimensionsElement[1].GetString());
+ Assert.Equal("FunctionName", dimensionsElement[0][0].GetString());
+ Assert.Equal("Service", dimensionsElement[0][1].GetString());
- Assert.True(root.TryGetProperty("FunctionContext", out JsonElement functionContextElement));
- Assert.Equal("$LATEST", functionContextElement.GetString());
+ Assert.True(root.TryGetProperty("FunctionName", out JsonElement functionNameElement));
+ Assert.Equal(_functionName, functionNameElement.GetString());
Assert.True(root.TryGetProperty("Service", out JsonElement serviceElement));
Assert.Equal("Test", serviceElement.GetString());
@@ -221,4 +300,23 @@ private void AssertColdStart(string output)
Assert.True(root.TryGetProperty("ColdStart", out JsonElement coldStartElement));
Assert.Equal(1, coldStartElement.GetInt32());
}
+
+ private async Task ForceColdStart()
+ {
+ var updateRequest = new UpdateFunctionConfigurationRequest
+ {
+ FunctionName = _functionName,
+ Environment = new Environment
+ {
+ Variables = new Dictionary
+ {
+ { "ForceColdStart", Guid.NewGuid().ToString() }
+ }
+ }
+ };
+
+ _ = await _lambdaClient.UpdateFunctionConfigurationAsync(updateRequest);
+
+ await Task.Delay(2000);
+ }
}
\ No newline at end of file