Exemple #1
0
        internal void Extract_InvalidSpanId(IHeadersCollection headers, string spanId)
        {
            const ulong            traceId          = 9;
            const SamplingPriority samplingPriority = SamplingPriority.UserKeep;
            const string           origin           = "synthetics";

            InjectContext(
                headers,
                traceId.ToString(CultureInfo.InvariantCulture),
                spanId,
                ((int)samplingPriority).ToString(CultureInfo.InvariantCulture),
                origin);

            var resultContext = SpanContextPropagator.Instance.Extract(headers);

            Assert.NotNull(resultContext);
            Assert.Equal(traceId, resultContext.TraceId);
            Assert.Equal(default(ulong), resultContext.SpanId);
            Assert.Equal(samplingPriority, resultContext.SamplingPriority);
            Assert.Equal(origin, resultContext.Origin);
        }
Exemple #2
0
        public static IEnumerable <KeyValuePair <string, string> > ExtractHeaderTags(this IHeadersCollection headers, IEnumerable <KeyValuePair <string, string> > headerToTagMap, string defaultTagPrefix, string userAgent)
        {
            foreach (KeyValuePair <string, string> headerNameToTagName in headerToTagMap)
            {
                var headerName      = headerNameToTagName.Key;
                var providedTagName = headerNameToTagName.Value;

                string headerValue;
                if (string.Equals(headerName, CommonHttpHeaderNames.UserAgent, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(userAgent))
                {
                    // A specific case for the user agent as it is splitted in .net framework web api.
                    headerValue = userAgent;
                }
                else
                {
                    headerValue = ParseString(headers, headerName);
                }

                if (headerValue is null)
                {
                    continue;
                }

                // Tag name is normalized during Tracer instantiation so use as-is
                if (!string.IsNullOrWhiteSpace(providedTagName))
                {
                    yield return(new KeyValuePair <string, string>(providedTagName, headerValue));
                }
                else
                {
                    // Since the header name was saved to do the lookup in the input headers,
                    // convert the header to its final tag name once per prefix
                    var    cacheKey      = new Key(headerName, defaultTagPrefix);
                    string tagNameResult = DefaultTagMappingCache.GetOrAdd(cacheKey, key =>
                    {
                        if (key.HeaderName.TryConvertToNormalizedTagName(normalizePeriods: true, out var normalizedHeaderTagName))
                        {
                            return(key.TagPrefix + "." + normalizedHeaderTagName);
                        }
Exemple #3
0
        public void OriginHeader_InjectFromChildSpan()
        {
            const ulong            traceId          = 9;
            const ulong            spanId           = 7;
            const SamplingPriority samplingPriority = SamplingPriority.UserKeep;
            const string           origin           = "synthetics";

            var propagatedContext = new SpanContext(traceId, spanId, samplingPriority, null, origin);

            using var firstSpan  = _tracer.StartActive("First Span", propagatedContext);
            using var secondSpan = _tracer.StartActive("Child", firstSpan.Span.Context);

            IHeadersCollection headers = WebRequest.CreateHttp("http://localhost").Headers.Wrap();

            SpanContextPropagator.Instance.Inject(secondSpan.Span.Context, headers);
            var resultContext = SpanContextPropagator.Instance.Extract(headers);

            Assert.NotNull(resultContext);
            Assert.Equal(firstSpan.Span.Context.Origin, resultContext.Origin);
            Assert.Equal(secondSpan.Span.Context.Origin, resultContext.Origin);
            Assert.Equal(origin, resultContext.Origin);
        }
Exemple #4
0
        internal void WebRequest_InjectExtract_Identity(IHeadersCollection headers)
        {
            var       traceId = TraceId.CreateFromString("52686470458518446744073709551615");
            const int spanId  = 2147483646;
            const SamplingPriority samplingPriority = SamplingPriority.AutoReject;

            var context = new SpanContext(traceId, spanId, samplingPriority);

            _propagator.Inject(context, headers);

            AssertExpected(headers, B3HttpHeaderNames.B3TraceId, "52686470458518446744073709551615");
            AssertExpected(headers, B3HttpHeaderNames.B3SpanId, "000000007ffffffe");
            AssertExpected(headers, B3HttpHeaderNames.B3Sampled, "0");
            AssertMissing(headers, B3HttpHeaderNames.B3ParentId);
            AssertMissing(headers, B3HttpHeaderNames.B3Flags);

            var resultContext = _propagator.Extract(headers);

            Assert.NotNull(resultContext);
            Assert.Equal(context.SpanId, resultContext.SpanId);
            Assert.Equal(context.TraceId, resultContext.TraceId);
            Assert.Equal(context.SamplingPriority, resultContext.SamplingPriority);
        }
        private static SamplingPriority?ParseB3Sampling(IHeadersCollection headers)
        {
            var debugged = headers.GetValues(HttpHeaderNames.B3Flags).ToList();
            var sampled  = headers.GetValues(HttpHeaderNames.B3Sampled).ToList();

            if (debugged.Count != 0 && (debugged[0] == "0" || debugged[0] == "1"))
            {
                return(debugged[0] == "1" ? SamplingPriority.UserKeep : (SamplingPriority?)null);
            }
            else if (sampled.Count != 0 && (sampled[0] == "0" || sampled[0] == "1"))
            {
                return(sampled[0] == "1" ? SamplingPriority.AutoKeep : SamplingPriority.AutoReject);
            }

            Log.Information(
                "Could not parse headers: {0}: {1} or {2}: {3}",
                HttpHeaderNames.B3Flags,
                string.Join(",", debugged),
                HttpHeaderNames.B3Sampled,
                string.Join(",", sampled));

            return(null);
        }
Exemple #6
0
        private static T?ParseEnum <T>(IHeadersCollection headers, string headerName)
            where T : struct, Enum
        {
            var headerValues = headers.GetValues(headerName).ToList();

            if (headerValues.Count > 0)
            {
                foreach (string headerValue in headerValues)
                {
                    if (Enum.TryParse <T>(headerValue, out var result) &&
                        Enum.IsDefined(typeof(T), result))
                    {
                        return(result);
                    }
                }

                Log.Information(
                    "Could not parse {0} headers: {1}",
                    headerName,
                    string.Join(",", headerValues));
            }

            return(default);
        public async Task <APIGatewayProxyResponse> InvokeAPIGatewayProxyAsync(
            Func <APIGatewayProxyRequest, ILambdaContext, Task <APIGatewayProxyResponse> > asyncHandler,
            APIGatewayProxyRequest request,
            ILambdaContext context,
            string operationName = null,
            IEnumerable <KeyValuePair <string, string> > tags = null)
        {
            IHeadersCollection headersCollection = null;

            if (TelemetryConfiguration.ContextPropagationEnabled)
            {
                headersCollection = new DictionaryHeadersCollection(request.MultiValueHeaders);
            }

            using (var tracker = new TelemetryTracker(context, operationName, tags, headersCollection))
            {
                try
                {
                    APIGatewayProxyResponse apiGatewayProxyResponse = await asyncHandler(request, context);

                    if (!apiGatewayProxyResponse.IsSuccessStatusCode())
                    {
                        tracker.SetErrorCounter();

                        // Preserve the legacy logging.
                        LambdaLogger.Log($"[ERR] Invoking lambda function. Http status code: {apiGatewayProxyResponse.StatusCode}. Response body: {apiGatewayProxyResponse.Body}{Environment.NewLine}");
                    }

                    return(apiGatewayProxyResponse);
                }
                catch (Exception e)
                {
                    tracker.SetException(e);
                    throw;
                }
            }
        }
        public void WebRequest_InjectExtract_Identity()
        {
            const int traceId = 2147483647;
            const int spanId  = 2147483646;
            const SamplingPriority samplingPriority = SamplingPriority.AutoReject;

            IHeadersCollection headers = WebRequest.CreateHttp("http://localhost").Headers.Wrap();
            var context = new SpanContext(traceId, spanId, samplingPriority);

            B3SpanContextPropagator.Instance.Inject(context, headers);

            AssertExpected(headers, HttpHeaderNames.B3TraceId, "000000007fffffff");
            AssertExpected(headers, HttpHeaderNames.B3SpanId, "000000007ffffffe");
            AssertExpected(headers, HttpHeaderNames.B3Sampled, "0");
            AssertMissing(headers, HttpHeaderNames.B3ParentId);
            AssertMissing(headers, HttpHeaderNames.B3Flags);

            var resultContext = B3SpanContextPropagator.Instance.Extract(headers);

            Assert.NotNull(resultContext);
            Assert.Equal(context.SpanId, resultContext.SpanId);
            Assert.Equal(context.TraceId, resultContext.TraceId);
            Assert.Equal(context.SamplingPriority, resultContext.SamplingPriority);
        }
Exemple #9
0
        /// <summary>
        /// Propagates the specified context by adding new headers to a <see cref="IHeadersCollection"/>.
        /// This locks the sampling priority for <paramref name="context"/>.
        /// </summary>
        /// <param name="context">A <see cref="SpanContext"/> value that will be propagated into <paramref name="headers"/>.</param>
        /// <param name="headers">A <see cref="IHeadersCollection"/> to add new headers to.</param>
        public void Inject(SpanContext context, IHeadersCollection headers)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (headers == null)
            {
                throw new ArgumentNullException(nameof(headers));
            }

            // lock sampling priority when span propagates.
            context.TraceContext?.LockSamplingPriority();

            headers.Set(HttpHeaderNames.TraceId, context.TraceId.ToString(InvariantCulture));
            headers.Set(HttpHeaderNames.ParentId, context.SpanId.ToString(InvariantCulture));

            var samplingPriority = (int?)(context.TraceContext?.SamplingPriority ?? context.SamplingPriority);

            headers.Set(
                HttpHeaderNames.SamplingPriority,
                samplingPriority?.ToString(InvariantCulture));
        }
Exemple #10
0
 public static Task <Response <TResponseBody> > GetAsync <TResponseBody>(this IClient client, Uri resource = null, IHeadersCollection requestHeaders = null, CancellationToken cancellationToken = default)
 {
     return(SendAsync <TResponseBody, object>(client,
                                              new Request <object>(
                                                  resource,
        private static void AssertMissing(IHeadersCollection headers, string key)
        {
            var matches = headers.GetValues(key);

            Assert.Empty(matches);
        }
Exemple #12
0
        internal void Extract_EmptyHeadersReturnsNull(IHeadersCollection headers)
        {
            var resultContext = SpanContextPropagator.Instance.Extract(headers);

            Assert.Null(resultContext);
        }
Exemple #13
0
        internal void ExtractHeaderTags_ForEmptyStringMappings_CreatesNormalizedTagWithPrefix(IHeadersCollection headers)
        {
            string invalidCharacterSequence      = "*|&#$%&^`.";
            string normalizedReplacementSequence = new string('_', invalidCharacterSequence.Length);

            // Add headers
            headers.Add("x-header-test-runner", "xunit");
            headers.Add($"x-header-1DATADOG-{invalidCharacterSequence}", "true");

            // Initialize header-tag arguments and expectations
            var headerToTagMap = new Dictionary <string, string>
            {
                { "x-header-test-runner", string.Empty },
                { $"x-header-1DATADOG-{invalidCharacterSequence}", string.Empty },
            };

            var expectedResults = new Dictionary <string, string>
            {
                { TestPrefix + "." + "x-header-test-runner", "xunit" },
                { TestPrefix + "." + $"x-header-1datadog-{normalizedReplacementSequence}", "true" }
            };

            // Test
            var tagsFromHeader = SpanContextPropagator.Instance.ExtractHeaderTags(headers, headerToTagMap, TestPrefix);

            // Assert
            Assert.NotNull(tagsFromHeader);
            Assert.Equal(expectedResults, tagsFromHeader);
        }
 public static SpanContext Extract(this IPropagator propagator, IHeadersCollection headers)
 {
     return(propagator.Extract(headers, ExtractFromHeadersCollection));
 }
 public static void Inject(this IPropagator propagator, SpanContext context, IHeadersCollection headers)
 {
     propagator.Inject(context, headers, InjectToHeadersCollection);
 }
Exemple #16
0
 private static void InjectToHeadersCollection(IHeadersCollection carrier, string header, string value)
 {
     carrier.Set(header, value);
 }
 internal static void SetHeaderTags(this Span span, IHeadersCollection headers, IDictionary <string, string> headerTags, string defaultTagPrefix)
 {
     SetHeaderTags <IHeadersCollection>(span, headers, headerTags, defaultTagPrefix);
 }
Exemple #18
0
 private static IEnumerable <string> ExtractFromHeadersCollection(IHeadersCollection carrier, string header)
 {
     return(carrier.GetValues(header));
 }
Exemple #19
0
 public static string ParseString(this IHeadersCollection headers, string headerName)
 {
     return(PropagationHelpers.ParseString(headers, (carrier, header) => carrier.GetValues(header), headerName));
 }
 public byte[] Serialize <TRequestBody>(TRequestBody value, IHeadersCollection requestHeaders)
 => value != null ?
 (IMessage)value is not IMessage message ? throw new InvalidOperationException("The object is not a Google Protobuf Message") : message.ToByteArray() : throw new ArgumentNullException(nameof(value));
Exemple #21
0
 public static IEnumerable <KeyValuePair <string, string> > ExtractHeaderTags(this IHeadersCollection headers, IEnumerable <KeyValuePair <string, string> > headerToTagMap, string defaultTagPrefix)
 {
     return(ExtractHeaderTags(headers, headerToTagMap, defaultTagPrefix, string.Empty));
 }