Skip to content

Commit 4e154a9

Browse files
authored
Merge pull request #741 from hjgraca/fix(tracing)-invalid-sement-name
chore: Tracing Sanitize SegmentName to avoid unsupported characters
2 parents f0aa415 + 2ac7b48 commit 4e154a9

File tree

5 files changed

+64
-3
lines changed

5 files changed

+64
-3
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.Text.RegularExpressions;
3+
4+
namespace AWS.Lambda.Powertools.Tracing.Internal;
5+
6+
/// <summary>
7+
/// Helper class
8+
/// </summary>
9+
public static class Helpers
10+
{
11+
/// <summary>
12+
/// Sanitize a string by removing any characters that are not alphanumeric, whitespace, or one of the following: _ . : / % & # = + - @
13+
/// </summary>
14+
/// <param name="input"></param>
15+
/// <returns></returns>
16+
public static string SanitizeString(string input)
17+
{
18+
// Define a regular expression pattern to match allowed characters
19+
var pattern = @"[^a-zA-Z0-9\s_\.\:/%&#=+\-@]";
20+
21+
// Replace any character that does not match the pattern with an empty string, with a timeout
22+
return Regex.Replace(input, pattern, string.Empty, RegexOptions.None, TimeSpan.FromMilliseconds(100));
23+
}
24+
}

libraries/src/AWS.Lambda.Powertools.Tracing/Internal/XRayRecorder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ public XRayRecorder(IAWSXRayRecorder awsxRayRecorder, IPowertoolsConfigurations
7878
public void BeginSubsegment(string name)
7979
{
8080
if (_isLambda)
81-
_awsxRayRecorder.BeginSubsegment(name);
81+
{
82+
_awsxRayRecorder.BeginSubsegment(Helpers.SanitizeString(name));
83+
}
8284
}
8385

8486
/// <summary>

libraries/src/AWS.Lambda.Powertools.Tracing/TracingAttribute.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
using System;
1717
using AspectInjector.Broker;
18-
using AWS.Lambda.Powertools.Common;
1918
using AWS.Lambda.Powertools.Tracing.Internal;
2019

2120
namespace AWS.Lambda.Powertools.Tracing;
@@ -114,8 +113,10 @@ public class TracingAttribute : Attribute
114113
/// <summary>
115114
/// Set custom segment name for the operation.
116115
/// The default is '## {MethodName}'.
116+
///
117+
/// The logical name of the service that handled the request, up to 200 characters.
118+
/// Names can contain Unicode letters, numbers, and whitespace, and the following symbols: \_, ., :, /, %, &amp;, #, =, +, \\, -, @
117119
/// </summary>
118-
/// <value>The name of the segment.</value>
119120
public string SegmentName { get; set; } = "";
120121

121122
/// <summary>

libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/Handlers/Handlers.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ public void HandleWithSegmentName()
3131

3232
}
3333

34+
[Tracing(SegmentName = "## <<Main>$>g__Handler|0_0")]
35+
public void HandleWithInvalidSegmentName()
36+
{
37+
MethodWithInvalidSegmentName();
38+
}
39+
40+
[Tracing(SegmentName = "Inval$#id | <Segment>")]
41+
private void MethodWithInvalidSegmentName()
42+
{
43+
44+
}
45+
3446
[Tracing(Namespace = "Namespace Defined")]
3547
public void HandleWithNamespace()
3648
{

libraries/tests/AWS.Lambda.Powertools.Tracing.Tests/TracingAttributeTest.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,28 @@ public void OnEntry_WhenSegmentNameHasValue_BeginSubsegmentWithValue()
256256
Assert.Single(segment.Subsegments);
257257
Assert.Equal("SegmentName", subSegment.Name);
258258
}
259+
260+
[Fact]
261+
public void OnEntry_WhenSegmentName_Is_Unsupported()
262+
{
263+
// Arrange
264+
Environment.SetEnvironmentVariable("LAMBDA_TASK_ROOT", "AWS");
265+
Environment.SetEnvironmentVariable("POWERTOOLS_SERVICE_NAME", "POWERTOOLS");
266+
267+
// Act
268+
var segment = AWSXRayRecorder.Instance.TraceContext.GetEntity();
269+
_handler.HandleWithInvalidSegmentName();
270+
var subSegment = segment.Subsegments[0];
271+
var childSegment = subSegment.Subsegments[0];
272+
273+
// Assert
274+
Assert.True(segment.IsSubsegmentsAdded);
275+
Assert.True(subSegment.IsSubsegmentsAdded);
276+
Assert.Single(segment.Subsegments);
277+
Assert.Single(subSegment.Subsegments);
278+
Assert.Equal("## Maing__Handler0_0", subSegment.Name);
279+
Assert.Equal("Inval#id Segment", childSegment.Name);
280+
}
259281

260282
[Fact]
261283
public void OnEntry_WhenNamespaceIsNull_SetNamespaceWithService()

0 commit comments

Comments
 (0)