diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index e3bb30d9cea2bc..14151e077022c9 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -25,13 +25,12 @@ - + + - + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityListener.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityListener.cs index 5c07128a2d0c14..b308a86aad5ee4 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityListener.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivityListener.cs @@ -46,7 +46,7 @@ public ActivityListener() /// /// Set or get the callback used to decide allowing creating objects with specific data state. /// - public GetRequestedData? GetRequestedDataUsingContext { get; set; } + public GetRequestedData? GetRequestedDataUsingContext { get; set; } /// /// Dispose will unregister this object from listeneing to events. diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs index becd3467a06e14..13b013ea218021 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ActivitySource.cs @@ -133,12 +133,19 @@ public bool HasListeners() } else { - ActivityContext initializedContext = context == default && Activity.Current != null ? Activity.Current.Context : context; - listeners.EnumWithFunc(listener => { + ParentActivityState parentActivityState = BuildParentActivityState(context); + listeners.EnumWithFunc(listener => + { var getRequestedDataUsingContext = listener.GetRequestedDataUsingContext; if (getRequestedDataUsingContext != null) { - ActivityCreationOptions aco = new ActivityCreationOptions(this, name, initializedContext, kind, tags, links); + ActivityCreationOptions aco = new ActivityCreationOptions( + this, + name, + parentActivityState, + kind, + tags, + links); ActivityDataRequest dr = getRequestedDataUsingContext(ref aco); if (dr > dataRequest) { @@ -242,6 +249,26 @@ internal void NotifyActivityStop(Activity activity) listeners.EnumWithAction(listener => listener.ActivityStopped?.Invoke(activity)); } } + + private static ParentActivityState BuildParentActivityState(ActivityContext context) + { + bool isDefaultContext = context == default; + + Activity? currentActivity = Activity.Current; + ActivityContext initializedContext = !isDefaultContext + ? context + : currentActivity?.Context ?? context; + + ActivityDataRequest parentDataRequested = isDefaultContext + ? ActivityDataRequest.None + : (initializedContext.TraceFlags & ActivityTraceFlags.Recorded) == ActivityTraceFlags.Recorded + ? ActivityDataRequest.AllDataAndRecorded + : currentActivity?.IsAllDataRequested == true + ? ActivityDataRequest.AllData + : ActivityDataRequest.PropagationData; + + return new ParentActivityState(parentDataRequested, initializedContext); + } } // SynchronizedList is a helper collection which ensure thread safety on the collection diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ParentActivityState.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ParentActivityState.cs new file mode 100644 index 00000000000000..3d7e4e8266a995 --- /dev/null +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/ParentActivityState.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Diagnostics +{ + public readonly struct ParentActivityState : IEquatable + { + public ParentActivityState(ActivityDataRequest requestedData, ActivityContext activityContext) + { + RequestedData = requestedData; + ActivityContext = activityContext; + } + + public ActivityDataRequest RequestedData { get; } + + public ActivityContext ActivityContext { get; } + + public bool Equals(ParentActivityState other) => ActivityContext.Equals(other.ActivityContext) && RequestedData == other.RequestedData; + + public override int GetHashCode() => HashCode.Combine(RequestedData, ActivityContext); + + public override bool Equals(object? obj) => (obj is ParentActivityState context) && Equals(context); + public static bool operator ==(ParentActivityState left, ParentActivityState right) => left.Equals(right); + public static bool operator !=(ParentActivityState left, ParentActivityState right) => !(left == right); + } +}