Skip to content

Commit a979415

Browse files
authored
Merge pull request #660 from hjgraca/fix(tracing)-revert-imethodaspecthander-removal
chore: Fix Lambda timeout with Tracing 1.5.1 using async methods
2 parents 4ab0fea + ba92787 commit a979415

File tree

6 files changed

+163
-138
lines changed

6 files changed

+163
-138
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
11
/*
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3-
*
3+
*
44
* Licensed under the Apache License, Version 2.0 (the "License").
55
* You may not use this file except in compliance with the License.
66
* A copy of the License is located at
7-
*
7+
*
88
* http://aws.amazon.com/apache2.0
9-
*
9+
*
1010
* or in the "license" file accompanying this file. This file is distributed
1111
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1212
* express or implied. See the License for the specific language governing
1313
* permissions and limitations under the License.
1414
*/
1515

1616
using System;
17-
using System.Linq;
1817
using System.Runtime.ExceptionServices;
1918
using System.Text;
20-
using AspectInjector.Broker;
2119
using AWS.Lambda.Powertools.Common;
2220

2321
namespace AWS.Lambda.Powertools.Tracing.Internal;
2422

2523
/// <summary>
26-
/// This aspect will automatically trace all function handlers.
27-
/// Scope.Global is singleton
24+
/// Class TracingAspectHandler.
25+
/// Implements the <see cref="IMethodAspectHandler" />
2826
/// </summary>
29-
[Aspect(Scope.Global)]
30-
public class TracingAspect
27+
/// <seealso cref="IMethodAspectHandler" />
28+
internal class TracingAspectHandler : IMethodAspectHandler
3129
{
3230
/// <summary>
3331
/// The Powertools for AWS Lambda (.NET) configurations
@@ -48,130 +46,120 @@ public class TracingAspect
4846
/// If true, capture annotations
4947
/// </summary>
5048
private static bool _captureAnnotations = true;
51-
49+
5250
/// <summary>
5351
/// If true, annotations have been captured
5452
/// </summary>
5553
private bool _isAnnotationsCaptured;
56-
54+
5755
/// <summary>
5856
/// Tracing namespace
5957
/// </summary>
60-
private string _namespace;
61-
58+
private readonly string _namespace;
59+
6260
/// <summary>
6361
/// The capture mode
6462
/// </summary>
65-
private TracingCaptureMode _captureMode;
63+
private readonly TracingCaptureMode _captureMode;
64+
65+
/// <summary>
66+
/// The segment name
67+
/// </summary>
68+
private readonly string _segmentName;
6669

6770
/// <summary>
68-
/// Initializes a new instance
71+
/// Initializes a new instance of the <see cref="TracingAspectHandler" /> class.
6972
/// </summary>
70-
public TracingAspect()
73+
/// <param name="segmentName">Name of the segment.</param>
74+
/// <param name="nameSpace">The namespace.</param>
75+
/// <param name="captureMode">The capture mode.</param>
76+
/// <param name="powertoolsConfigurations">The Powertools for AWS Lambda (.NET) configurations.</param>
77+
/// <param name="xRayRecorder">The X-Ray recorder.</param>
78+
internal TracingAspectHandler
79+
(
80+
string segmentName,
81+
string nameSpace,
82+
TracingCaptureMode captureMode,
83+
IPowertoolsConfigurations powertoolsConfigurations,
84+
IXRayRecorder xRayRecorder
85+
)
7186
{
72-
_xRayRecorder = XRayRecorder.Instance;
73-
_powertoolsConfigurations = PowertoolsConfigurations.Instance;
87+
_segmentName = segmentName;
88+
_namespace = nameSpace;
89+
_captureMode = captureMode;
90+
_powertoolsConfigurations = powertoolsConfigurations;
91+
_xRayRecorder = xRayRecorder;
7492
}
7593

7694
/// <summary>
77-
/// the code is executed instead of the target method.
78-
/// The call to original method is wrapped around the following code
79-
/// the original code is called with var result = target(args);
95+
/// Handles the <see cref="E:Entry" /> event.
8096
/// </summary>
81-
/// <param name="name"></param>
82-
/// <param name="args"></param>
83-
/// <param name="target"></param>
84-
/// <param name="triggers"></param>
85-
/// <returns></returns>
86-
[Advice(Kind.Around)]
87-
public object Around(
88-
[Argument(Source.Name)] string name,
89-
[Argument(Source.Arguments)] object[] args,
90-
[Argument(Source.Target)] Func<object[], object> target,
91-
[Argument(Source.Triggers)] Attribute[] triggers)
97+
/// <param name="eventArgs">
98+
/// The <see cref="T:AWS.Lambda.Powertools.Aspects.AspectEventArgs" /> instance containing the
99+
/// event data.
100+
/// </param>
101+
public void OnEntry(AspectEventArgs eventArgs)
92102
{
93-
// Before running Function
94-
95-
var trigger = triggers.OfType<TracingAttribute>().First();
96-
try
97-
{
98-
if (TracingDisabled())
99-
return target(args);
100-
101-
_namespace = trigger.Namespace;
102-
103-
var segmentName = !string.IsNullOrWhiteSpace(trigger.SegmentName) ? trigger.SegmentName : $"## {name}";
104-
var nameSpace = GetNamespace();
105-
106-
_xRayRecorder.BeginSubsegment(segmentName);
107-
_xRayRecorder.SetNamespace(nameSpace);
108-
109-
if (_captureAnnotations)
110-
{
111-
_xRayRecorder.AddAnnotation("ColdStart", _isColdStart);
112-
113-
_captureAnnotations = false;
114-
_isAnnotationsCaptured = true;
115-
116-
if (_powertoolsConfigurations.IsServiceDefined)
117-
_xRayRecorder.AddAnnotation("Service", _powertoolsConfigurations.Service);
118-
}
119-
120-
_isColdStart = false;
103+
if(TracingDisabled())
104+
return;
121105

122-
// return of the handler
123-
var result = target(args);
106+
var segmentName = !string.IsNullOrWhiteSpace(_segmentName) ? _segmentName : $"## {eventArgs.Name}";
107+
var nameSpace = GetNamespace();
124108

125-
// must get capture after all subsegments run
126-
_captureMode = trigger.CaptureMode;
109+
_xRayRecorder.BeginSubsegment(segmentName);
110+
_xRayRecorder.SetNamespace(nameSpace);
127111

128-
if (CaptureResponse())
129-
{
130-
_xRayRecorder.AddMetadata
131-
(
132-
nameSpace,
133-
$"{name} response",
134-
result
135-
);
136-
}
137-
138-
// after
139-
return result;
140-
}
141-
catch (Exception e)
112+
if (_captureAnnotations)
142113
{
143-
_captureMode = trigger.CaptureMode;
144-
HandleException(e, name);
145-
throw;
114+
_xRayRecorder.AddAnnotation("ColdStart", _isColdStart);
115+
116+
_captureAnnotations = false;
117+
_isAnnotationsCaptured = true;
118+
119+
if (_powertoolsConfigurations.IsServiceDefined)
120+
_xRayRecorder.AddAnnotation("Service", _powertoolsConfigurations.Service);
146121
}
122+
123+
_isColdStart = false;
147124
}
148125

149126
/// <summary>
150-
/// the code is injected after the method ends.
127+
/// Called when [success].
151128
/// </summary>
152-
[Advice(Kind.After)]
153-
public void OnExit()
129+
/// <param name="eventArgs">
130+
/// The <see cref="T:AWS.Lambda.Powertools.Aspects.AspectEventArgs" /> instance containing the
131+
/// event data.
132+
/// </param>
133+
/// <param name="result">The result.</param>
134+
public void OnSuccess(AspectEventArgs eventArgs, object result)
154135
{
155-
if (TracingDisabled())
156-
return;
157-
158-
if (_isAnnotationsCaptured)
159-
_captureAnnotations = true;
160-
161-
_xRayRecorder.EndSubsegment();
136+
if (CaptureResponse())
137+
{
138+
var nameSpace = GetNamespace();
139+
140+
_xRayRecorder.AddMetadata
141+
(
142+
nameSpace,
143+
$"{eventArgs.Name} response",
144+
result
145+
);
146+
}
162147
}
163148

164149
/// <summary>
165-
/// Code that handles when exceptions occur in the client method
150+
/// Called when [exception].
166151
/// </summary>
167-
/// <param name="exception"></param>
168-
/// <param name="name"></param>
169-
private void HandleException(Exception exception, string name)
152+
/// <param name="eventArgs">
153+
/// The <see cref="T:AWS.Lambda.Powertools.Aspects.AspectEventArgs" /> instance containing the
154+
/// event data.
155+
/// </param>
156+
/// <param name="exception">The exception.</param>
157+
public void OnException(AspectEventArgs eventArgs, Exception exception)
170158
{
171159
if (CaptureError())
172160
{
173161
var nameSpace = GetNamespace();
174-
162+
175163
var sb = new StringBuilder();
176164
sb.AppendLine($"Exception type: {exception.GetType()}");
177165
sb.AppendLine($"Exception message: {exception.Message}");
@@ -185,48 +173,45 @@ private void HandleException(Exception exception, string name)
185173
sb.AppendLine($"Stack trace: {exception.InnerException.StackTrace}");
186174
sb.AppendLine("---END Inner Exception");
187175
}
188-
176+
189177
_xRayRecorder.AddMetadata
190178
(
191179
nameSpace,
192-
$"{name} error",
180+
$"{eventArgs.Name} error",
193181
sb.ToString()
194182
);
195183
}
196184

197-
// // The purpose of ExceptionDispatchInfo.Capture is to capture a potentially mutating exception's StackTrace at a point in time:
198-
// // https://learn.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions#capture-exceptions-to-rethrow-later
185+
// The purpose of ExceptionDispatchInfo.Capture is to capture a potentially mutating exception's StackTrace at a point in time:
186+
// https://learn.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions#capture-exceptions-to-rethrow-later
199187
ExceptionDispatchInfo.Capture(exception).Throw();
200188
}
201189

202190
/// <summary>
203-
/// Gets the namespace.
191+
/// Handles the <see cref="E:Exit" /> event.
204192
/// </summary>
205-
/// <returns>System.String.</returns>
206-
private string GetNamespace()
193+
/// <param name="eventArgs">
194+
/// The <see cref="T:AWS.Lambda.Powertools.Aspects.AspectEventArgs" /> instance containing the
195+
/// event data.
196+
/// </param>
197+
public void OnExit(AspectEventArgs eventArgs)
207198
{
208-
return !string.IsNullOrWhiteSpace(_namespace) ? _namespace : _powertoolsConfigurations.Service;
199+
if(TracingDisabled())
200+
return;
201+
202+
if (_isAnnotationsCaptured)
203+
_captureAnnotations = true;
204+
205+
_xRayRecorder.EndSubsegment();
209206
}
210207

211208
/// <summary>
212-
/// Method that checks if tracing is disabled
209+
/// Gets the namespace.
213210
/// </summary>
214-
/// <returns></returns>
215-
private bool TracingDisabled()
211+
/// <returns>System.String.</returns>
212+
private string GetNamespace()
216213
{
217-
if (_powertoolsConfigurations.TracingDisabled)
218-
{
219-
Console.WriteLine("Tracing has been disabled via env var POWERTOOLS_TRACE_DISABLED");
220-
return true;
221-
}
222-
223-
if (!_powertoolsConfigurations.IsLambdaEnvironment)
224-
{
225-
Console.WriteLine("Running outside Lambda environment; disabling Tracing");
226-
return true;
227-
}
228-
229-
return false;
214+
return !string.IsNullOrWhiteSpace(_namespace) ? _namespace : _powertoolsConfigurations.Service;
230215
}
231216

