Skip to content

[API Proposal]: Activity.IsStopped (functionality required to conform to OpenTelemetry specification) #63353

@Oberon00

Description

@Oberon00

Background and motivation

As far as I know, the Activity class is meant to provide all the functionality required by the OpenTelemetry tracing specification for the concept that is called "Span" in OTel terms.

However, I could not find a way to get the following from Activity:

It must also be able to reliably determine whether the Span has ended (some languages might implement this by having an end timestamp of null, others might have an explicit hasEnded boolean).

-- https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/trace/sdk.md#additional-span-interfaces

At first, I thought one could check if Activity.Duration != TimeSpan.Zero, but while this is indeed true for all stopped/ended activities, even activities that are still running can have a non-zero duration if SetEndTime was called but Stop/Dispose was not.

In some situations, one could could use the callback from the Source and maintain a ConditionalWeakTable to record whether an Activity has stopped, but this is rather cumbersome, slow and not possible if you do not have control over the activities' source.

It seems that Activity already has this implemented as private functinality as a property IsFinished: https://github.com/dotnet/runtime/blob/v6.0.1/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs#L1301-L1303

Exposing the existing name IsFinished would also be an acceptable IMHO (I think the most OTel-like name would be HasEnded, but since End is called Stop, my primary suggestion is IsStopped).

The interface in OpenTelemetry Java is here https://github.com/open-telemetry/opentelemetry-java/blob/v1.9.1/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/ReadableSpan.java#L64-L71 and here https://github.com/open-telemetry/opentelemetry-java/blob/v1.9.1/sdk/trace/src/main/java/io/opentelemetry/sdk/trace/data/SpanData.java#L117-L122

API Proposal

namespace System.Diagnostics
{
    public class Activity: IDisposable
    {
        // ...
        public bool IsStopped { get; }
        // ...
    }
}

API Usage

var a = new Activity("foo");
Debug.Assert(!a.IsStopped);
a.Start();
Debug.Assert(!a.IsStopped);
a.Stop();
Debug.Assert(a.IsStopped);

In an ActivityListener.ActivityStopped callback, IsStopped of the notifying Activity must also be true to conform to OTel semantics.

Alternative Designs

If SetEndTime would always unconditionally Stop the activity, the check for nonzero Duration could be used instead of using a separate property. However, that would probably be an unacceptable breaking change. Note: The XML doc of Duration claims that calling SetEndTime ends the activity (is ending the same as stopping?) but unless Duration != Zero does logically end the activity (without invoking a listener), this does not seem to be true.

Alternative Workaround

OpenTelemetry SDK is already listening to Activity Start and Stop events, it can manually either create a weak reference table mapping the Activity object to its wrapper span object and then mark the span ended when receiving Stop event. Another idea is to set some property/tag value on the Activity when receiving the stop event. These are not clean solutions considering the simplicity we'll get if we added the proposed API.

Risks

None known. This proposal would add a new property exposing existing functionality that is required as an API surface by the OpenTelemetry specification.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions