private void OnBeginRequest(object sender, EventArgs eventArgs)
        {
            Scope scope = null;

            try
            {
                var tracer = Tracer.Instance;

                if (!tracer.Settings.IsIntegrationEnabled(IntegrationName))
                {
                    // integration disabled
                    return;
                }

                var httpContext = (sender as HttpApplication)?.Context;

                if (httpContext == null)
                {
                    return;
                }

                HttpRequest httpRequest       = httpContext.Request;
                SpanContext propagatedContext = null;

                if (tracer.ActiveScope == null)
                {
                    try
                    {
                        // extract propagated http headers
                        var headers = httpRequest.Headers.Wrap();
                        propagatedContext = SpanContextPropagator.Instance.Extract(headers);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Error extracting propagated HTTP headers.");
                    }
                }

                string host         = httpRequest.Headers.Get("Host");
                string httpMethod   = httpRequest.HttpMethod.ToUpperInvariant();
                string url          = httpRequest.RawUrl.ToLowerInvariant();
                string path         = UriHelpers.GetRelativeUrl(httpRequest.Url, tryRemoveIds: true);
                string resourceName = $"{httpMethod} {path.ToLowerInvariant()}";

                scope = tracer.StartActive(_requestOperationName, propagatedContext);
                scope.Span.DecorateWebServerSpan(resourceName, httpMethod, host, url);

                // set analytics sample rate if enabled
                var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true);
                scope.Span.SetMetric(Tags.Analytics, analyticsSampleRate);

                httpContext.Items[_httpContextScopeKey] = scope;
            }
            catch (Exception ex)
            {
                // Dispose here, as the scope won't be in context items and won't get disposed on request end in that case...
                scope?.Dispose();
                Log.Error(ex, "Datadog ASP.NET HttpModule instrumentation error");
            }
        }
        private static void GetTagValues(
            object actionDescriptor,
            object request,
            out string httpMethod,
            out string host,
            out string resourceName,
            out string url,
            out string controllerName,
            out string actionName)
        {
            controllerName = actionDescriptor.GetProperty <string>("ControllerName").GetValueOrDefault()?.ToLowerInvariant();

            actionName = actionDescriptor.GetProperty <string>("ActionName").GetValueOrDefault()?.ToLowerInvariant();

            host = request.GetProperty("Host").GetProperty <string>("Value").GetValueOrDefault();

            httpMethod = request.GetProperty <string>("Method").GetValueOrDefault()?.ToUpperInvariant() ?? "UNKNOWN";

            string pathBase = request.GetProperty("PathBase").GetProperty <string>("Value").GetValueOrDefault();

            string path = request.GetProperty("Path").GetProperty <string>("Value").GetValueOrDefault();

            string queryString = request.GetProperty("QueryString").GetProperty <string>("Value").GetValueOrDefault();

            url = $"{pathBase}{path}{queryString}";

            string resourceUrl = actionDescriptor.GetProperty("AttributeRouteInfo").GetProperty <string>("Template").GetValueOrDefault() ??
                                 UriHelpers.GetRelativeUrl(new Uri($"https://{host}{url}"), tryRemoveIds: true).ToLowerInvariant();

            resourceName = $"{httpMethod} {resourceUrl}";
        }
        private static void GetTagValues(
            object request,
            out string url,
            out string httpMethod,
            out string host,
            out string resourceName)
        {
            host = request.GetProperty("Host").GetProperty <string>("Value").GetValueOrDefault();

            httpMethod = request.GetProperty <string>("Method").GetValueOrDefault()?.ToUpperInvariant() ?? "UNKNOWN";

            string pathBase = request.GetProperty("PathBase").GetProperty <string>("Value").GetValueOrDefault();

            string path = request.GetProperty("Path").GetProperty <string>("Value").GetValueOrDefault();

            string queryString = request.GetProperty("QueryString").GetProperty <string>("Value").GetValueOrDefault();

            string scheme = request.GetProperty <string>("Scheme").GetValueOrDefault()?.ToUpperInvariant() ?? "http";

            url = $"{pathBase}{path}{queryString}";

            string resourceUrl = UriHelpers.GetRelativeUrl(new Uri($"{scheme}://{host}{url}"), tryRemoveIds: true).ToLowerInvariant();

            resourceName = $"{httpMethod} {resourceUrl}";
        }
Ejemplo n.º 4
0
        public override bool TryGetResourceName(out string resourceName)
        { // TODO: This will need to be moved out into a strategy to support extending to other integrations...
            var httpMethod = (GetHttpMethod() ?? Scope?.Span?.GetHttpMethod() ?? "GET").ToUpperInvariant();

            string suffix = _httpContext.Request?.Url == null
                                ? string.Empty
                                : UriHelpers.GetRelativeUrl(_httpContext.Request.Url, tryRemoveIds: true);

            resourceName = $"{httpMethod} {suffix.ToLowerInvariant()}";

            return(true);
        }
Ejemplo n.º 5
0
        private void OnHostingHttpRequestInStart(object arg)
        {
            var httpContext = HttpRequestInStartHttpContextFetcher.Fetch <HttpContext>(arg);

            if (ShouldIgnore(httpContext))
            {
                if (_isLogLevelDebugEnabled)
                {
                    Log.Debug("Ignoring request");
                }
            }
            else
            {
                HttpRequest request    = httpContext.Request;
                string      host       = request.Host.Value;
                string      httpMethod = request.Method?.ToUpperInvariant() ?? "UNKNOWN";
                string      url        = GetUrl(request);

                string absolutePath = request.Path.Value;

                if (request.PathBase.HasValue)
                {
                    absolutePath = request.PathBase.Value + absolutePath;
                }

                string resourceUrl = UriHelpers.GetRelativeUrl(absolutePath, tryRemoveIds: true)
                                     .ToLowerInvariant();

                string resourceName = $"{httpMethod} {resourceUrl}";

                SpanContext propagatedContext = ExtractPropagatedContext(request);
                var         tagsFromHeaders   = ExtractHeaderTags(request, _tracer);

                Span span = _tracer.StartSpan(HttpRequestInOperationName, propagatedContext)
                            .SetTag(Tags.InstrumentationName, ComponentName);

                span.DecorateWebServerSpan(resourceName, httpMethod, host, url, tagsFromHeaders);

                // set analytics sample rate if enabled
                var analyticsSampleRate = _tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true);
                span.SetMetric(Tags.Analytics, analyticsSampleRate);

                Scope scope = _tracer.ActivateSpan(span);

                _options.OnRequest?.Invoke(scope.Span, httpContext);
            }
        }
        private void OnHostingHttpRequestInStart(object arg)
        {
            var tracer = _tracer ?? Tracer.Instance;

            if (!tracer.Settings.IsIntegrationEnabled(IntegrationName))
            {
                return;
            }

            var         httpContext = HttpRequestInStartHttpContextFetcher.Fetch <HttpContext>(arg);
            HttpRequest request     = httpContext.Request;
            string      host        = request.Host.Value;
            string      httpMethod  = request.Method?.ToUpperInvariant() ?? "UNKNOWN";
            string      url         = GetUrl(request);

            string absolutePath = request.Path.Value;

            if (request.PathBase.HasValue)
            {
                absolutePath = request.PathBase.Value + absolutePath;
            }

            string resourceUrl = UriHelpers.GetRelativeUrl(absolutePath, tryRemoveIds: true)
                                 .ToLowerInvariant();

            string resourceName = $"{httpMethod} {resourceUrl}";

            SpanContext propagatedContext = ExtractPropagatedContext(request);
            var         tagsFromHeaders   = ExtractHeaderTags(request, tracer);

            var tags  = new AspNetCoreTags();
            var scope = tracer.StartActiveWithTags(HttpRequestInOperationName, propagatedContext, tags: tags);

            tags.InstrumentationName = ComponentName;

            scope.Span.DecorateWebServerSpan(resourceName, httpMethod, host, url, tags, tagsFromHeaders);

            // set analytics sample rate if enabled
            var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true);

            if (analyticsSampleRate != null)
            {
                tags.AnalyticsSampleRate = analyticsSampleRate;
            }
        }
Ejemplo n.º 7
0
        private void OnHostingHttpRequestInStart(object arg)
        {
            var httpContext = (HttpContext)HttpRequestInStartHttpContextFetcher.Fetch(arg);

            if (ShouldIgnore(httpContext))
            {
                if (_isLogLevelDebugEnabled)
                {
                    Log.Debug("Ignoring request");
                }
            }
            else
            {
                HttpRequest request    = httpContext.Request;
                string      host       = request.Host.Value;
                string      httpMethod = request.Method?.ToUpperInvariant() ?? "UNKNOWN";
                string      url        = GetUrl(request);

                string resourceUrl = UriHelpers.GetRelativeUrl(new Uri(url), tryRemoveIds: true)
                                     .ToLowerInvariant();

                var         propagator        = _tracer.Propagator;
                SpanContext propagatedContext = ExtractPropagatedContext(propagator, request);

                Span span = _tracer.StartSpan(HttpRequestInOperationName, propagatedContext)
                            .SetTag(Tags.InstrumentationName, ComponentName);

                IPAddress remoteIp = null;
                if (Tracing.Tracer.Instance.Settings.AddClientIpToServerSpans)
                {
                    remoteIp = httpContext?.Connection?.RemoteIpAddress;
                }

                span.DecorateWebServerSpan(resourceUrl, httpMethod, host, url, remoteIp);
                span.SetTag(Tags.InstrumentationName, IntegrationName);

                // set analytics sample rate if enabled
                var analyticsSampleRate = _tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true);
                span.SetMetric(Tags.Analytics, analyticsSampleRate);

                Scope scope = _tracer.ActivateSpan(span);

                _options.OnRequest?.Invoke(scope.Span, httpContext);
            }
        }