232217
/// <summary>
@@ -235,6 +220,9 @@ private bool TracingDisabled()
235220
/// <returns><c>true</c> if tracing should capture responses, <c>false</c> otherwise.</returns>
236221
private bool CaptureResponse()
237222
{
223+
if(TracingDisabled())
224+
return false;
225+
238226
switch (_captureMode)
239227
{
240228
case TracingCaptureMode.EnvironmentVariable:
@@ -255,9 +243,9 @@ private bool CaptureResponse()
255243
/// <returns><c>true</c> if tracing should capture errors, <c>false</c> otherwise.</returns>
256244
private bool CaptureError()
257245
{
258-
if (TracingDisabled())
246+
if(TracingDisabled())
259247
return false;
260-
248+
261249
switch (_captureMode)
262250
{
263251
case TracingCaptureMode.EnvironmentVariable:
@@ -271,7 +259,28 @@ private bool CaptureError()
271259
return false;
272260
}
273261
}
262+
263+
/// <summary>
264+
/// Tracing disabled.
265+
/// </summary>
266+
/// <returns><c>true</c> if tracing is disabled, <c>false</c> otherwise.</returns>
267+
private bool TracingDisabled()
268+
{
269+
if (_powertoolsConfigurations.TracingDisabled)
270+
{
271+
Console.WriteLine("Tracing has been disabled via env var POWERTOOLS_TRACE_DISABLED");
272+
return true;
273+
}
274+
275+
if (!_powertoolsConfigurations.IsLambdaEnvironment)
276+
{
277+
Console.WriteLine("Running outside Lambda environment; disabling Tracing");
278+
return true;
279+
}
274280

281+
return false;
282+
}
283+
275284
/// <summary>
276285
/// Resets static variables for test.
277286
/// </summary>
@@ -280,4 +289,4 @@ internal static void ResetForTest()
280289
_isColdStart = true;
281290
_captureAnnotations = true;
282291
}
283-
}
292+
}

0 commit comments

Comments
 (0)