runtime: Allow to specify ActivityContext of new Activity to StartActivity(..) to unblock interop with real-world vendors

Another one 😃 (On a personal note: I really wished we had started this work stream at the OTel group earlier, so that these requests had more chance to flow into .NET 5, but I believe that it still has value to point out potential improvement opportunities. 😃 )

I propose that from the perspective of Open Telemetry, it is a critical scenario that a distributed operation can be traced across microservices that are monitored by a heterogeneous vendor ecosystem, using manual and/or auto-instrumentation. Such vendor systems may use proprietary, non-W3C-based trace and span IDs. As long as each local vendor system interoperates with the W3C trace context in a manner compliant to the W3C specification, the trace context will flow correctly across service boundaries. For that, the .NET Activity API MUST allow explicitly specifying the W3C trace context details (trace and span IDs) for new spans in a manner compliant with the W3C recommendation [L1, L2]. Currently, that is not supported.

(I’d be very happy to be corrected in I am missing something. 😃 )

W3C specifies how to interoperate between non-W3C-based trace and span IDs potentially used by vendors and W3C-compliant trace contexts: On a high level, that involves:

  • taking the vendor-specific trace/span ID,
  • using it to generate the W3C trace context in a well-defined, compliant manner (see the referenced spec section, and other sections in the W3C doc)
  • setting the trace context generated in this manner on the current/new span

At the very least, if should be possible to restrict the number of significant bytes in the IDs, as described by W3C [L1, L2].

However, that is currently not possible with the ActivitySource based API. It is possible to supply the parent context, but the user has no control over the generation of the trace context for the new span.

We should consider adding ActivitySource.StartActivity(..) overloads that allow specifying an ActivityContext for the span being created. If this is too late for this in .NET5, we should make and document an explicit workaround recommendation.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 19 (11 by maintainers)

Most upvoted comments

Is the standard format really a goal?

Yes : ) For multiple reasons:

  • W3C is aiming to set an industry standard and .NET is taking a bet on it. One goal of using the standard is so that we don’t need to do large amounts of work supporting other vendor defined formats.
  • Activity is expected to update the ID when new child activities are formed. That requires update rules that are format specific.
  • For performance and usability the ID is exposed with strongly typed APIs, not as an opaque blob.
  • The ID isn’t treated as an opaque string by its consumers either, it has sub-structure such as the split between flags, spanId, and traceId. This requires everyone to agree how to interpret the data to extract this information or these consumers would be unable to interoperate.
  • There is ultimately only one thing that gets to populate Activity.ID. If the platform isn’t willing to standardize it then we have to delegate the responsibility for controlling it to some other component. That likely leads to multiple components competing to determine which of them gets control and probably incompatibility from whichever components aren’t delegated control. These are messy problems I’d like to avoid.

We can collaborate on mechanisms that give you more control when an inbound message that contains a [whichever] header needs to create an Activity. These extensibility points aren’t really part of Activity, they are part of networking stacks like Kestrel or GRPC.

Exactly, that’s what I am getting at. 😃

I’m not suggesting that you get to set an arbitrary format, I’m suggesting you get to define what W3C trace context will be treated as the parent, if any.