opentelemetry-dotnet icon indicating copy to clipboard operation
opentelemetry-dotnet copied to clipboard

Propagator.Inject: immutable friendly overload

Open bnayae opened this issue 3 years ago • 1 comments

Feature Request

The current signature of Propagator.Inject is not Immutable friendly.

I'm implementing a REDIS Stream channel.

Describe the solution you'd like:

What do you want to happen instead? What is the expected behavior?

I'm collecting the data into ImmutableArray<NameValueEntry>. The current API make do an ugly work around, i.e. using immutableToBuilder():

            NameValueEntry KV(RedisValue key, RedisValue value) => new NameValueEntry(key, value);
            var spanContext = Activity.Current?.Context;
            ImmutableArray<NameValueEntry> entriesBuilder = ImmutableArray.Create(
                KV(nameof(meta.MessageId), id),
            );

          // here the work around
          var telemetryBuilder = entriesBuilder.ToBuilder();
          Propagator.Inject(new PropagationContext(contextToInject, Baggage.Current), telemetryBuilder, LocalInjectTelemetry);

I would like to have the following signature in order to fix the issue:

void Inject<T>(PropagationContext context, T carrier, Func<T, string, string, T> setter);
// instead of
void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)

I suggest the following overload:

        public override void Inject<T>(PropagationContext context, T carrier, Func<T, string, string, T> setter)
        {
            if (context.ActivityContext.TraceId == default || context.ActivityContext.SpanId == default)
            {
                OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TraceContextPropagator), "Invalid context");
                return;
            }

            if (carrier == null)
            {
                OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TraceContextPropagator), "null carrier");
                return;
            }

            if (setter == null)
            {
                OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TraceContextPropagator), "null setter");
                return;
            }

            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");

            carrier = setter(carrier, TraceParent, traceparent);

            string tracestateStr = context.ActivityContext.TraceState;
            if (tracestateStr?.Length > 0)
            {
                carrier = setter(carrier, TraceState, tracestateStr);
            }
        }

bnayae avatar Jul 27 '21 12:07 bnayae