/// <inheritdoc/>
        public void Inject <T>(PropagationContext context, T carrier, Action <T, string, string> setter)
        {
            if (carrier == null)
            {
                OpenTelemetryApiEventSource.Log.FailedToInjectBaggage(nameof(BaggagePropagator), "null carrier");
                return;
            }

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

            using var e = context.Baggage.GetEnumerator();

            if (e.MoveNext() == true)
            {
                int           itemCount = 0;
                StringBuilder baggage   = new StringBuilder();
                do
                {
                    KeyValuePair <string, string> item = e.Current;
                    if (string.IsNullOrEmpty(item.Value))
                    {
                        continue;
                    }

                    baggage.Append(WebUtility.UrlEncode(item.Key)).Append('=').Append(WebUtility.UrlEncode(item.Value)).Append(',');
                }while (e.MoveNext() && ++itemCount < MaxBaggageItems && baggage.Length < MaxBaggageLength);
                baggage.Remove(baggage.Length - 1, 1);
                setter(carrier, BaggageHeaderName, baggage.ToString());
            }
        }
Exemple #2
0
 /// <inheritdoc/>
 public void Inject <T>(PropagationContext context, T carrier, Action <T, string, string> setter)
 {
     foreach (var textFormat in this.textFormats)
     {
         textFormat.Inject(context, carrier, setter);
     }
 }
Exemple #3
0
        /// <inheritdoc/>
        public PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            if (context.ActivityContext.IsValid())
            {
                // If a valid context has already been extracted, perform a noop.
                return(context);
            }

            if (carrier == null)
            {
                OpenTelemetryApiEventSource.Log.FailedToExtractActivityContext(nameof(B3Propagator), "null carrier");
                return(context);
            }

            if (getter == null)
            {
                OpenTelemetryApiEventSource.Log.FailedToExtractActivityContext(nameof(B3Propagator), "null getter");
                return(context);
            }

            if (this.singleHeader)
            {
                return(ExtractFromSingleHeader(context, carrier, getter));
            }
            else
            {
                return(ExtractFromMultipleHeaders(context, carrier, getter));
            }
        }
Exemple #4
0
        /// <inheritdoc/>
        public override void Inject <T>(PropagationContext context, T carrier, Action <T, string, string> 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");

            setter(carrier, TraceParent, traceparent);

            string tracestateStr = context.ActivityContext.TraceState;

            if (tracestateStr?.Length > 0)
            {
                setter(carrier, TraceState, tracestateStr);
            }
        }
Exemple #5
0
 /// <inheritdoc/>
 public override void Inject <T>(PropagationContext context, T carrier, Action <T, string, string> setter)
 {
     foreach (var propagator in this.propagators)
     {
         propagator.Inject(context, carrier, setter);
     }
 }
Exemple #6
0
        private static PropagationContext ExtractFromSingleHeader <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            try
            {
                var header = getter(carrier, XB3Combined)?.FirstOrDefault();
                if (string.IsNullOrWhiteSpace(header))
                {
                    return(context);
                }

                var parts = header.Split(XB3CombinedDelimiter);
                if (parts.Length < 2 || parts.Length > 4)
                {
                    return(context);
                }

                var traceIdStr = parts[0];
                if (string.IsNullOrWhiteSpace(traceIdStr))
                {
                    return(context);
                }

                if (traceIdStr.Length == 16)
                {
                    // This is an 8-byte traceID.
                    traceIdStr = UpperTraceId + traceIdStr;
                }

                var traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan());

                var spanIdStr = parts[1];
                if (string.IsNullOrWhiteSpace(spanIdStr))
                {
                    return(context);
                }

                var spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan());

                var traceOptions = ActivityTraceFlags.None;
                if (parts.Length > 2)
                {
                    var traceFlagsStr = parts[2];
                    if (SampledValues.Contains(traceFlagsStr) ||
                        FlagsValue.Equals(traceFlagsStr, StringComparison.Ordinal))
                    {
                        traceOptions |= ActivityTraceFlags.Recorded;
                    }
                }

                return(new PropagationContext(
                           new ActivityContext(traceId, spanId, traceOptions, isRemote: true),
                           context.Baggage));
            }
            catch (Exception e)
            {
                OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(B3Propagator), e);
                return(context);
            }
        }
Exemple #7
0
        /// <inheritdoc/>
        public PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            foreach (var textFormat in this.textFormats)
            {
                context = textFormat.Extract(context, carrier, getter);
            }

            return(context);
        }
Exemple #8
0
        /// <inheritdoc/>
        public override PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            if (context.ActivityContext.IsValid())
            {
                // If a valid context has already been extracted, perform a noop.
                return(context);
            }

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

            if (getter == null)
            {
                OpenTelemetryApiEventSource.Log.FailedToExtractActivityContext(nameof(TraceContextPropagator), "null getter");
                return(context);
            }

            try
            {
                var traceparentCollection = getter(carrier, TraceParent);

                // There must be a single traceparent
                if (traceparentCollection == null || traceparentCollection.Count() != 1)
                {
                    return(context);
                }

                var traceparent       = traceparentCollection.First();
                var traceparentParsed = TryExtractTraceparent(traceparent, out var traceId, out var spanId, out var traceoptions);

                if (!traceparentParsed)
                {
                    return(context);
                }

                string tracestate           = null;
                var    tracestateCollection = getter(carrier, TraceState);
                if (tracestateCollection?.Any() ?? false)
                {
                    TryExtractTracestate(tracestateCollection.ToArray(), out tracestate);
                }

                return(new PropagationContext(
                           new ActivityContext(traceId, spanId, traceoptions, tracestate, isRemote: true),
                           context.Baggage));
            }
            catch (Exception ex)
            {
                OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(TraceContextPropagator), ex);
            }

            // in case of exception indicate to upstream that there is no parseable context from the top
            return(context);
        }
