Exemple #1
0
        internal static Scope CreateScope(IHttpControllerContext controllerContext, out AspNetTags tags)
        {
            Scope scope = null;

            tags = null;

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

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

                if (request != null && tracer.InternalActiveScope == null)
                {
                    try
                    {
                        // extract propagated http headers
                        var headers           = request.Headers;
                        var headersCollection = new HttpHeadersCollection(headers);

                        propagatedContext = SpanContextPropagator.Instance.Extract(headersCollection);
                        tagsFromHeaders   = SpanContextPropagator.Instance.ExtractHeaderTags(headersCollection, tracer.Settings.HeaderTags, SpanContextPropagator.HttpRequestHeadersTagPrefix, request.Headers.UserAgent.ToString());
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Error extracting propagated HTTP headers.");
                    }
                }

                tags  = new AspNetTags();
                scope = tracer.StartActiveInternal(OperationName, propagatedContext, tags: tags);
                UpdateSpan(controllerContext, scope.Span, tags, tagsFromHeaders);

                tags.SetAnalyticsSampleRate(IntegrationId, tracer.Settings, enabledWithGlobalSetting: true);
                tracer.TracerManager.Telemetry.IntegrationGeneratedSpan(IntegrationId);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error creating scope.");
            }

            return(scope);
        }
        internal static void UpdateSpan(IHttpControllerContext controllerContext, Span span, AspNetTags tags, IEnumerable <KeyValuePair <string, string> > headerTags)
        {
            try
            {
                var newResourceNamesEnabled = Tracer.Instance.Settings.RouteTemplateResourceNamesEnabled;
                var request    = controllerContext.Request;
                Uri requestUri = request.RequestUri;

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

                string resourceName;

                if (route != null)
                {
                    resourceName = $"{method} {(newResourceNamesEnabled ? "/" : string.Empty)}{route.ToLowerInvariant()}";
                }
                else if (requestUri != null)
                {
                    var cleanUri = UriHelpers.GetCleanUriPath(requestUri);
                    resourceName = $"{method} {cleanUri.ToLowerInvariant()}";
                }
                else
                {
                    resourceName = $"{method}";
                }

                string controller = string.Empty;
                string action     = string.Empty;
                string area       = string.Empty;
                try
                {
                    var routeValues = controllerContext.RouteData.Values;
                    if (routeValues != null)
                    {
                        controller = (routeValues.GetValueOrDefault("controller") as string)?.ToLowerInvariant();
                        action     = (routeValues.GetValueOrDefault("action") as string)?.ToLowerInvariant();
                        area       = (routeValues.GetValueOrDefault("area") as string)?.ToLowerInvariant();
                    }
                }
                catch
                {
                }

                // Replace well-known routing tokens
                resourceName =
                    resourceName
                    .Replace("{area}", area)
                    .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.AspNetArea       = area;
                tags.AspNetRoute      = route;

                if (newResourceNamesEnabled)
                {
                    // set the resource name in the HttpContext so TracingHttpModule can update root span
                    var httpContext = System.Web.HttpContext.Current;
                    if (httpContext is not null)
                    {
                        httpContext.Items[SharedConstants.HttpContextPropagatedResourceNameKey] = resourceName;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error populating scope data.");
            }
        }
Exemple #3
0
        internal static void UpdateSpan(IHttpControllerContext controllerContext, Span span, AspNetTags tags, IEnumerable <KeyValuePair <string, string> > headerTags)
        {
            try
            {
                var newResourceNamesEnabled = Tracer.Instance.Settings.RouteTemplateResourceNamesEnabled;
                var request    = controllerContext.Request;
                Uri requestUri = request.RequestUri;

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

                IDictionary <string, object> routeValues = null;
                try
                {
                    routeValues = controllerContext.RouteData.Values;
                }
                catch
                {
                }

                string resourceName;

                string controller = string.Empty;
                string action     = string.Empty;
                string area       = string.Empty;

                if (route is not null && routeValues is not null)
                {
                    resourceName = AspNetResourceNameHelper.CalculateResourceName(
                        httpMethod: method,
                        routeTemplate: route,
                        routeValues,
                        defaults: null,
                        out area,
                        out controller,
                        out action,
                        addSlashPrefix: newResourceNamesEnabled,
                        expandRouteTemplates: newResourceNamesEnabled && Tracer.Instance.Settings.ExpandRouteTemplatesEnabled);
                }
                else if (requestUri != null)
                {
                    var cleanUri = UriHelpers.GetCleanUriPath(requestUri);
                    resourceName = $"{method} {cleanUri}";
                }
                else
                {
                    resourceName = $"{method}";
                }

                if (route is null && routeValues is not null)
                {
                    // we weren't able to get the route template (somehow) but _were_ able to
                    // get the route values. Not sure how this is possible, but is preexisting behaviour
                    try
                    {
                        controller = (routeValues.GetValueOrDefault("controller") as string)?.ToLowerInvariant();
                        action     = (routeValues.GetValueOrDefault("action") as string)?.ToLowerInvariant();
                        area       = (routeValues.GetValueOrDefault("area") as string)?.ToLowerInvariant();
                    }
                    catch
                    {
                    }
                }

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

                if (tags is not null)
                {
                    tags.AspNetAction     = action;
                    tags.AspNetController = controller;
                    tags.AspNetArea       = area;
                    tags.AspNetRoute      = route;
                }

                if (newResourceNamesEnabled)
                {
                    // set the resource name in the HttpContext so TracingHttpModule can update root span
                    var httpContext = System.Web.HttpContext.Current;
                    if (httpContext is not null)
                    {
                        httpContext.Items[SharedItems.HttpContextPropagatedResourceNameKey] = resourceName;
                    }
                }
            }