Skip to content

Commit a1ae03a

Browse files
authored
Merge pull request #613 from hjgraca/fix-metrics-resolution-context
chore: Fix metrics lambda context and storage resolution
2 parents 33546b4 + 7f4d676 commit a1ae03a

File tree

10 files changed

+205
-119
lines changed

10 files changed

+205
-119
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@
1111
<ProjectReference Include="..\AWS.Lambda.Powertools.Common\AWS.Lambda.Powertools.Common.csproj" PrivateAssets="All" />
1212
</ItemGroup>
1313

14+
<ItemGroup>
15+
<PackageReference Include="Amazon.Lambda.Core" />
16+
</ItemGroup>
17+
1418
</Project>

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

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Collections.Generic;
1818
using System.Linq;
1919
using System.Reflection;
20+
using Amazon.Lambda.Core;
2021
using AspectInjector.Broker;
2122
using AWS.Lambda.Powertools.Common;
2223

@@ -34,11 +35,6 @@ public class MetricsAspect
3435
/// </summary>
3536
private static bool _isColdStart;
3637

37-
/// <summary>
38-
/// Specify to clear Lambda Context on exit
39-
/// </summary>
40-
private bool _clearLambdaContext;
41-
4238
/// <summary>
4339
/// Gets the metrics instance.
4440
/// </summary>
@@ -100,14 +96,14 @@ public void Before(
10096
var nameSpace = _metricsInstance.GetNamespace();
10197
var service = _metricsInstance.GetService();
10298
Dictionary<string, string> dimensions = null;
103-
104-
_clearLambdaContext = PowertoolsLambdaContext.Extract(eventArgs);
105-
106-
if (PowertoolsLambdaContext.Instance is not null)
99+
100+
var context = GetContext(eventArgs);
101+
102+
if (context is not null)
107103
{
108104
dimensions = new Dictionary<string, string>
109105
{
110-
{ "FunctionName", PowertoolsLambdaContext.Instance.FunctionName }
106+
{ "FunctionName", context.FunctionName }
111107
};
112108
}
113109

@@ -129,8 +125,6 @@ public void Before(
129125
public void Exit()
130126
{
131127
_metricsInstance.Flush();
132-
if (_clearLambdaContext)
133-
PowertoolsLambdaContext.Clear();
134128
}
135129

136130

@@ -142,6 +136,21 @@ internal static void ResetForTest()
142136
_metricsInstance = null;
143137
_isColdStart = true;
144138
Metrics.ResetForTest();
145-
PowertoolsLambdaContext.Clear();
139+
}
140+
141+
/// <summary>
142+
/// Gets the Lambda context
143+
/// </summary>
144+
/// <param name="args"></param>
145+
/// <returns></returns>
146+
private static ILambdaContext GetContext(AspectEventArgs args)
147+
{
148+
var index = Array.FindIndex(args.Method.GetParameters(), p => p.ParameterType == typeof(ILambdaContext));
149+
if (index >= 0)
150+
{
151+
return (ILambdaContext)args.Args[index];
152+
}
153+
154+
return null;
146155
}
147156
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
using System.Runtime.Serialization;
21
using System.Text.Json.Serialization;
32

43
namespace AWS.Lambda.Powertools.Metrics;
54

65
/// <summary>
76
/// Enum MetricResolution
87
/// </summary>
8+
[JsonConverter(typeof(MetricResolutionJsonConverter))]
99
public enum MetricResolution
1010
{
1111
/// <summary>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace AWS.Lambda.Powertools.Metrics;
2424
#if NET8_0_OR_GREATER
2525
[JsonConverter(typeof(JsonStringEnumConverter<MetricUnit>))]
2626
#else
27-
[JsonConverter(typeof(StringEnumConverter))]
27+
[JsonConverter(typeof(JsonStringEnumConverter))]
2828
#endif
2929
public enum MetricUnit
3030
{
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Text.Json;
3+
using System.Text.Json.Serialization;
4+
5+
namespace AWS.Lambda.Powertools.Metrics;
6+
7+
/// <summary>
8+
/// Class MetricResolutionJsonConverter.
9+
/// Implements the <see cref="System.Text.Json.Serialization.JsonConverter{T}" />
10+
/// </summary>
11+
/// <seealso cref="System.Text.Json.Serialization.JsonConverter{T}" />
12+
public class MetricResolutionJsonConverter : JsonConverter<MetricResolution>
13+
{
14+
/// <summary>
15+
/// Reads the JSON representation of the object.
16+
/// </summary>
17+
/// <param name="reader">The <see cref="T:Utf8JsonReader" /> to read from.</param>
18+
/// <param name="typeToConvert">The <see cref="T:System.Type" /> being converted.</param>
19+
/// <param name="options">The <see cref="T:Utf8JsonSerializerOptions" /> being used.</param>
20+
/// <returns>The object value.</returns>
21+
public override MetricResolution Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
22+
{
23+
if (reader.TokenType == JsonTokenType.String)
24+
{
25+
var stringValue = reader.GetString();
26+
if (int.TryParse(stringValue, out int value))
27+
{
28+
return (MetricResolution)value;
29+
}
30+
}
31+
else if (reader.TokenType == JsonTokenType.Number)
32+
{
33+
return (MetricResolution)reader.GetInt32();
34+
}
35+
36+
throw new JsonException();
37+
}
38+
39+
/// <summary>
40+
/// Writes the JSON representation of the object.
41+
/// </summary>
42+
/// <param name="writer">The <see cref="T:Utf8JsonWriter" /> to write to.</param>
43+
/// <param name="value">The value to convert.</param>
44+
/// <param name="options">The <see cref="T:Utf8JsonSerializerOptions" /> being used.</param>
45+
public override void Write(Utf8JsonWriter writer, MetricResolution value, JsonSerializerOptions options)
46+
{
47+
writer.WriteNumberValue((int)value);
48+
}
49+
}

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

Lines changed: 0 additions & 102 deletions
This file was deleted.

libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandler.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,14 @@ public void HandleWithLambdaContext(ILambdaContext context)
169169
}
170170

171171
[Metrics(Namespace = "ns", Service = "svc")]
172-
public void HandleWithLambdaContextAndMetrics(TestLambdaContext context)
172+
public void HandleColdStartNoContext()
173173
{
174174
Metrics.AddMetric("MyMetric", 1);
175175
}
176+
177+
[Metrics(Namespace = "ns", Service = "svc", CaptureColdStart = true)]
178+
public void HandleWithParamAndLambdaContext(string input, ILambdaContext context)
179+
{
180+
181+
}
176182
}

libraries/tests/AWS.Lambda.Powertools.Metrics.Tests/Handlers/FunctionHandlerTests.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,46 @@ public void When_LambdaContext_Should_Add_FunctioName_Dimension_CaptureColdStart
8888
"\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"FunctionName\"],[\"Service\"]]}]}",
8989
metricsOutput);
9090
}
91+
92+
[Fact]
93+
public void When_LambdaContext_And_Parameter_Should_Add_FunctioName_Dimension_CaptureColdStart()
94+
{
95+
// Arrange
96+
var context = new TestLambdaContext
97+
{
98+
FunctionName = "My Function with context"
99+
};
100+
101+
// Act
102+
_handler.HandleWithParamAndLambdaContext("Hello",context);
103+
var metricsOutput = _consoleOut.ToString();
104+
105+
// Assert
106+
Assert.Contains(
107+
"\"FunctionName\":\"My Function with context\"",
108+
metricsOutput);
109+
110+
Assert.Contains(
111+
"\"Metrics\":[{\"Name\":\"ColdStart\",\"Unit\":\"Count\"}],\"Dimensions\":[[\"FunctionName\"],[\"Service\"]]}]}",
112+
metricsOutput);
113+
}
114+
115+
[Fact]
116+
public void When_No_LambdaContext_Should_Not_Add_FunctioName_Dimension_CaptureColdStart()
117+
{
118+
// Act
119+
_handler.HandleColdStartNoContext();
120+
var metricsOutput = _consoleOut.ToString();
121+
122+
// Assert
123+
Assert.DoesNotContain(
124+
"\"FunctionName\"",
125+
metricsOutput);
126+
127+
Assert.Contains(
128+
"\"Metrics\":[{\"Name\":\"MyMetric\",\"Unit\":\"None\"}],\"Dimensions\":[[\"Service\"]]}]},\"Service\":\"svc\",\"MyMetric\":1}",
129+
metricsOutput);
130+
}
91131

92132
public void Dispose()
93133
{

0 commit comments

Comments
 (0)