Skip to content

[Breaking change]: Activity.Recorded behavior change for PropagationData sampling result with Recorded parent #44282

@CodeBlanch

Description

@CodeBlanch

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

  • Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
  • Behavioral change: Existing binaries might behave differently at run time.

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

Metadata

Metadata

Assignees

Labels

🏁 Release: .NET 10Work items for the .NET 10 release📌 seQUESTeredIdentifies that an issue has been imported into Quest.breaking-changeIndicates a .NET Core breaking changein-prThis issue will be closed (fixed) by an active pull request.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions