Skip to content

Commit 8b1721e

Browse files
committed
Add support for High resolution metrics. New Enum with High (1) and Standard (60) resolution
1 parent 56d5583 commit 8b1721e

File tree

9 files changed

+150
-24
lines changed

9 files changed

+150
-24
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public interface IMetrics : IDisposable
3131
/// <param name="key">Metric key</param>
3232
/// <param name="value">Metric value</param>
3333
/// <param name="unit">Metric unit</param>
34-
void AddMetric(string key, double value, MetricUnit unit);
34+
/// <param name="metricResolution"></param>
35+
void AddMetric(string key, double value, MetricUnit unit, MetricResolution metricResolution);
3536

3637
/// <summary>
3738
/// Adds a dimension
@@ -62,8 +63,9 @@ public interface IMetrics : IDisposable
6263
/// <param name="nameSpace">Metric namespace</param>
6364
/// <param name="service">Metric service</param>
6465
/// <param name="defaultDimensions">Metric default dimensions</param>
66+
/// <param name="metricResolution">Metrics resolution</param>
6567
void PushSingleMetric(string metricName, double value, MetricUnit unit, string nameSpace = null,
66-
string service = null, Dictionary<string, string> defaultDimensions = null);
68+
string service = null, Dictionary<string, string> defaultDimensions = null, MetricResolution metricResolution = MetricResolution.Standard);
6769

6870
/// <summary>
6971
/// Sets the namespace

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ public void OnEntry(AspectEventArgs eventArgs)
106106
MetricUnit.Count,
107107
nameSpace,
108108
service,
109-
dimensions
109+
dimensions,
110+
MetricResolution.Standard
110111
);
111112
}
112113

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,12 @@ internal Metrics(IPowertoolsConfigurations powertoolsConfigurations, string name
7979
/// <param name="key">Metric Key</param>
8080
/// <param name="value">Metric Value</param>
8181
/// <param name="unit">Metric Unit</param>
82+
/// <param name="metricResolution">Metric resolution</param>
8283
/// <exception cref="System.ArgumentNullException">
8384
/// 'AddMetric' method requires a valid metrics key. 'Null' or empty values
8485
/// are not allowed.
8586
/// </exception>
86-
void IMetrics.AddMetric(string key, double value, MetricUnit unit)
87+
void IMetrics.AddMetric(string key, double value, MetricUnit unit, MetricResolution metricResolution)
8788
{
8889
if (string.IsNullOrWhiteSpace(key))
8990
throw new ArgumentNullException(
@@ -96,7 +97,7 @@ void IMetrics.AddMetric(string key, double value, MetricUnit unit)
9697

9798
if (_context.GetMetrics().Count == 100) _instance.Flush(true);
9899

99-
_context.AddMetric(key, value, unit);
100+
_context.AddMetric(key, value, unit, metricResolution);
100101
}
101102

102103
/// <summary>
@@ -229,19 +230,20 @@ public string Serialize()
229230
/// <param name="nameSpace">Metric Namespace</param>
230231
/// <param name="service">Service Name</param>
231232
/// <param name="defaultDimensions">Default dimensions list</param>
233+
/// <param name="metricResolution">Metrics resolution</param>
232234
/// <exception cref="System.ArgumentNullException">
233235
/// 'PushSingleMetric' method requires a valid metrics key. 'Null' or empty
234236
/// values are not allowed.
235237
/// </exception>
236238
void IMetrics.PushSingleMetric(string metricName, double value, MetricUnit unit, string nameSpace, string service,
237-
Dictionary<string, string> defaultDimensions)
239+
Dictionary<string, string> defaultDimensions, MetricResolution metricResolution)
238240
{
239241
if (string.IsNullOrWhiteSpace(metricName))
240242
throw new ArgumentNullException(
241243
$"'PushSingleMetric' method requires a valid metrics key. 'Null' or empty values are not allowed.");
242244

243245
using var context = InitializeContext(nameSpace, service, defaultDimensions);
244-
context.AddMetric(metricName, value, unit);
246+
context.AddMetric(metricName, value, unit, metricResolution);
245247

246248
Flush(context);
247249
}
@@ -260,9 +262,11 @@ public void Dispose()
260262
/// <param name="key">Metric Key. Must not be null, empty or whitespace</param>
261263
/// <param name="value">Metric Value</param>
262264
/// <param name="unit">Metric Unit</param>
263-
public static void AddMetric(string key, double value, MetricUnit unit = MetricUnit.None)
265+
/// <param name="metricResolution"></param>
266+
public static void AddMetric(string key, double value, MetricUnit unit = MetricUnit.None,
267+
MetricResolution metricResolution = MetricResolution.Standard)
264268
{
265-
_instance.AddMetric(key, value, unit);
269+
_instance.AddMetric(key, value, unit, metricResolution);
266270
}
267271

268272
/// <summary>
@@ -334,10 +338,11 @@ private void Flush(MetricsContext context)
334338
/// <param name="nameSpace">Metric Namespace</param>
335339
/// <param name="service">Service Name</param>
336340
/// <param name="defaultDimensions">Default dimensions list</param>
341+
/// <param name="metricResolution">Metrics resolution</param>
337342
public static void PushSingleMetric(string metricName, double value, MetricUnit unit, string nameSpace = null,
338-
string service = null, Dictionary<string, string> defaultDimensions = null)
343+
string service = null, Dictionary<string, string> defaultDimensions = null, MetricResolution metricResolution = MetricResolution.Standard)
339344
{
340-
_instance.PushSingleMetric(metricName, value, unit, nameSpace, service, defaultDimensions);
345+
_instance.PushSingleMetric(metricName, value, unit, nameSpace, service, defaultDimensions, metricResolution);
341346
}
342347

