Skip to content

Commit

Permalink
fix: Remove invalid trailing comma added to W3C tracestate header. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jaffinito committed Jul 14, 2023
1 parent 4b4e375 commit 790a3b7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
Expand Up @@ -12,6 +12,7 @@
using NewRelic.Core.Logging;
using System;
using System.Collections.Generic;
using System.Linq;

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

if (transaction.TracingState != null)
if (transaction.TracingState?.VendorStateEntries != null && transaction.TracingState.VendorStateEntries.Any())
{
if (transaction.TracingState.VendorStateEntries != null)
{
otherVendorTracestates = string.Join(",", transaction.TracingState.VendorStateEntries);
}
otherVendorTracestates = string.Join(",", transaction.TracingState.VendorStateEntries);
}

// If otherVendorTracestates is null/empty we get a trailing comma.
if (string.IsNullOrWhiteSpace(otherVendorTracestates))
{
return newRelicTracestate;
}

return string.Join(",", newRelicTracestate, otherVendorTracestates);
Expand Down
Expand Up @@ -1031,6 +1031,55 @@ public void TraceIdShouldBeSameForAllSpansWhenNoTraceIdReceived()

#endregion TraceID Tests

[TestCase(true)]
[TestCase(true, "")]
[TestCase(true, "k1=v1", "k2=v2")]
[TestCase(false)]
[TestCase(false, "")]
[TestCase(false, "k1=v1", "k2=v2")]
public void W3C_BuildTracestate_EmptyVendors_NoCommas(bool hasIncomingPayload, params string[] vendorState)
{
// Arrange
Mock.Arrange(() => _configuration.SpanEventsEnabled).Returns(true);
Mock.Arrange(() => _configuration.PayloadSuccessMetricsEnabled).Returns(true);

var transaction = BuildMockTransaction(hasIncomingPayload: hasIncomingPayload, sampled: true);

var transactionGuid = GuidGenerator.GenerateNewRelicGuid();
Mock.Arrange(() => transaction.Guid).Returns(transactionGuid);

var expectedSpanGuid = GuidGenerator.GenerateNewRelicGuid();
var segment = Mock.Create<ISegment>();
Mock.Arrange(() => segment.SpanId).Returns(expectedSpanGuid);

Mock.Arrange(() => transaction.CurrentSegment).Returns(segment);

var headers = new List<KeyValuePair<string, string>>();
var setHeaders = new Action<List<KeyValuePair<string, string>>, string, string>((carrier, key, value) =>
{
carrier.Add(new KeyValuePair<string, string>(key, value));
});

var tracingState = Mock.Create<ITracingState>();

var vendorStateEntries = vendorState.ToList();

Mock.Arrange(() => tracingState.VendorStateEntries).Returns(vendorStateEntries);
Mock.Arrange(() => transaction.TracingState).Returns(tracingState);

Mock.Arrange(() => transaction.InsertDistributedTraceHeaders(
Arg.IsAny<List<KeyValuePair<string, string>>>(),
Arg.IsAny<Action<List<KeyValuePair<string, string>>, string, string>>()))
.DoInstead(() => _distributedTracePayloadHandler.InsertDistributedTraceHeaders(transaction, headers, setHeaders));

// Act
transaction.InsertDistributedTraceHeaders(headers, setHeaders);

var tracestateHeaderValue = headers.Where(header => header.Key == TracestateHeaderName).Select(header => header.Value).FirstOrDefault();

Assert.That(!tracestateHeaderValue.EndsWith(","), "W3C Tracestate string has a trailing comma.");
}

#endregion

#region Supportability Metrics
Expand Down

0 comments on commit 790a3b7

Please sign in to comment.