Description
Background and motivation
OpenTelemetry .NET's propagation API is centered around ActivityContext
. Anytime we need to propagate a span/Activity
(for example outgoing http call) we generate a W3C traceparent
:
This is a string allocation and takes some CPU cycles.
If a trace is NOT sampled, we create a single root span/Activity
. That root span/Activity
may be propagated many times servicing a request (if it calls a lot of downstream services). In that case we're going to be generating the same string each time.
The idea here is basically a performance optimization.
Activity
has this Id property which is the same W3C traceparent
as what OTel is building, but it is cached so subsequent calls don't incur the perf hit to generate it.
The goal here is to expose that same Id
on ActivityContext
and utilize the cache mechanism where we can.
Proof of concept diff: https://github.com/dotnet/runtime/compare/main...CodeBlanch:activitycontext-id?expand=1
API Proposal
namespace System.Diagnostics;
public readonly partial struct ActivityContext
{
+ public string Id { get; }
}
API Usage
// OTel W3C propagation implementation
public class TraceContextPropagator : TextMapPropagator
{
public override void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
{
// ...
+ var traceparent = context.ActivityContext.Id;
-#if NET6_0_OR_GREATER
- var traceparent = string.Create(55, context.ActivityContext, WriteTraceParentIntoSpan);
-#else
- var traceparent = string.Concat("00-", context.ActivityContext.TraceId.ToHexString(), "-", -context.ActivityContext.SpanId.ToHexString());
- traceparent = string.Concat(traceparent, (context.ActivityContext.TraceFlags & ActivityTraceFlags.Recorded) != 0 ? "-01" : "-00");
-#endif
// ...
}
}
Alternative Designs
No response
Risks
No response