diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs index fd218a7dbf9df..2a1c68004026a 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/ref/System.Diagnostics.DiagnosticSourceActivity.cs @@ -214,6 +214,7 @@ public readonly struct ActivityEvent public string? TraceState { get { throw null; } } public bool IsRemote { get { throw null; } } public static bool TryParse(string? traceParent, string? traceState, out System.Diagnostics.ActivityContext context) { throw null; } + public static bool TryParse(string? traceParent, string? traceState, bool isRemote, out System.Diagnostics.ActivityContext context) { throw null; } public static System.Diagnostics.ActivityContext Parse(string traceParent, string? traceState) { throw null; } public static bool operator ==(System.Diagnostics.ActivityContext left, System.Diagnostics.ActivityContext right) { throw null; } public static bool operator !=(System.Diagnostics.ActivityContext left, System.Diagnostics.ActivityContext right) { throw null; } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs index 72c8a20bb7745..e71b79e9b93a5 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs @@ -920,7 +920,7 @@ private static bool IsW3CId(string id) #if ALLOW_PARTIALLY_TRUSTED_CALLERS [System.Security.SecuritySafeCriticalAttribute] #endif - internal static bool TryConvertIdToContext(string traceParent, string? traceState, out ActivityContext context) + internal static bool TryConvertIdToContext(string traceParent, string? traceState, bool isRemote, out ActivityContext context) { context = default; if (!IsW3CId(traceParent)) @@ -941,7 +941,8 @@ internal static bool TryConvertIdToContext(string traceParent, string? traceStat new ActivityTraceId(traceIdSpan.ToString()), new ActivitySpanId(spanIdSpan.ToString()), (ActivityTraceFlags) ActivityTraceId.HexByteFromChars(traceParent[53], traceParent[54]), - traceState); + traceState, + isRemote); return true; } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs index 93661f5d84135..55cacc67053ea 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityContext.cs @@ -65,8 +65,9 @@ public ActivityContext(ActivityTraceId traceId, ActivitySpanId spanId, ActivityT /// /// W3C trace parent header. /// W3C trace state. + /// Indicate the context is propagated from remote parent. /// The ActivityContext object created from the parsing operation. - public static bool TryParse(string? traceParent, string? traceState, out ActivityContext context) + public static bool TryParse(string? traceParent, string? traceState, bool isRemote, out ActivityContext context) { if (traceParent is null) { @@ -74,9 +75,17 @@ public static bool TryParse(string? traceParent, string? traceState, out Activit return false; } - return Activity.TryConvertIdToContext(traceParent, traceState, out context); + return Activity.TryConvertIdToContext(traceParent, traceState, isRemote, out context); } + /// + /// Parse W3C trace context headers to ActivityContext object. + /// + /// W3C trace parent header. + /// W3C trace state. + /// The ActivityContext object created from the parsing operation. + public static bool TryParse(string? traceParent, string? traceState, out ActivityContext context) => TryParse(traceParent, traceState, isRemote: false, out context); + /// /// Parse W3C trace context headers to ActivityContext object. /// @@ -92,7 +101,7 @@ public static ActivityContext Parse(string traceParent, string? traceState) throw new ArgumentNullException(nameof(traceParent)); } - if (!Activity.TryConvertIdToContext(traceParent, traceState, out ActivityContext context)) + if (!Activity.TryConvertIdToContext(traceParent, traceState, isRemote: false, out ActivityContext context)) { throw new ArgumentException(SR.InvalidTraceParent); } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/PassThroughPropagator.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/PassThroughPropagator.cs index 12515555fcf46..a8aec1bb72cfc 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/PassThroughPropagator.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/PassThroughPropagator.cs @@ -52,7 +52,7 @@ private static void GetRootId(out string? parentId, out string? traceState, out traceState = activity?.TraceStateString; parentId = activity?.ParentId ?? activity?.Id; - isW3c = parentId is not null ? Activity.TryConvertIdToContext(parentId, traceState, out _) : false; + isW3c = parentId is not null ? Activity.TryConvertIdToContext(parentId, traceState, isRemote: false, out _) : false; baggage = activity?.Baggage; } } diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs index edc695503c373..8468ce541c1b3 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/ActivitySourceTests.cs @@ -470,15 +470,32 @@ public void TestActivityContextParsing() Assert.Equal("e82825765f051b47", context.SpanId.ToHexString()); Assert.Equal(ActivityTraceFlags.Recorded, context.TraceFlags); Assert.Equal("k=v", context.TraceState); + Assert.False(context.IsRemote); + + Assert.True(ActivityContext.TryParse(w3cId, "k=v", isRemote: true, out context)); + Assert.Equal("99d43cb30a4cdb4fbeee3a19c29201b0", context.TraceId.ToHexString()); + Assert.Equal("e82825765f051b47", context.SpanId.ToHexString()); + Assert.Equal(ActivityTraceFlags.Recorded, context.TraceFlags); + Assert.Equal("k=v", context.TraceState); + Assert.True(context.IsRemote); + + Assert.True(ActivityContext.TryParse(w3cId, "k=v", isRemote: false, out context)); + Assert.Equal("99d43cb30a4cdb4fbeee3a19c29201b0", context.TraceId.ToHexString()); + Assert.Equal("e82825765f051b47", context.SpanId.ToHexString()); + Assert.Equal(ActivityTraceFlags.Recorded, context.TraceFlags); + Assert.Equal("k=v", context.TraceState); + Assert.False(context.IsRemote); context = ActivityContext.Parse(w3cId, "k=v"); Assert.Equal("99d43cb30a4cdb4fbeee3a19c29201b0", context.TraceId.ToHexString()); Assert.Equal("e82825765f051b47", context.SpanId.ToHexString()); Assert.Equal(ActivityTraceFlags.Recorded, context.TraceFlags); Assert.Equal("k=v", context.TraceState); + Assert.False(context.IsRemote); context = ActivityContext.Parse(w3cId, null); Assert.Null(context.TraceState); + Assert.False(context.IsRemote); Assert.False(ActivityContext.TryParse(null, "k=v", out context)); Assert.Throws(() => ActivityContext.Parse(null, null)); @@ -486,6 +503,8 @@ public void TestActivityContextParsing() const string invalidW3CContext = "00-Z9d43cb30a4cdb4fbeee3a19c29201b0-e82825765f051b47-01"; Assert.False(ActivityContext.TryParse(invalidW3CContext, null, out context)); + Assert.False(ActivityContext.TryParse(invalidW3CContext, null, isRemote: true, out context)); + Assert.False(ActivityContext.TryParse(invalidW3CContext, null, isRemote: false, out context)); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]