Skip to content

Commit 790a3b7

Browse files
authored
fix: Remove invalid trailing comma added to W3C tracestate header. (#1779)
1 parent 4b4e375 commit 790a3b7

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

src/Agent/NewRelic/Agent/Core/DistributedTracing/DistributedTracePayloadHandler.cs

+9-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using NewRelic.Core.Logging;
1313
using System;
1414
using System.Collections.Generic;
15+
using System.Linq;
1516

1617
namespace NewRelic.Agent.Core.DistributedTracing
1718
{
@@ -162,12 +163,15 @@ private string BuildTracestate(IInternalTransaction transaction, DateTime timest
162163
var newRelicTracestate = $"{accountKey}@nr={version}-{parentType}-{parentAccountId}-{appId}-{spanId}-{transactionId}-{sampled}-{priority}-{timestampInMillis}";
163164
var otherVendorTracestates = string.Empty;
164165

165-
if (transaction.TracingState != null)
166+
if (transaction.TracingState?.VendorStateEntries != null && transaction.TracingState.VendorStateEntries.Any())
166167
{
167-
if (transaction.TracingState.VendorStateEntries != null)
168-
{
169-
otherVendorTracestates = string.Join(",", transaction.TracingState.VendorStateEntries);
170-
}
168+
otherVendorTracestates = string.Join(",", transaction.TracingState.VendorStateEntries);
169+
}
170+
171+
// If otherVendorTracestates is null/empty we get a trailing comma.
172+
if (string.IsNullOrWhiteSpace(otherVendorTracestates))
173+
{
174+
return newRelicTracestate;
171175
}
172176

173177
return string.Join(",", newRelicTracestate, otherVendorTracestates);

tests/Agent/UnitTests/Core.UnitTest/Wrapper/AgentWrapperApi/DistributedTracing/DistributedTracePayloadHandlerTests.cs

+49
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,55 @@ public void TraceIdShouldBeSameForAllSpansWhenNoTraceIdReceived()
10311031

10321032
#endregion TraceID Tests
10331033

1034+
[TestCase(true)]
1035+
[TestCase(true, "")]
1036+
[TestCase(true, "k1=v1", "k2=v2")]
1037+
[TestCase(false)]
1038+
[TestCase(false, "")]
1039+
[TestCase(false, "k1=v1", "k2=v2")]
1040+
public void W3C_BuildTracestate_EmptyVendors_NoCommas(bool hasIncomingPayload, params string[] vendorState)
1041+
{
1042+
// Arrange
1043+
Mock.Arrange(() => _configuration.SpanEventsEnabled).Returns(true);
1044+
Mock.Arrange(() => _configuration.PayloadSuccessMetricsEnabled).Returns(true);
1045+
1046+
var transaction = BuildMockTransaction(hasIncomingPayload: hasIncomingPayload, sampled: true);
1047+
1048+
var transactionGuid = GuidGenerator.GenerateNewRelicGuid();
1049+
Mock.Arrange(() => transaction.Guid).Returns(transactionGuid);
1050+
1051+
var expectedSpanGuid = GuidGenerator.GenerateNewRelicGuid();
1052+
var segment = Mock.Create<ISegment>();
1053+
Mock.Arrange(() => segment.SpanId).Returns(expectedSpanGuid);
1054+
1055+
Mock.Arrange(() => transaction.CurrentSegment).Returns(segment);
1056+
1057+
var headers = new List<KeyValuePair<string, string>>();
1058+
var setHeaders = new Action<List<KeyValuePair<string, string>>, string, string>((carrier, key, value) =>
1059+
{
1060+
carrier.Add(new KeyValuePair<string, string>(key, value));
1061+
});
1062+
1063+
var tracingState = Mock.Create<ITracingState>();
1064+
1065+
var vendorStateEntries = vendorState.ToList();
1066+
1067+
Mock.Arrange(() => tracingState.VendorStateEntries).Returns(vendorStateEntries);
1068+
Mock.Arrange(() => transaction.TracingState).Returns(tracingState);
1069+
1070+
Mock.Arrange(() => transaction.InsertDistributedTraceHeaders(
1071+
Arg.IsAny<List<KeyValuePair<string, string>>>(),
1072+
Arg.IsAny<Action<List<KeyValuePair<string, string>>, string, string>>()))
1073+
.DoInstead(() => _distributedTracePayloadHandler.InsertDistributedTraceHeaders(transaction, headers, setHeaders));
1074+
1075+
// Act
1076+
transaction.InsertDistributedTraceHeaders(headers, setHeaders);
1077+
1078+
var tracestateHeaderValue = headers.Where(header => header.Key == TracestateHeaderName).Select(header => header.Value).FirstOrDefault();
1079+
1080+
Assert.That(!tracestateHeaderValue.EndsWith(","), "W3C Tracestate string has a trailing comma.");
1081+
}
1082+
10341083
#endregion
10351084

10361085
#region Supportability Metrics

0 commit comments

Comments
 (0)