Description
The ActivitySource.CreateActivity and ActivitySource.StartActivity APIs only return an Activity when there is a registered listener which decides the instance should be created. This is generally known as sampling.
The ActivitySamplingResult enum defines the possible sampling decisions.
When creating an Activity without a parent, ActivitySamplingResult drives whether the Activity is created and then how the Recorded and IsAllDataRequested properties are set:
| ActivitySamplingResult |
Activity created |
Activity.Recorded |
Activity.IsAllDataRequested |
| None |
No |
|
|
| PropagationData |
Yes |
False |
False |
| AllData |
Yes |
False |
True |
| AllDataAndRecorded |
Yes |
True |
True |
It is also possible to create an Activity with a parent. The parent could be in the same process, or it could be a remote parent propagated to the current process.
An issue was discovered where if the parent has Recorded=true AND the ActivitySamplingResult is PropagationData then the created Activity has a Recorded value which breaks with the above:
| ActivitySamplingResult |
Activity created |
Activity.Recorded |
Activity.IsAllDataRequested |
| PropagationData |
Yes |
True |
False |
This may cause issues for users:
-
OpenTelemetry .NET, for example, will capture/export any Activity with Recorded=true. An Activity sampled as PropagationData should not be recorded by definition.
-
When performing external operations (such as HTTP calls) the current Activity is propagated to downstream systems. A PropagationData Activity should be propagated, but the current design causes it to be propagated as Recorded which may lead downstream systems to treat the trace as sampled.
dotnet/runtime#111289 adjusts the logic as such:
| ActivitySamplingResult |
Activity created |
Activity.Recorded |
Activity.IsAllDataRequested |
| PropagationData |
Yes |
False |
False |
This is a breaking change but one that corrects the behavior following the OpenTelemetry Specification.
Version
.NET 10 Preview 1
Previous behavior
When creating an Activity as PropagationData with a parent marked as Recorded:
| ActivitySamplingResult |
Activity created |
Activity.Recorded |
Activity.IsAllDataRequested |
| PropagationData |
Yes |
True |
False |
New behavior
When creating an Activity as PropagationData with a parent marked as Recorded:
| ActivitySamplingResult |
Activity created |
Activity.Recorded |
Activity.IsAllDataRequested |
| PropagationData |
Yes |
False |
False |
Type of breaking change
Reason for change
The existing behavior does not follow the OpenTelemetry Specification.
Recommended action
Users who have implemented ActivityListener.Sample directly AND use ActivitySamplingResult.PropagationData should verify they are not reliant on the flawed behavior. Activity.ActivityTraceFlags may be set to Recorded after the CreateActivity or StartActivity call to restore the previous behavior.
Users using OpenTelemetry .NET should verify their sampler configuration. The default OpenTelemetry .NET configuration uses a parent-based algorithm which is not impacted. Only users who have customized the sampler should verify the behavior.
Feature area
Other (please put exact area in description textbox)
Affected APIs
ActivitySource.CreateActivity
ActivitySource.StartActivity
Associated WorkItem - 367791
Description
The
ActivitySource.CreateActivityandActivitySource.StartActivityAPIs only return anActivitywhen there is a registered listener which decides the instance should be created. This is generally known as sampling.The
ActivitySamplingResultenumdefines the possible sampling decisions.When creating an
Activitywithout a parent,ActivitySamplingResultdrives whether theActivityis created and then how theRecordedandIsAllDataRequestedproperties are set:It is also possible to create an
Activitywith a parent. The parent could be in the same process, or it could be a remote parent propagated to the current process.An issue was discovered where if the parent has
Recorded=trueAND theActivitySamplingResultisPropagationDatathen the createdActivityhas aRecordedvalue which breaks with the above:This may cause issues for users:
OpenTelemetry .NET, for example, will capture/export any
ActivitywithRecorded=true. AnActivitysampled asPropagationDatashould not be recorded by definition.When performing external operations (such as HTTP calls) the current
Activityis propagated to downstream systems. APropagationDataActivityshould be propagated, but the current design causes it to be propagated asRecordedwhich may lead downstream systems to treat the trace as sampled.dotnet/runtime#111289 adjusts the logic as such:
This is a breaking change but one that corrects the behavior following the OpenTelemetry Specification.
Version
.NET 10 Preview 1
Previous behavior
When creating an
ActivityasPropagationDatawith a parent marked asRecorded:New behavior
When creating an
ActivityasPropagationDatawith a parent marked asRecorded:Type of breaking change
Reason for change
The existing behavior does not follow the OpenTelemetry Specification.
Recommended action
Users who have implemented
ActivityListener.Sampledirectly AND useActivitySamplingResult.PropagationDatashould verify they are not reliant on the flawed behavior.Activity.ActivityTraceFlagsmay be set toRecordedafter theCreateActivityorStartActivitycall to restore the previous behavior.Users using OpenTelemetry .NET should verify their sampler configuration. The default OpenTelemetry .NET configuration uses a parent-based algorithm which is not impacted. Only users who have customized the sampler should verify the behavior.
Feature area
Other (please put exact area in description textbox)
Affected APIs
ActivitySource.CreateActivityActivitySource.StartActivityAssociated WorkItem - 367791