Skip to content

Commit 0ca1252

Browse files
authored
Merge pull request #312 from hjgraca/metrics-prevent-exceed-100-datapoint
fix: Prevent a single metric have more than 100 data points
2 parents 6298b82 + 546caaa commit 0ca1252

File tree

3 files changed

+76
-6
lines changed

3 files changed

+76
-6
lines changed

libraries/src/AWS.Lambda.Powertools.Metrics/Metrics.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
using System;
1717
using System.Collections.Generic;
18+
using System.Linq;
1819
using AWS.Lambda.Powertools.Common;
1920

2021
namespace AWS.Lambda.Powertools.Metrics;
@@ -97,7 +98,15 @@ void IMetrics.AddMetric(string key, double value, MetricUnit unit, MetricResolut
9798
"'AddMetric' method requires a valid metrics value. Value must be >= 0.");
9899
}
99100

100-
if (_context.GetMetrics().Count == 100) _instance.Flush(true);
101+
var metrics = _context.GetMetrics();
102+
103+
if (metrics.Count > 0 &&
104+
(metrics.Count == PowertoolsConfigurations.MaxMetrics ||
105+
metrics.FirstOrDefault(x => x.Name == key)
106+
?.Values.Count == PowertoolsConfigurations.MaxMetrics))
107+
{
108+
_instance.Flush(true);
109+
}
101110

102111
_context.AddMetric(key, value, unit, metricResolution);
103112
}

libraries/src/AWS.Lambda.Powertools.Metrics/Model/MetricDirective.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,21 @@ public void AddMetric(string name, double value, MetricUnit unit, MetricResoluti
148148
{
149149
var metric = Metrics.FirstOrDefault(m => m.Name == name);
150150
if (metric != null)
151-
metric.AddValue(value);
151+
{
152+
if (metric.Values.Count < PowertoolsConfigurations.MaxMetrics)
153+
metric.AddValue(value);
154+
else
155+
throw new ArgumentOutOfRangeException(nameof(metric),
156+
$"Cannot add more than {PowertoolsConfigurations.MaxMetrics} metric data points at the same time.");
157+
}
152158
else
153159
Metrics.Add(new MetricDefinition(name, unit, value, metricResolution));
154160
}
155161
}
156162
else
157163
{
158164
throw new ArgumentOutOfRangeException(nameof(Metrics),
159-
"Cannot add more than 100 metrics at the same time.");
165+
$"Cannot add more than {PowertoolsConfigurations.MaxMetrics} metrics at the same time.");
160166
}
161167
}
162168

libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/EMFValidationTests.cs

+58-3
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void WhenCaptureColdStartEnabled_ValidateExists()
112112

113113
[Trait("Category", "EMFLimits")]
114114
[Fact]
115-
public void When100MetricsAreAdded_FlushAutomatically()
115+
public void WhenMaxMetricsAreAdded_FlushAutomatically()
116116
{
117117
// Arrange
118118
var methodName = Guid.NewGuid().ToString();
@@ -137,23 +137,78 @@ public void When100MetricsAreAdded_FlushAutomatically()
137137
// Act
138138
handler.OnEntry(eventArgs);
139139

140-
for (var i = 0; i <= 100; i++)
140+
for (var i = 0; i <= PowertoolsConfigurations.MaxMetrics; i++)
141141
{
142142
Metrics.AddMetric($"Metric Name {i + 1}", i, MetricUnit.Count);
143-
}
144143

144+
if (i == PowertoolsConfigurations.MaxMetrics)
145+
{
146+
// flush when it reaches MaxMetrics
147+
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\"]]", consoleOut.ToString());
148+
}
149+
}
145150
handler.OnExit(eventArgs);
146151

147152
var metricsOutput = consoleOut.ToString();
148153

149154
// Assert
155+
// flush the (MaxMetrics + 1) item only
150156
Assert.Contains("{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name 101\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\"]", metricsOutput);
151157

152158
// Reset
153159
handler.ResetForTest();
154160
}
155161

162+
[Trait("Category", "EMFLimits")]
163+
[Fact]
164+
public void WhenMaxDataPointsAreAddedToTheSameMetric_FlushAutomatically()
165+
{
166+
// Arrange
167+
var methodName = Guid.NewGuid().ToString();
168+
var consoleOut = new StringWriter();
169+
Console.SetOut(consoleOut);
170+
171+
var configurations = new Mock<IPowertoolsConfigurations>();
156172

173+
var metrics = new Metrics(
174+
configurations.Object,
175+
nameSpace: "dotnet-powertools-test",
176+
service: "testService"
177+
);
178+
179+
var handler = new MetricsAspectHandler(
180+
metrics,
181+
false
182+
);
183+
184+
var eventArgs = new AspectEventArgs { Name = methodName };
185+
186+
// Act
187+
handler.OnEntry(eventArgs);
188+
189+
for (var i = 0; i <= PowertoolsConfigurations.MaxMetrics; i++)
190+
{
191+
Metrics.AddMetric($"Metric Name", i, MetricUnit.Count);
192+
if(i == PowertoolsConfigurations.MaxMetrics)
193+
{
194+
// flush when it reaches MaxMetrics
195+
Assert.Contains(
196+
"\"Service\":\"testService\",\"Metric Name\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99]}",
197+
consoleOut.ToString());
198+
}
199+
}
200+
201+
handler.OnExit(eventArgs);
202+
203+
var metricsOutput = consoleOut.ToString();
204+
205+
// Assert
206+
// flush the (MaxMetrics + 1) item only
207+
Assert.Contains("[[\"Service\"]]}]},\"Service\":\"testService\",\"Metric Name\":100}", metricsOutput);
208+
209+
// Reset
210+
handler.ResetForTest();
211+
}
157212

158213
[Trait("Category", "EMFLimits")]
159214
[Fact]

0 commit comments

Comments
 (0)