From b3a57a8fd8eb7607da04bb725f21f58f3b2245a8 Mon Sep 17 00:00:00 2001 From: Henrique <999396+hjgraca@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:25:37 +0000 Subject: [PATCH 1/6] feat(metrics): add support for default dimensions in metrics handling --- docs/core/metrics-v2.md | 65 +++++++++++++++++++ .../AWS.Lambda.Powertools.Metrics/Metrics.cs | 18 ++++- .../EMFValidationTests.cs | 26 ++++++++ .../Handlers/FunctionHandler.cs | 16 +++++ .../Handlers/FunctionHandlerTests.cs | 34 ++++++++++ .../Handlers/MetricsnBuilderHandler.cs | 10 +++ 6 files changed, 168 insertions(+), 1 deletion(-) diff --git a/docs/core/metrics-v2.md b/docs/core/metrics-v2.md index af5f6859..5502edde 100644 --- a/docs/core/metrics-v2.md +++ b/docs/core/metrics-v2.md @@ -596,6 +596,30 @@ CloudWatch EMF uses the same dimensions across all your metrics. Use **`PushSing === "Function.cs" + ```csharp hl_lines="8-13" + using AWS.Lambda.Powertools.Metrics; + + public class Function { + + [Metrics(Namespace = ExampleApplication, Service = "Booking")] + public async Task FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context) + { + Metrics.PushSingleMetric( + metricName: "ColdStart", + value: 1, + unit: MetricUnit.Count, + nameSpace: "ExampleApplication", + service: "Booking"); + ... + ``` + +By default it will skip all previously defined dimensions including default dimensions. Use default_dimensions keyword argument if you want to reuse default dimensions or specify custom dimensions from a dictionary. + +- `Metrics.DefaultDimensions`: Reuse default dimensions when using static Metrics +- `Options.DefaultDimensions`: Reuse default dimensions when using Builder or Configure patterns + +=== "New Default Dimensions.cs" + ```csharp hl_lines="8-17" using AWS.Lambda.Powertools.Metrics; @@ -616,6 +640,47 @@ CloudWatch EMF uses the same dimensions across all your metrics. Use **`PushSing }); ... ``` +=== "Default Dimensions static.cs" + + ```csharp hl_lines="8-12" + using AWS.Lambda.Powertools.Metrics; + + public class Function { + + [Metrics(Namespace = ExampleApplication, Service = "Booking")] + public async Task FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context) + { + Metrics.SetDefaultDimensions(new Dictionary + { + { "Default", "SingleMetric" } + }); + Metrics.PushSingleMetric("SingleMetric", 1, MetricUnit.Count, defaultDimensions: Metrics.DefaultDimensions ); + ... + ``` +=== "Default Dimensions Options / Builder patterns .cs" + + ```csharp hl_lines="9-13 18" + using AWS.Lambda.Powertools.Metrics; + + public MetricsnBuilderHandler(IMetrics metrics = null) + { + _metrics = metrics ?? new MetricsBuilder() + .WithCaptureColdStart(true) + .WithService("testService") + .WithNamespace("dotnet-powertools-test") + .WithDefaultDimensions(new Dictionary + { + { "Environment", "Prod1" }, + { "Another", "One" } + }).Build(); + } + + public void HandlerSingleMetricDimensions() + { + _metrics.PushSingleMetric("SuccessfulBooking", 1, MetricUnit.Count, defaultDimensions: _metrics.Options.DefaultDimensions); + } + ... + ``` ## AspNetCore diff --git a/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs b/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs index 86823bf0..8da23030 100644 --- a/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs +++ b/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; using AWS.Lambda.Powertools.Common; @@ -32,12 +33,27 @@ public class Metrics : IMetrics, IDisposable /// /// Gets or sets the instance. /// - public static IMetrics Instance + internal static IMetrics Instance { get => Current.Value ?? new Metrics(PowertoolsConfigurations.Instance); private set => Current.Value = value; } + /// + /// Gets DefaultDimensions + /// + public static Dictionary DefaultDimensions => Instance.Options.DefaultDimensions; + + /// + /// Gets Namespace + /// + public static string Namespace => Instance.Options.Namespace; + + /// + /// Gets Service + /// + public static string Service => Instance.Options.Service; + /// public MetricsOptions Options => new() diff --git a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs index adce5337..04b86b3c 100644 --- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs +++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs @@ -176,6 +176,32 @@ public void When_PushSingleMetric_With_Namespace() 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_No_DefaultDimensions() + { + // Act + _handler.PushSingleMetricNoDefaultDimensions(); + + var metricsOutput = _consoleOut.ToString(); + + // Assert + Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"ExampleApplication\",\"Metrics\":[{\"Name\":\"SingleMetric\",\"Unit\":\"Count\"}],\"Dimensions\":[[]]}]},\"SingleMetric\":1}", metricsOutput); + } + + [Trait("Category", "SchemaValidation")] + [Fact] + public void When_PushSingleMetric_With_DefaultDimensions() + { + // Act + _handler.PushSingleMetricDefaultDimensions(); + + var metricsOutput = _consoleOut.ToString(); + + // Assert + Assert.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"ExampleApplication\",\"Metrics\":[{\"Name\":\"SingleMetric\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Default\"]]}]},\"Default\":\"SingleMetric\",\"SingleMetric\":1}", metricsOutput); + } + [Trait("Category", "SchemaValidation")] [Fact] public void When_PushSingleMetric_With_Env_Namespace() 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 d860a9f9..8954134c 100644 --- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs +++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs @@ -65,6 +65,22 @@ public void PushSingleMetricWithNamespace() }); } + [Metrics(Namespace = "ExampleApplication")] + public void PushSingleMetricNoDefaultDimensions() + { + Metrics.PushSingleMetric("SingleMetric", 1, MetricUnit.Count); + } + + [Metrics(Namespace = "ExampleApplication")] + public void PushSingleMetricDefaultDimensions() + { + Metrics.SetDefaultDimensions(new Dictionary + { + { "Default", "SingleMetric" } + }); + Metrics.PushSingleMetric("SingleMetric", 1, MetricUnit.Count, defaultDimensions: Metrics.DefaultDimensions ); + } + [Metrics] public void PushSingleMetricWithEnvNamespace() { 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 dc338d59..1049c737 100644 --- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs +++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs @@ -266,6 +266,40 @@ public void Handler_With_Builder_Should_Configure_In_Constructor_Mock() service: "testService", Arg.Any>()); metricsMock.Received(1).AddMetric("SuccessfulBooking", 1, MetricUnit.Count); } + + [Fact] + public void Handler_With_Builder_Push_Single_Metric_No_Dimensions() + { + // Arrange + var handler = new MetricsnBuilderHandler(); + + // Act + handler.HandlerSingleMetric(); + + // Get the output and parse it + var metricsOutput = _consoleOut.ToString(); + + Assert.Contains( + "\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"SuccessfulBooking\",\"Unit\":\"Count\"}],\"Dimensions\":[[]]}]},\"SuccessfulBooking\":1}", + metricsOutput); + } + + [Fact] + public void Handler_With_Builder_Push_Single_Metric_Dimensions() + { + // Arrange + var handler = new MetricsnBuilderHandler(); + + // Act + handler.HandlerSingleMetricDimensions(); + + // Get the output and parse it + var metricsOutput = _consoleOut.ToString(); + + Assert.Contains( + "\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"SuccessfulBooking\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\",\"Environment\",\"Another\"]]}]},\"Service\":\"testService\",\"Environment\":\"Prod1\",\"Another\":\"One\",\"SuccessfulBooking\":1}", + metricsOutput); + } public void Dispose() { diff --git a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/MetricsnBuilderHandler.cs b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/MetricsnBuilderHandler.cs index f9fd329f..82c16b9c 100644 --- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/MetricsnBuilderHandler.cs +++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/MetricsnBuilderHandler.cs @@ -26,4 +26,14 @@ public void Handler(ILambdaContext context) { _metrics.AddMetric("SuccessfulBooking", 1, MetricUnit.Count); } + + public void HandlerSingleMetric() + { + _metrics.PushSingleMetric("SuccessfulBooking", 1, MetricUnit.Count); + } + + public void HandlerSingleMetricDimensions() + { + _metrics.PushSingleMetric("SuccessfulBooking", 1, MetricUnit.Count, defaultDimensions: _metrics.Options.DefaultDimensions); + } } \ No newline at end of file From dbb337795ebce2af9e48aa74750950cd62f55671 Mon Sep 17 00:00:00 2001 From: Henrique <999396+hjgraca@users.noreply.github.com> Date: Tue, 25 Feb 2025 09:53:38 +0000 Subject: [PATCH 2/6] fix functionname dimension to only coldstart --- .../Internal/MetricsAspect.cs | 24 ++++++++++----- .../Handlers/FunctionHandler.cs | 6 ++++ .../Handlers/FunctionHandlerTests.cs | 30 +++++++++++++++++-- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs b/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs index 3a09db42..dae4c321 100644 --- a/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs +++ b/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using Amazon.Lambda.Core; @@ -69,11 +70,13 @@ public void Before( var trigger = triggers.OfType().First(); - _metricsInstance ??= Metrics.Configure(options => { + _metricsInstance ??= Metrics.Configure(options => + { options.Namespace = trigger.Namespace; options.Service = trigger.Service; options.RaiseOnEmptyMetrics = trigger.IsRaiseOnEmptyMetricsSet ? trigger.RaiseOnEmptyMetrics : null; options.CaptureColdStart = trigger.IsCaptureColdStartSet ? trigger.CaptureColdStart : null; + options.FunctionName = trigger.FunctionName; }); var eventArgs = new AspectEventArgs @@ -87,17 +90,22 @@ public void Before( Triggers = triggers }; - if (_metricsInstance.Options.CaptureColdStart != null && _metricsInstance.Options.CaptureColdStart.Value && _isColdStart) + if (_metricsInstance.Options.CaptureColdStart != null && _metricsInstance.Options.CaptureColdStart.Value && + _isColdStart) { - var defaultDimensions = _metricsInstance.Options?.DefaultDimensions; _isColdStart = false; - var context = GetContext(eventArgs); - - if (context is not null) + var functionName = _metricsInstance.Options?.FunctionName; + var defaultDimensions = _metricsInstance.Options?.DefaultDimensions; + + if (string.IsNullOrWhiteSpace(functionName)) + { + functionName = GetContext(eventArgs)?.FunctionName ?? ""; + } + + if (!string.IsNullOrWhiteSpace(functionName)) { - defaultDimensions?.Add("FunctionName", context.FunctionName); - _metricsInstance.SetDefaultDimensions(defaultDimensions); + defaultDimensions?.Add("FunctionName", functionName); } _metricsInstance.PushSingleMetric( 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 8954134c..4abb6f45 100644 --- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs +++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs @@ -230,4 +230,10 @@ public void HandleWithParamAndLambdaContext(string input, ILambdaContext context { } + + [Metrics(Namespace = "ns", Service = "svc", CaptureColdStart = true)] + public void HandleOnlyDimensionsInColdStart(ILambdaContext context) + { + Metrics.AddMetric("MyMetric", 1); + } } \ No newline at end of file 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 1049c737..44d4e841 100644 --- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs +++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs @@ -174,7 +174,7 @@ public void DefaultDimensions_AreAppliedCorrectly_WithContext_FunctionName() metricsOutput); // Assert successful Memory metrics Assert.Contains( - "\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Memory\",\"Unit\":\"Megabytes\"}],\"Dimensions\":[[\"Service\",\"Environment\",\"Another\",\"FunctionName\"]]}]},\"Service\":\"testService\",\"Environment\":\"Prod\",\"Another\":\"One\",\"FunctionName\":\"My_Function_Name\",\"Memory\":10}", + "\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Memory\",\"Unit\":\"Megabytes\"}],\"Dimensions\":[[\"Service\",\"Environment\",\"Another\"]]}]},\"Service\":\"testService\",\"Environment\":\"Prod\",\"Another\":\"One\",\"Memory\":10}", metricsOutput); } @@ -231,7 +231,7 @@ public void Handler_With_Builder_Should_Configure_In_Constructor() metricsOutput); // Assert successful Memory metrics Assert.Contains( - "\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"SuccessfulBooking\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\",\"Environment\",\"Another\",\"FunctionName\"]]}]},\"Service\":\"testService\",\"Environment\":\"Prod1\",\"Another\":\"One\",\"FunctionName\":\"My_Function_Name\",\"SuccessfulBooking\":1}", + "\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"SuccessfulBooking\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\",\"Environment\",\"Another\"]]}]},\"Service\":\"testService\",\"Environment\":\"Prod1\",\"Another\":\"One\",\"SuccessfulBooking\":1}", metricsOutput); } @@ -300,6 +300,32 @@ public void Handler_With_Builder_Push_Single_Metric_Dimensions() "\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"SuccessfulBooking\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\",\"Environment\",\"Another\"]]}]},\"Service\":\"testService\",\"Environment\":\"Prod1\",\"Another\":\"One\",\"SuccessfulBooking\":1}", metricsOutput); } + + [Fact] + public void Dimension_Only_Set_In_Cold_Start() + { + // Arrange + var handler = new FunctionHandler(); + + // Act + handler.HandleOnlyDimensionsInColdStart(new TestLambdaContext + { + FunctionName = "My_Function_Name" + }); + + // Get the output and parse it + var metricsOutput = _consoleOut.ToString(); + + // Assert cold start + Assert.Contains( + "\"CloudWatchMetrics\":[{\"Namespace\":\"ns\",\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\",\"FunctionName\"]]}]},\"Service\":\"svc\",\"FunctionName\":\"My_Function_Name\",\"ColdStart\":1}", + metricsOutput); + + // Assert successful add metric without dimensions + Assert.Contains( + "\"CloudWatchMetrics\":[{\"Namespace\":\"ns\",\"Metrics\":[{\"Name\":\"MyMetric\",\"Unit\":\"None\"}],\"Dimensions\":[[\"Service\"]]}]},\"Service\":\"svc\",\"MyMetric\":1}", + metricsOutput); + } public void Dispose() { From 9e71bec12e51829d7c57863993860bcd1dcd21a7 Mon Sep 17 00:00:00 2001 From: Henrique <999396+hjgraca@users.noreply.github.com> Date: Tue, 25 Feb 2025 10:04:09 +0000 Subject: [PATCH 3/6] remove functionname --- .../Internal/MetricsAspect.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs b/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs index dae4c321..1577f5fc 100644 --- a/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs +++ b/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs @@ -76,7 +76,6 @@ public void Before( options.Service = trigger.Service; options.RaiseOnEmptyMetrics = trigger.IsRaiseOnEmptyMetricsSet ? trigger.RaiseOnEmptyMetrics : null; options.CaptureColdStart = trigger.IsCaptureColdStartSet ? trigger.CaptureColdStart : null; - options.FunctionName = trigger.FunctionName; }); var eventArgs = new AspectEventArgs @@ -90,22 +89,16 @@ public void Before( Triggers = triggers }; - if (_metricsInstance.Options.CaptureColdStart != null && _metricsInstance.Options.CaptureColdStart.Value && - _isColdStart) + if (_metricsInstance.Options.CaptureColdStart != null && _metricsInstance.Options.CaptureColdStart.Value && _isColdStart) { - _isColdStart = false; - - var functionName = _metricsInstance.Options?.FunctionName; var defaultDimensions = _metricsInstance.Options?.DefaultDimensions; + _isColdStart = false; - if (string.IsNullOrWhiteSpace(functionName)) - { - functionName = GetContext(eventArgs)?.FunctionName ?? ""; - } - - if (!string.IsNullOrWhiteSpace(functionName)) + var context = GetContext(eventArgs); + + if (context is not null) { - defaultDimensions?.Add("FunctionName", functionName); + defaultDimensions?.Add("FunctionName", context.FunctionName); } _metricsInstance.PushSingleMetric( From 4ea9fa9ec90447b73e548845a1c05c8b7dc31516 Mon Sep 17 00:00:00 2001 From: Henrique <999396+hjgraca@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:27:20 +0000 Subject: [PATCH 4/6] fix(metrics): rename variable for default dimensions in cold start handling --- .../AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs b/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs index 1577f5fc..d5eac029 100644 --- a/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs +++ b/libraries/src/AWS.Lambda.Powertools.Metrics/Internal/MetricsAspect.cs @@ -91,14 +91,14 @@ public void Before( if (_metricsInstance.Options.CaptureColdStart != null && _metricsInstance.Options.CaptureColdStart.Value && _isColdStart) { - var defaultDimensions = _metricsInstance.Options?.DefaultDimensions; + var dimensions = _metricsInstance.Options?.DefaultDimensions; _isColdStart = false; var context = GetContext(eventArgs); if (context is not null) { - defaultDimensions?.Add("FunctionName", context.FunctionName); + dimensions?.Add("FunctionName", context.FunctionName); } _metricsInstance.PushSingleMetric( @@ -107,7 +107,7 @@ public void Before( MetricUnit.Count, _metricsInstance.Options?.Namespace ?? "", _metricsInstance.Options?.Service ?? "", - defaultDimensions + dimensions ); } } From eab141d62cce9195906f46c9bf9143d2e42751a0 Mon Sep 17 00:00:00 2001 From: Henrique <999396+hjgraca@users.noreply.github.com> Date: Thu, 27 Feb 2025 12:33:54 +0000 Subject: [PATCH 5/6] update docs --- docs/core/metrics-v2.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/core/metrics-v2.md b/docs/core/metrics-v2.md index fb71e795..4854bae5 100644 --- a/docs/core/metrics-v2.md +++ b/docs/core/metrics-v2.md @@ -619,7 +619,7 @@ CloudWatch EMF uses the same dimensions across all your metrics. Use **`PushSing ... ``` -By default it will skip all previously defined dimensions including default dimensions. Use default_dimensions keyword argument if you want to reuse default dimensions or specify custom dimensions from a dictionary. +By default it will skip all previously defined dimensions including default dimensions. Use `dimensions` argument if you want to reuse default dimensions or specify custom dimensions from a dictionary. - `Metrics.DefaultDimensions`: Reuse default dimensions when using static Metrics - `Options.DefaultDimensions`: Reuse default dimensions when using Builder or Configure patterns @@ -660,7 +660,7 @@ By default it will skip all previously defined dimensions including default dime { { "Default", "SingleMetric" } }); - Metrics.PushSingleMetric("SingleMetric", 1, MetricUnit.Count, defaultDimensions: Metrics.DefaultDimensions ); + Metrics.PushSingleMetric("SingleMetric", 1, MetricUnit.Count, dimensions: Metrics.DefaultDimensions ); ... ``` === "Default Dimensions Options / Builder patterns .cs" @@ -683,7 +683,7 @@ By default it will skip all previously defined dimensions including default dime public void HandlerSingleMetricDimensions() { - _metrics.PushSingleMetric("SuccessfulBooking", 1, MetricUnit.Count, defaultDimensions: _metrics.Options.DefaultDimensions); + _metrics.PushSingleMetric("SuccessfulBooking", 1, MetricUnit.Count, dimensions: _metrics.Options.DefaultDimensions); } ... ``` From ce9bf85bdb9382b44ff742aa4d4c05996c4bcbad Mon Sep 17 00:00:00 2001 From: Henrique <999396+hjgraca@users.noreply.github.com> Date: Thu, 27 Feb 2025 12:38:26 +0000 Subject: [PATCH 6/6] add metrics tests --- .../MetricsTests.cs | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/MetricsTests.cs b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/MetricsTests.cs index 36039756..ecdd94d6 100644 --- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/MetricsTests.cs +++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/MetricsTests.cs @@ -243,4 +243,82 @@ public void When_ColdStart_And_DefaultDimensions_Is_Null_Should_Only_Add_Service Arg.Is(s => s.Contains("\"CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"FunctionName\"]]}]},\"FunctionName\":\"TestFunction\",\"ColdStart\":1}")) ); } + + [Fact] + public void Namespace_Should_Return_OptionsNamespace() + { + // Arrange + Metrics.ResetForTest(); + var metricsMock = Substitute.For(); + var optionsMock = new MetricsOptions + { + Namespace = "TestNamespace" + }; + + metricsMock.Options.Returns(optionsMock); + Metrics.UseMetricsForTests(metricsMock); + + // Act + var result = Metrics.Namespace; + + // Assert + Assert.Equal("TestNamespace", result); + } + + [Fact] + public void Service_Should_Return_OptionsService() + { + // Arrange + Metrics.ResetForTest(); + var metricsMock = Substitute.For(); + var optionsMock = new MetricsOptions + { + Service = "TestService" + }; + + metricsMock.Options.Returns(optionsMock); + Metrics.UseMetricsForTests(metricsMock); + + // Act + var result = Metrics.Service; + + // Assert + Assert.Equal("TestService", result); + } + + [Fact] + public void Namespace_Should_Return_Null_When_Not_Set() + { + // Arrange + Metrics.ResetForTest(); + var metricsMock = Substitute.For(); + var optionsMock = new MetricsOptions(); + + metricsMock.Options.Returns(optionsMock); + Metrics.UseMetricsForTests(metricsMock); + + // Act + var result = Metrics.Namespace; + + // Assert + Assert.Null(result); + } + + [Fact] + public void Service_Should_Return_Null_When_Not_Set() + { + // Arrange + Metrics.ResetForTest(); + var metricsMock = Substitute.For(); + var optionsMock = new MetricsOptions(); + + metricsMock.Options.Returns(optionsMock); + Metrics.UseMetricsForTests(metricsMock); + + // Act + var result = Metrics.Service; + + // Assert + Assert.Null(result); + } } \ No newline at end of file