Exemple #9
0
        /// <inheritdoc/>
        public override PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            foreach (var propagator in this.propagators)
            {
                context = propagator.Extract(context, carrier, getter);
            }

            return(context);
        }
Exemple #10
0
        private static PropagationContext ExtractFromMultipleHeaders <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            try
            {
                ActivityTraceId traceId;
                var             traceIdStr = getter(carrier, XB3TraceId)?.FirstOrDefault();
                if (traceIdStr != null)
                {
                    if (traceIdStr.Length == 16)
                    {
                        // This is an 8-byte traceID.
                        traceIdStr = UpperTraceId + traceIdStr;
                    }

                    traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan());
                }
                else
                {
                    return(context);
                }

                ActivitySpanId spanId;
                var            spanIdStr = getter(carrier, XB3SpanId)?.FirstOrDefault();
                if (spanIdStr != null)
                {
                    spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan());
                }
                else
                {
                    return(context);
                }

                var traceOptions = ActivityTraceFlags.None;
                if (SampledValues.Contains(getter(carrier, XB3Sampled)?.FirstOrDefault()) ||
                    FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault(), StringComparison.Ordinal))
                {
                    traceOptions |= ActivityTraceFlags.Recorded;
                }

                return(new PropagationContext(
                           new ActivityContext(traceId, spanId, traceOptions, isRemote: true),
                           context.Baggage));
            }
            catch (Exception e)
            {
                OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(B3Propagator), e);
                return(context);
            }
        }
Exemple #11
0
        /// <inheritdoc/>
        public void Inject <T>(PropagationContext context, T carrier, Action <T, string, string> setter)
        {
            if (context.ActivityContext.TraceId == default || context.ActivityContext.SpanId == default)
            {
                OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(B3Propagator), "invalid context");
                return;
            }

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

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

            if (this.singleHeader)
            {
                var sb = new StringBuilder();
                sb.Append(context.ActivityContext.TraceId.ToHexString());
                sb.Append(XB3CombinedDelimiter);
                sb.Append(context.ActivityContext.SpanId.ToHexString());
                if ((context.ActivityContext.TraceFlags & ActivityTraceFlags.Recorded) != 0)
                {
                    sb.Append(XB3CombinedDelimiter);
                    sb.Append(SampledValue);
                }

                setter(carrier, XB3Combined, sb.ToString());
            }
            else
            {
                setter(carrier, XB3TraceId, context.ActivityContext.TraceId.ToHexString());
                setter(carrier, XB3SpanId, context.ActivityContext.SpanId.ToHexString());
                if ((context.ActivityContext.TraceFlags & ActivityTraceFlags.Recorded) != 0)
                {
                    setter(carrier, XB3Sampled, SampledValue);
                }
            }
        }
        /// <inheritdoc/>
        public PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
        {
            if (context.Baggage != default)
            {
                // If baggage has already been extracted, perform a noop.
                return(context);
            }

            if (carrier == null)
            {
                OpenTelemetryApiEventSource.Log.FailedToExtractBaggage(nameof(BaggagePropagator), "null carrier");
                return(context);
            }

            if (getter == null)
            {
                OpenTelemetryApiEventSource.Log.FailedToExtractBaggage(nameof(BaggagePropagator), "null getter");
                return(context);
            }

            try
            {
                Dictionary <string, string> baggage = null;
                var baggageCollection = getter(carrier, BaggageHeaderName);
                if (baggageCollection?.Any() ?? false)
                {
                    TryExtractBaggage(baggageCollection.ToArray(), out baggage);
                }

                return(new PropagationContext(
                           context.ActivityContext,
                           baggage == null ? context.Baggage : new Baggage(baggage)));
            }
            catch (Exception ex)
            {
                OpenTelemetryApiEventSource.Log.BaggageExtractException(nameof(BaggagePropagator), ex);
            }

            return(context);
        }
 public override void Inject <T>(PropagationContext context, T carrier, Action <T, string, string> setter)
 {
 }
 public override PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter)
 {
     return(DefaultPropagationContext);
 }
 /// <summary>
 /// Extracts the context from a carrier.
 /// </summary>
 /// <typeparam name="T">Type of object to extract context from. Typically HttpRequest or similar.</typeparam>
 /// <param name="context">The default context to be used if Extract fails.</param>
 /// <param name="carrier">Object to extract context from. Instance of this object will be passed to the getter.</param>
 /// <param name="getter">Function that will return string value of a key with the specified name.</param>
 /// <returns>Context from it's text representation.</returns>
 public abstract PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter);
 /// <summary>
 /// Injects the context into a carrier.
 /// </summary>
 /// <typeparam name="T">Type of an object to set context on. Typically HttpRequest or similar.</typeparam>
 /// <param name="context">The default context to transmit over the wire.</param>
 /// <param name="carrier">Object to set context on. Instance of this object will be passed to setter.</param>
 /// <param name="setter">Action that will set name and value pair on the object.</param>
 public abstract void Inject <T>(PropagationContext context, T carrier, Action <T, string, string> setter);