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);
                    }
                }
            }
        }
Exemple #3
0
        /// <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());
        }
Exemple #4
0
        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;
                }
            }
        }
Exemple #5
0
        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);
            }
        }
Exemple #9
0
        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;
                }
            }
        }
Exemple #10
0
        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;
                }
            }
        }
Exemple #13
0
        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());
        }
Exemple #15
0
        /// <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());
        }
Exemple #16
0
        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;
                }
            }
        }
Exemple #17
0
        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);
            }
        }
Exemple #18
0
        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;
                }
            }
        }
Exemple #20
0
        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;
                }
            }
        }
Exemple #21
0
        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;
                }
            }
        }
Exemple #22
0
        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;
                }
            }
        }