Ejemplo n.º 8
0
        private static void UpdateSpan(object controllerContext, Span span, AspNetTags tags, IEnumerable <KeyValuePair <string, string> > headerTags)
        {
            try
            {
                object request    = controllerContext.GetProperty <object>("Request").GetValueOrDefault();
                Uri    requestUri = request.GetProperty <Uri>("RequestUri").GetValueOrDefault();

                string host        = request.GetProperty <object>("Headers").GetProperty <string>("Host").GetValueOrDefault() ?? string.Empty;
                string rawUrl      = requestUri?.ToString().ToLowerInvariant() ?? string.Empty;
                string absoluteUri = requestUri?.AbsoluteUri?.ToLowerInvariant() ?? string.Empty;
                string method      = request.GetProperty <object>("Method").GetProperty <string>("Method").GetValueOrDefault()?.ToUpperInvariant() ?? "GET";
                string route       = null;
                try
                {
                    route = controllerContext.GetProperty <object>("RouteData").GetProperty <object>("Route").GetProperty <string>("RouteTemplate").GetValueOrDefault();
                }
                catch
                {
                }

                string resourceName = $"{method} {absoluteUri.ToLowerInvariant()}";

                if (route != null)
                {
                    resourceName = $"{method} {route.ToLowerInvariant()}";
                }
                else if (requestUri != null)
                {
                    var cleanUri = UriHelpers.GetRelativeUrl(requestUri, tryRemoveIds: true);
                    resourceName = $"{method} {cleanUri.ToLowerInvariant()}";
                }

                string controller = string.Empty;
                string action     = string.Empty;
                try
                {
                    var routeValues = controllerContext.GetProperty <object>("RouteData").GetProperty <IDictionary <string, object> >("Values").GetValueOrDefault();
                    if (routeValues != null)
                    {
                        controller = (routeValues.GetValueOrDefault("controller") as string)?.ToLowerInvariant();
                        action     = (routeValues.GetValueOrDefault("action") as string)?.ToLowerInvariant();
                    }
                }
                catch
                {
                }

                // Fail safe to catch templates in routing values
                resourceName =
                    resourceName
                    .Replace("{controller}", controller)
                    .Replace("{action}", action);

                span.DecorateWebServerSpan(
                    resourceName: resourceName,
                    method: method,
                    host: host,
                    httpUrl: rawUrl,
                    tags,
                    headerTags);

                tags.AspNetAction     = action;
                tags.AspNetController = controller;
                tags.AspNetRoute      = route;
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error populating scope data.");
            }
        }
        /// <summary>
        /// Creates a scope used to instrument an MVC action and populates some common details.
        /// </summary>
        /// <param name="controllerContext">The System.Web.Mvc.ControllerContext that was passed as an argument to the instrumented method.</param>
        /// <returns>A new scope used to instrument an MVC action.</returns>
        public static Scope CreateScope(object controllerContext)
        {
            Scope scope = null;

            try
            {
                if (!Tracer.Instance.Settings.IsIntegrationEnabled(IntegrationName))
                {
                    // integration disabled, don't create a scope, skip this trace
                    return(null);
                }

                if (controllerContext == null || controllerContext.GetType().FullName != ControllerContextTypeName)
                {
                    return(null);
                }

                var httpContext = controllerContext.GetProperty <HttpContextBase>("HttpContext").GetValueOrDefault();

                if (httpContext == null)
                {
                    return(null);
                }

                string host         = httpContext.Request.Headers.Get("Host");
                string httpMethod   = httpContext.Request.HttpMethod.ToUpperInvariant();
                string url          = httpContext.Request.RawUrl.ToLowerInvariant();
                string resourceName = null;

                RouteData            routeData   = controllerContext.GetProperty <RouteData>("RouteData").GetValueOrDefault();
                Route                route       = routeData?.Route as Route;
                RouteValueDictionary routeValues = routeData?.Values;

                if (route == null && routeData?.Route.GetType().FullName == RouteCollectionRouteTypeName)
                {
                    var routeMatches = routeValues?.GetValueOrDefault("MS_DirectRouteMatches") as List <RouteData>;

                    if (routeMatches?.Count > 0)
                    {
                        // route was defined using attribute routing i.e. [Route("/path/{id}")]
                        // get route and routeValues from the RouteData in routeMatches
                        route       = routeMatches[0].Route as Route;
                        routeValues = routeMatches[0].Values;

                        if (route != null)
                        {
                            var resourceUrl = route.Url?.ToLowerInvariant() ?? string.Empty;
                            if (resourceUrl.FirstOrDefault() != '/')
                            {
                                resourceUrl = string.Concat("/", resourceUrl);
                            }

                            resourceName = $"{httpMethod} {resourceUrl}";
                        }
                    }
                }

                if (string.IsNullOrEmpty(resourceName) && httpContext.Request.Url != null)
                {
                    var cleanUri = UriHelpers.GetRelativeUrl(httpContext.Request.Url, tryRemoveIds: true);
                    resourceName = $"{httpMethod} {cleanUri.ToLowerInvariant()}";
                }

                string controllerName = (routeValues?.GetValueOrDefault("controller") as string)?.ToLowerInvariant();
                string actionName     = (routeValues?.GetValueOrDefault("action") as string)?.ToLowerInvariant();

                if (string.IsNullOrEmpty(resourceName))
                {
                    // Keep the legacy resource name, just to have something
                    resourceName = $"{httpMethod} {controllerName}.{actionName}";
                }

                SpanContext propagatedContext = null;
                var         tracer            = Tracer.Instance;
                var         tagsFromHeaders   = Enumerable.Empty <KeyValuePair <string, string> >();

                if (tracer.ActiveScope == null)
                {
                    try
                    {
                        // extract propagated http headers
                        var headers = httpContext.Request.Headers.Wrap();
                        propagatedContext = SpanContextPropagator.Instance.Extract(headers);
                        tagsFromHeaders   = SpanContextPropagator.Instance.ExtractHeaderTags(headers, tracer.Settings.HeaderTags);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Error extracting propagated HTTP headers.");
                    }
                }

                scope = Tracer.Instance.StartActive(OperationName, propagatedContext);
                Span span = scope.Span;

                // Fail safe to catch templates in routing values
                resourceName =
                    resourceName
                    .Replace("{controller}", controllerName)
                    .Replace("{action}", actionName);

                span.DecorateWebServerSpan(
                    resourceName: resourceName,
                    method: httpMethod,
                    host: host,
                    httpUrl: url,
                    tags: tagsFromHeaders);
                span.SetTag(Tags.AspNetRoute, route?.Url);
                span.SetTag(Tags.AspNetController, controllerName);
                span.SetTag(Tags.AspNetAction, actionName);

                // set analytics sample rate if enabled
                var analyticsSampleRate = tracer.Settings.GetIntegrationAnalyticsSampleRate(IntegrationName, enabledWithGlobalSetting: true);
                span.SetMetric(Tags.Analytics, analyticsSampleRate);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error creating or populating scope.");
            }

            return(scope);
        }
        private static void UpdateSpan(dynamic controllerContext, Span span)
        {
            try
            {
                var req = controllerContext?.Request as HttpRequestMessage;

                string host        = req?.Headers?.Host ?? string.Empty;
                string rawUrl      = req?.RequestUri?.ToString().ToLowerInvariant() ?? string.Empty;
                string absoluteUri = req?.RequestUri?.AbsoluteUri?.ToLowerInvariant() ?? string.Empty;
                string method      = controllerContext?.Request?.Method?.Method?.ToUpperInvariant() ?? "GET";
                string route       = null;
                try
                {
                    route = controllerContext?.RouteData?.Route?.RouteTemplate;
                }
                catch
                {
                }

                string resourceName = $"{method} {absoluteUri.ToLowerInvariant()}";

                if (route != null)
                {
                    resourceName = $"{method} {route.ToLowerInvariant()}";
                }
                else if (req?.RequestUri != null)
                {
                    var cleanUri = UriHelpers.GetRelativeUrl(req?.RequestUri, tryRemoveIds: true);
                    resourceName = $"{method} {cleanUri.ToLowerInvariant()}";
                }

                string controller = string.Empty;
                string action     = string.Empty;
                try
                {
                    if (controllerContext?.RouteData?.Values is IDictionary <string, object> routeValues)
                    {
                        controller = (routeValues.GetValueOrDefault("controller") as string)?.ToLowerInvariant();
                        action     = (routeValues.GetValueOrDefault("action") as string)?.ToLowerInvariant();
                    }
                }
                catch
                {
                }

                // Fail safe to catch templates in routing values
                resourceName =
                    resourceName
                    .Replace("{controller}", controller)
                    .Replace("{action}", action);

                IPAddress remoteIp = null;
                if (req != null && Tracer.Instance.Settings.AddClientIpToServerSpans)
                {
                    var httpContextWrapper = req.Properties.GetValueOrDefault("MS_HttpContext") as HttpContextWrapper;
                    if (httpContextWrapper != null)
                    {
                        IPAddress.TryParse(httpContextWrapper.Request.UserHostAddress, out remoteIp);
                    }
                    else
                    {
                        var remoteEndpoint = req.Properties.GetValueOrDefault(RemoteEndpointMessageProperty.Name) as RemoteEndpointMessageProperty;
                        if (remoteEndpoint != null)
                        {
                            IPAddress.TryParse(remoteEndpoint.Address, out remoteIp);
                        }
                    }
                }

                span.DecorateWebServerSpan(
                    resourceName: resourceName,
                    method: method,
                    host: host,
                    httpUrl: rawUrl,
                    remoteIp: remoteIp);
                span.SetTag(Tags.AspNetAction, action);
                span.SetTag(Tags.AspNetController, controller);
                span.SetTag(Tags.AspNetRoute, route);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error populating scope data.");
            }
        }
