From d02ae25f1c3f88ac7be1b0be9935980e0ff95a3c Mon Sep 17 00:00:00 2001
From: Henrique <999396+hjgraca@users.noreply.github.com>
Date: Tue, 25 Feb 2025 11:22:50 +0000
Subject: [PATCH 1/2] feat(metrics): add support for disabling metrics via
environment variable
---
docs/core/metrics-v2.md | 21 ++++-----
.../Core/Constants.cs | 5 ++
.../Core/IPowertoolsConfigurations.cs | 9 +++-
.../Core/PowertoolsConfigurations.cs | 3 ++
.../AWS.Lambda.Powertools.Metrics/Metrics.cs | 14 +++++-
.../MetricsTests.cs | 46 +++++++++++++++++++
6 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/docs/core/metrics-v2.md b/docs/core/metrics-v2.md
index 5502edde..f070dcc5 100644
--- a/docs/core/metrics-v2.md
+++ b/docs/core/metrics-v2.md
@@ -52,12 +52,16 @@ Visit the AWS documentation for a complete explanation for [Amazon CloudWatch co
**`Metrics`** is implemented as a Singleton to keep track of your aggregate metrics in memory and make them accessible anywhere in your code. To guarantee that metrics are flushed properly the **`MetricsAttribute`** must be added on the lambda handler.
-Metrics has two global settings that will be used across all metrics emitted. Use your application or main service as the metric namespace to easily group all metrics:
+Metrics has three global settings that will be used across all metrics emitted. Use your application or main service as the metric namespace to easily group all metrics:
-Setting | Description | Environment variable | Constructor parameter
-------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | -------------------------------------------------
-**Service** | Optionally, sets **service** metric dimension across all metrics e.g. `payment` | `POWERTOOLS_SERVICE_NAME` | `Service`
-**Metric namespace** | Logical container where all metrics will be placed e.g. `MyCompanyEcommerce` | `POWERTOOLS_METRICS_NAMESPACE` | `Namespace`
+ Setting | Description | Environment variable | Decorator parameter
+-------------------------------|---------------------------------------------------------------------------------| ------------------------------------------------- |-----------------------
+ **Metric namespace** | Logical container where all metrics will be placed e.g. `MyCompanyEcommerce` | `POWERTOOLS_METRICS_NAMESPACE` | `Namespace`
+ **Service** | Optionally, sets **Service** metric dimension across all metrics e.g. `payment` | `POWERTOOLS_SERVICE_NAME` | `Service`
+**Disable Powertools Metrics** | Optionally, disables all Powertools metrics |`POWERTOOLS_METRICS_DISABLED` | N/A |
+
+???+ info
+ `POWERTOOLS_METRICS_DISABLED` will not disable default metrics created by AWS services.
!!! info "Autocomplete Metric Units"
All parameters in **`Metrics Attribute`** are optional. Following rules apply:
@@ -67,13 +71,6 @@ Setting | Description | Environment variable | Constructor parameter
- **CaptureColdStart:** **`false`** by default.
- **RaiseOnEmptyMetrics:** **`false`** by default.
-### Full list of environment variables
-
-| Environment variable | Description | Default |
-| ------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------- |
-| **POWERTOOLS_SERVICE_NAME** | Sets service name used for tracing namespace, metrics dimension and structured logging | `"service_undefined"` |
-| **POWERTOOLS_METRICS_NAMESPACE** | Sets namespace used for metrics | `None` |
-
### Metrics object
#### Attribute
diff --git a/libraries/src/AWS.Lambda.Powertools.Common/Core/Constants.cs b/libraries/src/AWS.Lambda.Powertools.Common/Core/Constants.cs
index 912196da..343faa68 100644
--- a/libraries/src/AWS.Lambda.Powertools.Common/Core/Constants.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Common/Core/Constants.cs
@@ -130,4 +130,9 @@ internal static class Constants
/// Constant for POWERTOOLS_BATCH_THROW_ON_FULL_BATCH_FAILURE environment variable
///
internal const string BatchThrowOnFullBatchFailureEnv = "POWERTOOLS_BATCH_THROW_ON_FULL_BATCH_FAILURE";
+
+ ///
+ /// Constant for POWERTOOLS_METRICS_DISABLED environment variable
+ ///
+ internal const string PowertoolsMetricsDisabledEnv = "POWERTOOLS_METRICS_DISABLED";
}
\ No newline at end of file
diff --git a/libraries/src/AWS.Lambda.Powertools.Common/Core/IPowertoolsConfigurations.cs b/libraries/src/AWS.Lambda.Powertools.Common/Core/IPowertoolsConfigurations.cs
index ff2c5664..58955a50 100644
--- a/libraries/src/AWS.Lambda.Powertools.Common/Core/IPowertoolsConfigurations.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Common/Core/IPowertoolsConfigurations.cs
@@ -155,11 +155,16 @@ public interface IPowertoolsConfigurations
/// Gets the maximum degree of parallelism to apply during batch processing.
///
/// Defaults to 1 (no parallelism). Specify -1 to automatically use the value of ProcessorCount.
- int BatchProcessingMaxDegreeOfParallelism { get; }
-
+ int BatchProcessingMaxDegreeOfParallelism { get; }
+
///
/// Gets a value indicating whether Batch processing will throw an exception on full batch failure.
///
/// Defaults to true
bool BatchThrowOnFullBatchFailureEnabled { get; }
+
+ ///
+ /// Gets a value indicating whether Metrics are disabled.
+ ///
+ bool MetricsDisabled { get; }
}
\ No newline at end of file
diff --git a/libraries/src/AWS.Lambda.Powertools.Common/Core/PowertoolsConfigurations.cs b/libraries/src/AWS.Lambda.Powertools.Common/Core/PowertoolsConfigurations.cs
index cf316389..bb12dbdc 100644
--- a/libraries/src/AWS.Lambda.Powertools.Common/Core/PowertoolsConfigurations.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Common/Core/PowertoolsConfigurations.cs
@@ -219,4 +219,7 @@ public void SetExecutionEnvironment(T type)
///
public bool BatchThrowOnFullBatchFailureEnabled => GetEnvironmentVariableOrDefault(Constants.BatchThrowOnFullBatchFailureEnv, true);
+
+ ///
+ public bool MetricsDisabled => GetEnvironmentVariableOrDefault(Constants.PowertoolsMetricsDisabledEnv, false);
}
\ No newline at end of file
diff --git a/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs b/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs
index 5d403ad4..04936987 100644
--- a/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs
@@ -100,6 +100,11 @@ internal static IMetrics Instance
///
private string _functionName;
+ ///
+ /// Gets a value indicating whether metrics are disabled.
+ ///
+ private bool _disabled;
+
///
/// Initializes a new instance of the class.
///
@@ -156,6 +161,7 @@ internal Metrics(IPowertoolsConfigurations powertoolsConfigurations, string name
_context = new MetricsContext();
_raiseOnEmptyMetrics = raiseOnEmptyMetrics;
_captureColdStartEnabled = captureColdStartEnabled;
+ _disabled = _powertoolsConfigurations.MetricsDisabled;
Instance = this;
_powertoolsConfigurations.SetExecutionEnvironment(this);
@@ -167,7 +173,7 @@ internal Metrics(IPowertoolsConfigurations powertoolsConfigurations, string name
///
void IMetrics.AddMetric(string key, double value, MetricUnit unit, MetricResolution resolution)
{
- if (Instance != null)
+ if (Instance != null && !_disabled)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(
@@ -261,6 +267,9 @@ void IMetrics.SetDefaultDimensions(Dictionary defaultDimensions)
///
void IMetrics.Flush(bool metricsOverflow)
{
+ if(_disabled)
+ return;
+
if (_context.GetMetrics().Count == 0
&& _raiseOnEmptyMetrics)
throw new SchemaValidationException(true);
@@ -329,6 +338,9 @@ private Dictionary GetDefaultDimensions()
void IMetrics.PushSingleMetric(string name, double value, MetricUnit unit, string nameSpace,
string service, Dictionary defaultDimensions, MetricResolution resolution)
{
+ if(_disabled)
+ return;
+
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException(nameof(name),
"'PushSingleMetric' method requires a valid metrics key. 'Null' or empty values are not allowed.");
diff --git a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/MetricsTests.cs b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/MetricsTests.cs
index 120d1a72..f3c94c27 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/MetricsTests.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/MetricsTests.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using Amazon.Lambda.Core;
using Amazon.Lambda.TestUtilities;
using AWS.Lambda.Powertools.Common;
@@ -141,6 +142,51 @@ public void Before_When_RaiseOnEmptyMetricsNotSet_Should_Configure_Null()
Assert.False(metrics.Options.RaiseOnEmptyMetrics);
}
+ [Fact]
+ public void When_MetricsDisabled_Should_Not_AddMetric()
+ {
+ // Arrange
+ var conf = Substitute.For();
+ conf.MetricsDisabled.Returns(true);
+
+ IMetrics metrics = new Metrics(conf);
+ var stringWriter = new StringWriter();
+ Console.SetOut(stringWriter);
+
+ // Act
+ metrics.AddMetric("test", 1.0);
+ metrics.Flush();
+
+ // Assert
+ Assert.Empty(stringWriter.ToString());
+
+ // Cleanup
+ stringWriter.Dispose();
+ Console.SetOut(new StreamWriter(Console.OpenStandardOutput()));
+ }
+
+ [Fact]
+ public void When_MetricsDisabled_Should_Not_PushSingleMetric()
+ {
+ // Arrange
+ var conf = Substitute.For();
+ conf.MetricsDisabled.Returns(true);
+
+ IMetrics metrics = new Metrics(conf);
+ var stringWriter = new StringWriter();
+ Console.SetOut(stringWriter);
+
+ // Act
+ metrics.PushSingleMetric("test", 1.0, MetricUnit.Count);
+
+ // Assert
+ Assert.Empty(stringWriter.ToString());
+
+ // Cleanup
+ stringWriter.Dispose();
+ Console.SetOut(new StreamWriter(Console.OpenStandardOutput()));
+ }
+
// Helper method for the tests
internal void TestMethod(ILambdaContext context)
{
From f2e94df9ab4bbb81711dfb20b6ce37c7c0e19818 Mon Sep 17 00:00:00 2001
From: Henrique <999396+hjgraca@users.noreply.github.com>
Date: Thu, 27 Feb 2025 15:28:27 +0000
Subject: [PATCH 2/2] fix flaky test
---
.../AWS.Lambda.Powertools.Common.Tests/ConsoleWrapperTests.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/libraries/tests/AWS.Lambda.Powertools.Common.Tests/ConsoleWrapperTests.cs b/libraries/tests/AWS.Lambda.Powertools.Common.Tests/ConsoleWrapperTests.cs
index 6395f79a..4da57dc0 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Common.Tests/ConsoleWrapperTests.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Common.Tests/ConsoleWrapperTests.cs
@@ -31,6 +31,7 @@ public void Error_Should_Write_To_Error_Console()
// Act
consoleWrapper.Error("error message");
+ writer.Flush();
// Assert
Assert.Equal($"error message{Environment.NewLine}", writer.ToString());