343348
/// <summary>

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,10 @@ internal void ClearNonDefaultDimensions()
8282
/// <param name="key">Metric key. Cannot be null, empty or whitespace</param>
8383
/// <param name="value">Metric value</param>
8484
/// <param name="unit">Metric Unit</param>
85-
internal void AddMetric(string key, double value, MetricUnit unit)
85+
/// <param name="metricResolution">Metric Resolution, Standard (default), High</param>
86+
internal void AddMetric(string key, double value, MetricUnit unit, MetricResolution metricResolution)
8687
{
87-
_metricDirective.AddMetric(key, value, unit);
88+
_metricDirective.AddMetric(key, value, unit, metricResolution);
8889
}
8990

9091
/// <summary>

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class MetricDefinition
2828
/// </summary>
2929
/// <param name="name">Metric name</param>
3030
/// <param name="value">Metric value</param>
31-
public MetricDefinition(string name, double value) : this(name, MetricUnit.None, new List<double> {value})
31+
public MetricDefinition(string name, double value) : this(name, MetricUnit.None, new List<double> {value}, MetricResolution.Standard)
3232
{
3333
}
3434

@@ -38,7 +38,8 @@ public class MetricDefinition
3838
/// <param name="name">Metric name</param>
3939
/// <param name="unit">Metric unit</param>
4040
/// <param name="value">Metric value</param>
41-
public MetricDefinition(string name, MetricUnit unit, double value) : this(name, unit, new List<double> {value})
41+
/// <param name="metricResolution">Metric resolution</param>
42+
public MetricDefinition(string name, MetricUnit unit, double value, MetricResolution metricResolution) : this(name, unit, new List<double> {value}, metricResolution)
4243
{
4344
}
4445

@@ -48,11 +49,13 @@ public class MetricDefinition
4849
/// <param name="name">Metric name</param>
4950
/// <param name="unit">Metric unit</param>
5051
/// <param name="values">List of metric values</param>
51-
public MetricDefinition(string name, MetricUnit unit, List<double> values)
52+
/// <param name="metricResolution">Metric resolution</param>
53+
public MetricDefinition(string name, MetricUnit unit, List<double> values, MetricResolution metricResolution)
5254
{
5355
Name = name;
5456
Unit = unit;
5557
Values = values;
58+
StorageResolution = metricResolution;
5659
}
5760

5861
/// <summary>
@@ -75,6 +78,13 @@ public MetricDefinition(string name, MetricUnit unit, List<double> values)
7578
/// <value>The unit.</value>
7679
[JsonPropertyName(nameof(Unit))]
7780
public MetricUnit Unit { get; set; }
81+
82+
/// <summary>
83+
/// Gets or sets the StorageResolution.
84+
/// </summary>
85+
/// <value>The unit.</value>
86+
[JsonPropertyName(nameof(StorageResolution))]
87+
public MetricResolution StorageResolution { get; set; }
7888

7989
/// <summary>
8090
/// Adds value to existing metric with same key

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,17 @@ public List<List<string>> AllDimensionKeys
133133
/// <param name="name">Metric name. Cannot be null, empty or whitespace</param>
134134
/// <param name="value">Metric value</param>
135135
/// <param name="unit">Metric unit</param>
136+
/// <param name="metricResolution">Metric Resolution, Standard (default), High</param>
136137
/// <exception cref="System.ArgumentOutOfRangeException">Metrics - Cannot add more than 100 metrics at the same time.</exception>
137-
public void AddMetric(string name, double value, MetricUnit unit)
138+
public void AddMetric(string name, double value, MetricUnit unit, MetricResolution metricResolution)
138139
{
139140
if (Metrics.Count < PowertoolsConfigurations.MaxMetrics)
140141
{
141142
var metric = Metrics.FirstOrDefault(m => m.Name == name);
142143
if (metric != null)
143144
metric.AddValue(value);
144145
else
145-
Metrics.Add(new MetricDefinition(name, unit, value));
146+
Metrics.Add(new MetricDefinition(name, unit, value, metricResolution));
146147
}
147148
else
148149
{
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Runtime.Serialization;
2+
using System.Text.Json.Serialization;
3+
4+
namespace AWS.Lambda.Powertools.Metrics;
5+
6+
/// <summary>
7+
/// Enum MetricResolution
8+
/// </summary>
9+
// [JsonConverter(typeof(StringEnumConverter))]
10+
public enum MetricResolution
11+
{
12+
/// <summary>
13+
/// Standard resolution, with data having a one-minute granularity
14+
/// </summary>
15+
Standard = 60,
16+
17+
/// <summary>
18+
/// High resolution, with data at a granularity of one second
19+
/// </summary>
20+
High = 1,
21+
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ internal void ClearNonDefaultDimensions()
8383
/// <param name="key">Metric key. Cannot be null, empty or whitespace</param>
8484
/// <param name="value">Metric value</param>
8585
/// <param name="unit">Metric unit</param>
86-
public void AddMetric(string key, double value, MetricUnit unit)
86+
/// <param name="metricResolution">Metric Resolution, Standard (default), High</param>
87+
public void AddMetric(string key, double value, MetricUnit unit, MetricResolution metricResolution)
8788
{
88-
_rootNode.AWS.AddMetric(key, value, unit);
89+
_rootNode.AWS.AddMetric(key, value, unit, metricResolution);
8990
}
9091

9192
/// <summary>

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

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public void WhenCaptureColdStartEnabled_ValidateExists()
103103
var result = consoleOut.ToString();
104104

105105
// Assert
106-
Assert.Contains("\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}]", result);
106+
Assert.Contains("\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\",\"StorageResolution\":60}]", result);
107107
Assert.Contains("\"ColdStart\":1", result);
108108

109109
handler.ResetForTest();
@@ -146,7 +146,7 @@ public void When100MetricsAreAdded_FlushAutomatically()
146146
var metricsOutput = consoleOut.ToString();
147147

148148
// Assert
149-
Assert.Contains("{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name 101\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"Service\"]", metricsOutput);
149+
Assert.Contains("{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Metric Name 101\",\"Unit\":\"Count\",\"StorageResolution\":60}],\"Dimensions\":[[\"Service\"]", metricsOutput);
150150

151151
// Reset
152152
handler.ResetForTest();
@@ -490,7 +490,7 @@ public void WhenMetricsAndMetadataAdded_ValidateOutput()
490490
var result = consoleOut.ToString();
491491

492492
// Assert
493-
Assert.Contains("CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\"}],\"Dimensions\":[[\"Service\"],[\"functionVersion\"]]}]},\"Service\":\"testService\",\"functionVersion\":\"$LATEST\",\"env\":\"dev\",\"Time\":100.7}"
493+
Assert.Contains("CloudWatchMetrics\":[{\"Namespace\":\"dotnet-powertools-test\",\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\",\"StorageResolution\":60}],\"Dimensions\":[[\"Service\"],[\"functionVersion\"]]}]},\"Service\":\"testService\",\"functionVersion\":\"$LATEST\",\"env\":\"dev\",\"Time\":100.7}"
494494
, result);
495495

496496
// Reset
@@ -531,14 +531,98 @@ public void WhenMetricsWithSameNameAdded_ValidateMetricArray()
531531
var result = consoleOut.ToString();
532532

533533
// Assert
534-
Assert.Contains("\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\"}]"
534+
Assert.Contains("\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\",\"StorageResolution\":60}]"
535535
, result);
536536
Assert.Contains("\"Time\":[100.5,200]"
537537
, result);
538538

539539
// Reset
540540
handler.ResetForTest();
541541
}
542+
543+
[Trait("Category", "MetricsImplementation")]
544+
[Fact]
545+
public void WhenMetricsWithStandardResolutionAdded_ValidateMetricArray()
546+
{
547+
// Arrange
548+
var methodName = Guid.NewGuid().ToString();
549+
var consoleOut = new StringWriter();
550+
Console.SetOut(consoleOut);
551+
552+
var configurations = new Mock<IPowertoolsConfigurations>();
553+
554+
var logger = new Metrics(
555+
configurations.Object,
556+
nameSpace: "dotnet-powertools-test",
557+
service: "testService"
558+
);
559+
560+
var handler = new MetricsAspectHandler(
561+
logger,
562+
false
563+
);
564+
565+
var eventArgs = new AspectEventArgs { Name = methodName };
566+
567+
// Act
568+
handler.OnEntry(eventArgs);
569+
Metrics.AddDimension("functionVersion", "$LATEST");
570+
Metrics.AddMetric("Time", 100.5, MetricUnit.Milliseconds, MetricResolution.Standard);
571+
handler.OnExit(eventArgs);
572+
573+
var result = consoleOut.ToString();
574+
575+
// Assert
576+
Assert.Contains("\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\",\"StorageResolution\":60}]"
577+
, result);
578+
Assert.Contains("\"Time\":100.5"
579+
, result);
580+
581+
// Reset
582+
handler.ResetForTest();
583+
}
584+
585+
[Trait("Category", "MetricsImplementation")]
586+
[Fact]
587+
public void WhenMetricsWithHighResolutionAdded_ValidateMetricArray()
588+
{
589+
// Arrange
590+
var methodName = Guid.NewGuid().ToString();
591+
var consoleOut = new StringWriter();
592+
Console.SetOut(consoleOut);
593+
594+
var configurations = new Mock<IPowertoolsConfigurations>();
595+
596+
var logger = new Metrics(
597+
configurations.Object,
598+
nameSpace: "dotnet-powertools-test",
599+
service: "testService"
600+
);
601+
602+
var handler = new MetricsAspectHandler(
603+
logger,
604+
false
605+
);
606+
607+
var eventArgs = new AspectEventArgs { Name = methodName };
608+
609+
// Act
610+
handler.OnEntry(eventArgs);
611+
Metrics.AddDimension("functionVersion", "$LATEST");
612+
Metrics.AddMetric("Time", 100.5, MetricUnit.Milliseconds, MetricResolution.High);
613+
handler.OnExit(eventArgs);
614+
615+
var result = consoleOut.ToString();
616+
617+
// Assert
618+
Assert.Contains("\"Metrics\":[{\"Name\":\"Time\",\"Unit\":\"Milliseconds\",\"StorageResolution\":1}]"
619+
, result);
620+
Assert.Contains("\"Time\":100.5"
621+
, result);
622+
623+
// Reset
624+
handler.ResetForTest();
625+
}
542626

543627
#region Helpers
544628

0 commit comments

Comments
 (0)