Ejemplo n.º 11
0
        private void OnBeginRequest(object sender, EventArgs eventArgs)
        {
            Scope scope = null;

            try
            {
                var tracer = Tracer.Instance;

                if (!tracer.Settings.IsIntegrationEnabled(IntegrationId))
                {
                    // integration disabled
                    return;
                }

                var httpContext = (sender as HttpApplication)?.Context;

                if (httpContext == null)
                {
                    return;
                }

                HttpRequest httpRequest       = httpContext.Request;
                SpanContext propagatedContext = null;
                var         tagsFromHeaders   = Enumerable.Empty <KeyValuePair <string, string> >();

                if (tracer.ActiveScope == null)
                {
                    try
                    {
                        // extract propagated http headers
                        var headers = httpRequest.Headers.Wrap();
                        propagatedContext = SpanContextPropagator.Instance.Extract(headers);
                        tagsFromHeaders   = SpanContextPropagator.Instance.ExtractHeaderTags(headers, tracer.Settings.HeaderTags);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Error extracting propagated HTTP headers.");
                    }
                }

                string host         = httpRequest.Headers.Get("Host");
                string httpMethod   = httpRequest.HttpMethod.ToUpperInvariant();
                string url          = httpRequest.RawUrl.ToLowerInvariant();
                string path         = UriHelpers.GetRelativeUrl(httpRequest.Url, tryRemoveIds: true);
                string resourceName = $"{httpMethod} {path.ToLowerInvariant()}";

                var tags = new WebTags();
                scope = tracer.StartActiveWithTags(_requestOperationName, propagatedContext, tags: tags);
                scope.Span.DecorateWebServerSpan(resourceName, httpMethod, host, url, tags, tagsFromHeaders);

                tags.SetAnalyticsSampleRate(IntegrationId, tracer.Settings, enabledWithGlobalSetting: true);

                httpContext.Items[_httpContextScopeKey] = scope;

                // Decorate the incoming HTTP Request with distributed tracing headers
                // in case the next processor cannot access the stored Scope
                // (e.g. WCF being hosted in IIS)
                SpanContextPropagator.Instance.Inject(scope.Span.Context, httpRequest.Headers.Wrap());
            }
            catch (Exception ex)
            {
                // Dispose here, as the scope won't be in context items and won't get disposed on request end in that case...
                scope?.Dispose();
                Log.Error(ex, "Datadog ASP.NET HttpModule instrumentation error");
            }
        }
Ejemplo n.º 12
0
        private static void UpdateSpan(dynamic controllerContext, Span span, IEnumerable <KeyValuePair <string, string> > headerTags)
        {
            try
            {
                var req = controllerContext?.Request;

                string host        = req?.Headers?.Host ?? string.Empty;
                string rawUrl      = req?.RequestUri?.ToString().ToLowerInvariant() ?? string.Empty;
                string absoluteUri = req?.RequestUri?.AbsoluteUri?.ToLowerInvariant() ?? string.Empty;
                string method      = controllerContext?.Request?.Method?.Method?.ToUpperInvariant() ?? "GET";
                string route       = null;
                try
                {
                    route = controllerContext?.RouteData?.Route?.RouteTemplate;
                }
                catch
                {
                }

                string resourceName = $"{method} {absoluteUri.ToLowerInvariant()}";

                if (route != null)
                {
                    resourceName = $"{method} {route.ToLowerInvariant()}";
                }
                else if (req?.RequestUri != null)
                {
                    var cleanUri = UriHelpers.GetRelativeUrl(req?.RequestUri, tryRemoveIds: true);
                    resourceName = $"{method} {cleanUri.ToLowerInvariant()}";
                }

                string controller = string.Empty;
                string action     = string.Empty;
                try
                {
                    if (controllerContext?.RouteData?.Values is IDictionary <string, object> routeValues)
                    {
                        controller = (routeValues.GetValueOrDefault("controller") as string)?.ToLowerInvariant();
                        action     = (routeValues.GetValueOrDefault("action") as string)?.ToLowerInvariant();
                    }
                }
                catch
                {
                }

                // Fail safe to catch templates in routing values
                resourceName =
                    resourceName
                    .Replace("{controller}", controller)
                    .Replace("{action}", action);

                span.DecorateWebServerSpan(
                    resourceName: resourceName,
                    method: method,
                    host: host,
                    httpUrl: rawUrl,
                    tags: headerTags);
                span.SetTag(Tags.AspNetAction, action);
                span.SetTag(Tags.AspNetController, controller);
                span.SetTag(Tags.AspNetRoute, route);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error populating scope data.");
            }
        }