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); }
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); }
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); }
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); }
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); }
/// <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)); }
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); }
internal void Extract_EmptyHeadersReturnsNull(IHeadersCollection headers) { var resultContext = SpanContextPropagator.Instance.Extract(headers); Assert.Null(resultContext); }
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); }
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); }
private static IEnumerable <string> ExtractFromHeadersCollection(IHeadersCollection carrier, string header) { return(carrier.GetValues(header)); }
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));
public static IEnumerable <KeyValuePair <string, string> > ExtractHeaderTags(this IHeadersCollection headers, IEnumerable <KeyValuePair <string, string> > headerToTagMap, string defaultTagPrefix) { return(ExtractHeaderTags(headers, headerToTagMap, defaultTagPrefix, string.Empty)); }