private static async Task <WebResponse> GetResponseAsyncInternal(WebRequest request) { if (!(request is HttpWebRequest) || !IsTracingEnabled(request)) { return(await request.GetResponseAsync().ConfigureAwait(false)); } using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, request.Method, request.RequestUri, IntegrationName)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } WebResponse response = await request.GetResponseAsync().ConfigureAwait(false); if (scope != null && response is HttpWebResponse webResponse) { scope.Span.SetTag(Tags.HttpStatusCode, ((int)webResponse.StatusCode).ToString()); } return(response); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
[InlineData((int)IntegrationId.WebRequest, (int)IntegrationId.HttpMessageHandler)] // This scenario may occur on .NET Core where the underlying transport for WebRequest is HttpMessageHandler public void CreateOutboundHttpScope_AlwaysCreatesOneAutomaticInstrumentationScope(int integration1, int integration2) { // Set up Tracer var settings = new TracerSettings(); var writerMock = new Mock <IAgentWriter>(); var samplerMock = new Mock <ISampler>(); var tracer = new Tracer(settings, writerMock.Object, samplerMock.Object, scopeManager: null, statsd: null); const string method = "GET"; const string url = "http://www.contoso.com"; // Manually create a span decorated with HTTP information using (var manualScope = tracer.StartActive("http.request")) { manualScope.Span.Type = SpanTypes.Http; manualScope.Span.ResourceName = $"{method} {url}"; manualScope.Span.ServiceName = $"{tracer.DefaultServiceName}-http-client"; using (var automaticScope1 = ScopeFactory.CreateOutboundHttpScope(tracer, method, new Uri(url), (IntegrationId)integration1, out _)) { using (var automaticScope2 = ScopeFactory.CreateOutboundHttpScope(tracer, method, new Uri(url), (IntegrationId)integration2, out _)) { Assert.NotNull(manualScope); Assert.NotNull(automaticScope1); Assert.Null(automaticScope2); } } } }
/// <summary> /// OnMethodBegin callback /// </summary> /// <typeparam name="TTarget">Type of the target</typeparam> /// <param name="instance">Instance value, aka `this` of the instrumented method.</param> /// <returns>Calltarget state value</returns> public static CallTargetState GetResponse_OnMethodBegin <TTarget>(TTarget instance) { if (instance is HttpWebRequest request && IsTracingEnabled(request)) { Tracer tracer = Tracer.Instance; // Check if any headers were injected by a previous call to GetRequestStream var spanContext = tracer.Propagator.Extract(request.Headers.Wrap()); Scope scope = null; try { scope = ScopeFactory.CreateOutboundHttpScope(tracer, request.Method, request.RequestUri, IntegrationId, out var tags, spanContext?.SpanId); if (scope != null) { // add distributed tracing headers to the HTTP request tracer.Propagator.Inject(scope.Span.Context, request.Headers.Wrap()); return(new CallTargetState(scope)); } } catch { scope?.Dispose(); throw; } } return(CallTargetState.GetDefault()); }
private static async Task <WebResponse> GetResponseAsyncInternal(WebRequest webRequest, Func <object, Task <WebResponse> > originalMethod) { if (!(webRequest is HttpWebRequest) || !IsTracingEnabled(webRequest)) { return(await originalMethod(webRequest).ConfigureAwait(false)); } using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, webRequest.Method, webRequest.RequestUri, IntegrationName, out var tags)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, webRequest.Headers.Wrap()); } WebResponse response = await originalMethod(webRequest).ConfigureAwait(false); if (scope != null && response is HttpWebResponse webResponse) { tags.HttpStatusCode = HttpTags.ConvertStatusCodeToString((int)webResponse.StatusCode); } return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object GetResponse(object webRequest, int opCode, int mdToken) { var request = (WebRequest)webRequest; if (!(request is HttpWebRequest) || !IsTracingEnabled(request)) { return(request.GetResponse()); } using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, request.Method, request.RequestUri, IntegrationName)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } WebResponse response = request.GetResponse(); if (scope != null && response is HttpWebResponse webResponse) { scope.Span.SetTag(Tags.HttpStatusCode, ((int)webResponse.StatusCode).ToString()); } return(response); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
public static object GetResponse(object webRequest, int opCode, int mdToken, long moduleVersionPtr) { const string methodName = nameof(GetResponse); Func <object, WebResponse> callGetResponse; try { var instrumentedType = webRequest.GetInstrumentedType("System.Net.WebRequest"); callGetResponse = MethodBuilder <Func <object, WebResponse> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(instrumentedType) .WithNamespaceAndNameFilters("System.Net.WebResponse") .Build(); } catch (Exception ex) { // profiled app will not continue working as expected without this method Log.ErrorException($"Error retrieving System.Net.WebRequest.{methodName}()", ex); throw; } var request = (WebRequest)webRequest; if (!(request is HttpWebRequest) || !IsTracingEnabled(request)) { return(callGetResponse(webRequest)); } using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, request.Method, request.RequestUri, IntegrationName)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } WebResponse response = callGetResponse(webRequest); if (scope != null && response is HttpWebResponse webResponse) { scope.Span.SetTag(Tags.HttpStatusCode, ((int)webResponse.StatusCode).ToString()); } return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public void CreateOutboundHttpScope_Null_ResourceUri() { // Set up Tracer var settings = new TracerSettings(); var writerMock = new Mock <IAgentWriter>(); var samplerMock = new Mock <ISampler>(); var tracer = new Tracer(settings, writerMock.Object, samplerMock.Object, scopeManager: null, statsd: null); using (var automaticScope = ScopeFactory.CreateOutboundHttpScope(tracer, "GET", null, IntegrationId.HttpMessageHandler, out _)) { Assert.Equal(expected: "GET ", actual: automaticScope.Span.ResourceName); } }
public void CleanUri_ResourceName(string uri, string method, string expected) { // Set up Tracer var settings = new TracerSettings(); var writerMock = new Mock <IAgentWriter>(); var samplerMock = new Mock <ISampler>(); var tracer = new Tracer(settings, writerMock.Object, samplerMock.Object, scopeManager: null, statsd: null); using (var automaticScope = ScopeFactory.CreateOutboundHttpScope(tracer, method, new Uri(uri), IntegrationId.HttpMessageHandler, out _)) { Assert.Equal(expected, automaticScope.Span.ResourceName); } }
private static async Task <HttpResponseMessage> SendAsyncInternal( Func <HttpMessageHandler, HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > sendAsync, Type reportedType, HttpMessageHandler handler, HttpRequestMessage request, CancellationToken cancellationToken) { if (!(handler is HttpClientHandler || "System.Net.Http.SocketsHttpHandler".Equals(reportedType.FullName, StringComparison.OrdinalIgnoreCase)) || !IsTracingEnabled(request)) { // skip instrumentation return(await sendAsync(handler, request, cancellationToken).ConfigureAwait(false)); } string httpMethod = request.Method?.Method; var tracer = Tracer.Instance; using (var scope = ScopeFactory.CreateOutboundHttpScope(tracer, httpMethod, request.RequestUri, IntegrationName)) { try { if (scope != null) { scope.Span.SetTag("http-client-handler-type", reportedType.FullName); // add distributed tracing headers to the HTTP request tracer.Propagator.Inject(scope.Span.Context, request.Headers.Wrap()); } HttpResponseMessage response = await sendAsync(handler, request, cancellationToken).ConfigureAwait(false); if (scope != null) { // this tag can only be set after the response is returned scope.Span.SetTag(Tags.HttpStatusCode, ((int)response.StatusCode).ToString()); if (!response.IsSuccessStatusCode && !string.IsNullOrWhiteSpace(response.ReasonPhrase)) { scope.Span.SetTag(Tags.HttpStatusText, response.ReasonPhrase); } } return(response); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
private static async Task <T> SendAsyncInternal <T>( Func <object, object, CancellationToken, object> sendAsync, Type reportedType, object handler, object request, CancellationToken cancellationToken) { var headers = request.GetProperty <object>("Headers").GetValueOrDefault(); if (!(reportedType.FullName.Equals(HttpClientHandler, StringComparison.OrdinalIgnoreCase) || IsSocketsHttpHandlerEnabled(reportedType)) || !IsTracingEnabled(headers)) { // skip instrumentation var task = (Task <T>)sendAsync(handler, request, cancellationToken); return(await task.ConfigureAwait(false)); } var httpMethod = request.GetProperty("Method").GetProperty <string>("Method").GetValueOrDefault(); var requestUri = request.GetProperty <Uri>("RequestUri").GetValueOrDefault(); using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, httpMethod, requestUri, IntegrationName)) { try { if (scope != null) { scope.Span.SetTag("http-client-handler-type", reportedType.FullName); // add distributed tracing headers to the HTTP request SpanContextPropagatorHelpers.InjectHttpHeadersWithReflection(scope.Span.Context, headers); } var task = (Task <T>)sendAsync(handler, request, cancellationToken); var response = await task.ConfigureAwait(false); // this tag can only be set after the response is returned int statusCode = response.GetProperty <int>("StatusCode").GetValueOrDefault(); scope?.Span.SetTag(Tags.HttpStatusCode, (statusCode).ToString()); return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public void CleanUri_HttpUrlTag(string uri, string expected) { // Set up Tracer var settings = new TracerSettings(); var writerMock = new Mock <ITraceWriter>(); var samplerMock = new Mock <ISampler>(); var tracer = new Tracer(settings, plugins: null, writerMock.Object, samplerMock.Object, scopeManager: null, statsd: null); const string method = "GET"; using (var automaticScope = ScopeFactory.CreateOutboundHttpScope(tracer, method, new Uri(uri), new IntegrationInfo((int)IntegrationIds.HttpMessageHandler), out var tags)) { Assert.Equal(expected, automaticScope.Span.GetTag(Tags.HttpUrl)); Assert.Equal(expected, tags.HttpUrl); } }
private static async Task <object> SendAsyncInternal( Func <object, object, CancellationToken, object> sendAsync, Type reportedType, HttpRequestMessageStruct requestValue, object handler, object request, CancellationToken cancellationToken) { var httpMethod = requestValue.Method.Method; var requestUri = requestValue.RequestUri; var tracer = Tracer.Instance; using (var scope = ScopeFactory.CreateOutboundHttpScope(tracer, httpMethod, requestUri, IntegrationId, out var tags)) { try { if (scope != null) { tags.HttpClientHandlerType = reportedType.FullName; // add distributed tracing headers to the HTTP request tracer.Propagator.Inject(scope.Span.Context, new HttpHeadersCollection(requestValue.Headers)); } var task = (Task)sendAsync(handler, request, cancellationToken); await task.ConfigureAwait(false); var response = task.DuckCast <TaskObjectStruct>().Result; // this tag can only be set after the response is returned int statusCode = response.DuckCast <HttpResponseMessageStruct>().StatusCode; if (scope != null) { scope.Span.SetHttpStatusCode(statusCode, isServer: false); } return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
private static async Task <HttpResponseMessage> SendAsyncInternal( HttpMessageHandler handler, HttpRequestMessage request, CancellationToken cancellationToken) { var executeAsync = DynamicMethodBuilder <Func <HttpMessageHandler, HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > > .GetOrCreateMethodCallDelegate( handler.GetType(), nameof(SendAsync)); var handlerTypeName = handler.GetType().FullName; if (handlerTypeName != "System.Net.Http.HttpClientHandler" || !IsTracingEnabled(request)) { // skip instrumentation return(await executeAsync(handler, request, cancellationToken).ConfigureAwait(false)); } string httpMethod = request.Method.ToString().ToUpperInvariant(); string integrationName = typeof(HttpMessageHandlerIntegration).Name.TrimEnd("Integration", StringComparison.OrdinalIgnoreCase); using (var scope = ScopeFactory.CreateOutboundHttpScope(httpMethod, request.RequestUri, integrationName)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } HttpResponseMessage response = await executeAsync(handler, request, cancellationToken).ConfigureAwait(false); // this tag can only be set after the response is returned scope?.Span.SetTag(Tags.HttpStatusCode, ((int)response.StatusCode).ToString()); return(response); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
public static CallTargetState OnMethodBegin <TTarget, TRequest>(TTarget instance, TRequest requestMessage, CancellationToken cancellationToken) where TRequest : IHttpRequestMessage { if (IsTracingEnabled(requestMessage.Headers)) { Scope scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, requestMessage.Method.Method, requestMessage.RequestUri, IntegrationId, out HttpTags tags); if (scope != null) { tags.HttpClientHandlerType = instance.GetType().FullName; // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, new HttpHeadersCollection(requestMessage.Headers)); return(new CallTargetState(scope)); } } return(CallTargetState.GetDefault()); }
/// <summary> /// OnMethodBegin callback /// </summary> /// <typeparam name="TTarget">Type of the target</typeparam> /// <param name="instance">Instance value, aka `this` of the instrumented method.</param> /// <returns>Calltarget state value</returns> public static CallTargetState GetResponse_OnMethodBegin <TTarget>(TTarget instance) { if (instance is HttpWebRequest request && IsTracingEnabled(request)) { Tracer tracer = Tracer.Instance; // Check if any headers were injected by a previous call to GetRequestStream var spanContext = SpanContextPropagator.Instance.Extract(request.Headers.Wrap()); // If this operation creates the trace, then we need to re-apply the sampling priority bool setSamplingPriority = spanContext?.SamplingPriority != null && tracer.ActiveScope == null; Scope scope = null; try { scope = ScopeFactory.CreateOutboundHttpScope(tracer, request.Method, request.RequestUri, IntegrationId, out _, spanContext?.TraceId, spanContext?.SpanId); if (scope != null) { if (setSamplingPriority && spanContext?.SamplingPriority is not null) { scope.Span.SetTraceSamplingPriority(spanContext.SamplingPriority.Value); } // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); tracer.TracerManager.Telemetry.IntegrationGeneratedSpan(IntegrationId); return(new CallTargetState(scope)); } } catch { scope?.Dispose(); throw; } } return(CallTargetState.GetDefault()); }
private static async Task <HttpResponseMessage> SendAsyncInternal( Func <HttpMessageHandler, HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > sendAsync, Type reportedType, HttpMessageHandler handler, HttpRequestMessage request, CancellationToken cancellationToken) { if (!(handler is HttpClientHandler || IsSocketsHttpHandlerEnabled(reportedType)) || !IsTracingEnabled(request)) { // skip instrumentation return(await sendAsync(handler, request, cancellationToken).ConfigureAwait(false)); } string httpMethod = request.Method?.Method; using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, httpMethod, request.RequestUri, IntegrationName)) { try { if (scope != null) { scope.Span.SetTag("http-client-handler-type", reportedType.FullName); // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } HttpResponseMessage response = await sendAsync(handler, request, cancellationToken).ConfigureAwait(false); // this tag can only be set after the response is returned scope?.Span.SetTag(Tags.HttpStatusCode, ((int)response.StatusCode).ToString()); return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public void OutboundHttp(Input input, Result expected) { var settings = new TracerSettings(); settings.Convention = ConventionType.OpenTelemetry; var tracer = new Tracer(settings, plugins: null, Mock.Of <ITraceWriter>(), Mock.Of <ISampler>(), scopeManager: null, statsd: null); using (var scope = ScopeFactory.CreateOutboundHttpScope(tracer, input.Method, new Uri(input.Uri), new IntegrationInfo((int)IntegrationIds.HttpMessageHandler), out var tags)) { var span = scope.Span; var actual = new Result { OperationName = span.OperationName, HttpMethodTag = span.GetTag("http.method"), HttpUrlTag = span.GetTag("http.url"), }; actual.Should().BeEquivalentTo(expected); } }
private static async Task <object> SendAsyncInternal( Func <object, object, CancellationToken, object> sendAsync, Type reportedType, object headers, object handler, object request, CancellationToken cancellationToken) { var httpMethod = request.GetProperty("Method").GetProperty <string>("Method").GetValueOrDefault(); var requestUri = request.GetProperty <Uri>("RequestUri").GetValueOrDefault(); using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, httpMethod, requestUri, IntegrationName)) { try { if (scope != null) { scope.Span.SetTag("http-client-handler-type", reportedType.FullName); // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, new ReflectionHttpHeadersCollection(headers)); } var task = (Task)sendAsync(handler, request, cancellationToken); await task.ConfigureAwait(false); var response = task.GetProperty("Result").Value; // this tag can only be set after the response is returned int statusCode = response.GetProperty <int>("StatusCode").GetValueOrDefault(); scope?.Span.SetTag(Tags.HttpStatusCode, (statusCode).ToString()); return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object GetResponse(object webRequest) { var request = (WebRequest)webRequest; if (!IsTracingEnabled(request)) { return(request.GetResponse()); } string httpMethod = request.Method.ToUpperInvariant(); string integrationName = typeof(WebRequestIntegration).Name.TrimEnd("Integration", StringComparison.OrdinalIgnoreCase); using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, httpMethod, request.RequestUri, integrationName)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } WebResponse response = request.GetResponse(); if (response is HttpWebResponse webResponse) { scope?.Span.SetTag(Tags.HttpStatusCode, ((int)webResponse.StatusCode).ToString()); } return(response); } catch (Exception ex) when(scope?.Span.SetExceptionForFilter(ex) ?? false) { // unreachable code throw; } } }
private static async Task <WebResponse> GetResponseAsyncInternal(WebRequest webRequest, Func <object, Task <WebResponse> > originalMethod) { if (!(webRequest is HttpWebRequest) || !IsTracingEnabled(webRequest)) { return(await originalMethod(webRequest).ConfigureAwait(false)); } // The headers may have been set/propagated to the server on a previous method call, but no actual span was created for it yet. // Try to extract the context and if available use the already propagated span ID. SpanContext spanContext = Tracer.Instance.Propagator.Extract(webRequest.Headers.Wrap()); using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, webRequest.Method, webRequest.RequestUri, IntegrationName, propagatedSpanId: spanContext?.SpanId)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request Tracer.Instance.Propagator.Inject(scope.Span.Context, webRequest.Headers.Wrap()); } WebResponse response = await originalMethod(webRequest).ConfigureAwait(false); if (scope != null && response is HttpWebResponse webResponse) { scope.Span.SetTag(Tags.HttpStatusCode, ((int)webResponse.StatusCode).ToString()); } return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object GetResponse(object webRequest, int opCode, int mdToken, long moduleVersionPtr) { if (webRequest == null) { throw new ArgumentNullException(nameof(webRequest)); } const string methodName = nameof(GetResponse); Func <object, WebResponse> callGetResponse; try { var instrumentedType = webRequest.GetInstrumentedType("System.Net.WebRequest"); callGetResponse = MethodBuilder <Func <object, WebResponse> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(instrumentedType) .WithNamespaceAndNameFilters("System.Net.WebResponse") .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: WebRequestTypeName, methodName: methodName, instanceType: webRequest.GetType().AssemblyQualifiedName); throw; } var request = (WebRequest)webRequest; if (!(request is HttpWebRequest) || !IsTracingEnabled(request)) { return(callGetResponse(webRequest)); } using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, request.Method, request.RequestUri, IntegrationName, out var tags)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request SpanContextPropagator.Instance.Inject(scope.Span.Context, request.Headers.Wrap()); } WebResponse response = callGetResponse(webRequest); if (scope != null && response is HttpWebResponse webResponse) { tags.HttpStatusCode = HttpTags.ConvertStatusCodeToString((int)webResponse.StatusCode); } return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }
public static object GetResponse(object webRequest, int opCode, int mdToken, long moduleVersionPtr) { if (webRequest == null) { throw new ArgumentNullException(nameof(webRequest)); } const string methodName = nameof(GetResponse); Func <object, WebResponse> callGetResponse; try { var instrumentedType = webRequest.GetInstrumentedType("System.Net.WebRequest"); callGetResponse = MethodBuilder <Func <object, WebResponse> > .Start(moduleVersionPtr, mdToken, opCode, methodName) .WithConcreteType(instrumentedType) .WithNamespaceAndNameFilters("System.Net.WebResponse") .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: WebRequestTypeName, methodName: methodName, instanceType: webRequest.GetType().AssemblyQualifiedName); throw; } var request = (WebRequest)webRequest; if (!(request is HttpWebRequest) || !IsTracingEnabled(request)) { return(callGetResponse(webRequest)); } // The headers may have been set/propagated to the server on a previous method call, but no actual span was created for it yet. // Try to extract the context and if available use the already propagated span ID. var headers = request?.Headers?.Wrap(); SpanContext spanContext = null; if (headers != null) { spanContext = Tracer.Instance.Propagator.Extract(headers); } using (var scope = ScopeFactory.CreateOutboundHttpScope(Tracer.Instance, request.Method, request.RequestUri, IntegrationName, propagatedSpanId: spanContext?.SpanId)) { try { if (scope != null) { // add distributed tracing headers to the HTTP request Tracer.Instance.Propagator.Inject(scope.Span.Context, request.Headers.Wrap()); } WebResponse response = callGetResponse(webRequest); if (scope != null && response is HttpWebResponse webResponse) { scope.Span.SetTag(Tags.HttpStatusCode, ((int)webResponse.StatusCode).ToString()); } return(response); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } } }