Esempio n. 1
0
        public override void OnStartActivity(Activity activity, object payload)
        {
            const string EventNameSuffix = ".OnStartActivity";

            if (!(this.startRequestFetcher.Fetch(payload) is HttpRequestMessage request))
            {
                InstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener) + EventNameSuffix);
                return;
            }

            if (request.Headers.Contains("traceparent"))
            {
                // this request is already instrumented, we should back off
                return;
            }

            // TODO: Avoid the reflection hack once .NET ships new Activity with Kind settable.
            activity.GetType().GetProperty("Kind").SetValue(activity, ActivityKind.Client);
            activity.DisplayName = HttpTagHelper.GetOperationNameForHttpMethod(request.Method);

            var samplingParameters = new ActivitySamplingParameters(
                activity.Context,
                activity.TraceId,
                activity.DisplayName,
                activity.Kind,
                activity.Tags,
                activity.Links);

            // TODO: Find a way to avoid Instrumentation being tied to Sampler
            var samplingDecision = this.sampler.ShouldSample(samplingParameters);

            activity.IsAllDataRequested = samplingDecision.IsSampled;
            if (samplingDecision.IsSampled)
            {
                activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded;
            }

            if (activity.IsAllDataRequested)
            {
                activity.AddTag(SpanAttributeConstants.ComponentKey, "http");
                activity.AddTag(SpanAttributeConstants.HttpMethodKey, HttpTagHelper.GetNameForHttpMethod(request.Method));
                activity.AddTag(SpanAttributeConstants.HttpHostKey, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri));
                activity.AddTag(SpanAttributeConstants.HttpUrlKey, request.RequestUri.OriginalString);

                if (this.options.SetHttpFlavor)
                {
                    activity.AddTag(SpanAttributeConstants.HttpFlavorKey, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version));
                }
            }

            if (!(this.httpClientSupportsW3C && this.options.TextFormat is TraceContextFormat))
            {
                // TODO: implement this
                // this.options.TextFormat.Inject(span.Context, request, (r, k, v) => r.Headers.Add(k, v));
            }
        }
        private static void AddResponseTags(HttpWebResponse response, Activity activity)
        {
            activity.SetCustomProperty("HttpWebRequest.Response", response);

            if (activity.IsAllDataRequested)
            {
                activity.AddTag(SpanAttributeConstants.HttpStatusCodeKey, HttpTagHelper.GetStatusCodeTagValueFromHttpStatusCode(response.StatusCode));

                Status status = SpanHelper.ResolveSpanStatusForHttpStatusCode((int)response.StatusCode);

                activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
                activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, response.StatusDescription);
            }
        }
        private static void AddResponseTags(HttpWebResponse response, Activity activity)
        {
            activity.SetCustomProperty("HttpWebRequest.Response", response);

            if (activity.IsAllDataRequested)
            {
                activity.AddTag(SemanticConventions.AttributeHttpStatusCode, HttpTagHelper.GetStatusCodeTagValueFromHttpStatusCode(response.StatusCode));

                activity.SetStatus(
                    SpanHelper
                    .ResolveSpanStatusForHttpStatusCode((int)response.StatusCode)
                    .WithDescription(response.StatusDescription));
            }
        }
        private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, Activity activity)
        {
            activity.DisplayName = HttpTagHelper.GetOperationNameForHttpMethod(request.Method);

            InstrumentRequest(request, activity);

            activity.SetCustomProperty("HttpWebRequest.Request", request);

            if (activity.IsAllDataRequested)
            {
                activity.AddTag(SpanAttributeConstants.ComponentKey, "http");
                activity.AddTag(SpanAttributeConstants.HttpMethodKey, request.Method);
                activity.AddTag(SpanAttributeConstants.HttpHostKey, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri));
                activity.AddTag(SpanAttributeConstants.HttpUrlKey, request.RequestUri.OriginalString);
                activity.AddTag(SpanAttributeConstants.HttpFlavorKey, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.ProtocolVersion));
            }
        }
        private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, Activity activity)
        {
            activity.DisplayName = HttpTagHelper.GetOperationNameForHttpMethod(request.Method);

            InstrumentRequest(request, activity);

            activity.SetCustomProperty("HttpWebRequest.Request", request);

            if (activity.IsAllDataRequested)
            {
                activity.AddTag(SemanticConventions.AttributeHttpMethod, request.Method);
                activity.AddTag(SemanticConventions.AttributeHttpHost, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri));
                activity.AddTag(SemanticConventions.AttributeHttpUrl, request.RequestUri.OriginalString);
                if (Options.SetHttpFlavor)
                {
                    activity.AddTag(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.ProtocolVersion));
                }
            }
        }
        public override void OnStartActivity(Activity activity, object payload)
        {
            const string EventNameSuffix = ".OnStartActivity";

            if (!(this.startRequestFetcher.Fetch(payload) is HttpRequestMessage request))
            {
                InstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener) + EventNameSuffix);
                return;
            }

            if (request.Headers.Contains("traceparent"))
            {
                // this request is already instrumented, we should back off
                activity.IsAllDataRequested = false;
                return;
            }

            // TODO: Avoid the reflection hack once .NET ships new Activity with Kind settable.
            activity.GetType().GetProperty("Kind").SetValue(activity, ActivityKind.Client);
            activity.DisplayName = HttpTagHelper.GetOperationNameForHttpMethod(request.Method);

            this.activitySource.Start(activity);

            if (activity.IsAllDataRequested)
            {
                activity.AddTag(SpanAttributeConstants.ComponentKey, "http");
                activity.AddTag(SpanAttributeConstants.HttpMethodKey, HttpTagHelper.GetNameForHttpMethod(request.Method));
                activity.AddTag(SpanAttributeConstants.HttpHostKey, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri));
                activity.AddTag(SpanAttributeConstants.HttpUrlKey, request.RequestUri.OriginalString);

                if (this.options.SetHttpFlavor)
                {
                    activity.AddTag(SpanAttributeConstants.HttpFlavorKey, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version));
                }
            }

            if (!(this.httpClientSupportsW3C && this.options.TextFormat is TraceContextFormatActivity))
            {
                this.options.TextFormat.Inject(activity.Context, request, (r, k, v) => r.Headers.Add(k, v));
            }
        }
        public override void OnStartActivity(Activity activity, object payload)
        {
            if (!(this.startRequestFetcher.Fetch(payload) is HttpRequestMessage request))
            {
                DependenciesInstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener), nameof(this.OnStartActivity));
                return;
            }

            if (this.options.TextFormat.IsInjected(request, HttpRequestMessageHeaderValuesGetter))
            {
                // this request is already instrumented, we should back off
                activity.IsAllDataRequested = false;
                return;
            }

            activity.SetKind(ActivityKind.Client);
            activity.DisplayName = HttpTagHelper.GetOperationNameForHttpMethod(request.Method);

            this.activitySource.Start(activity);

            if (activity.IsAllDataRequested)
            {
                activity.AddTag(SemanticConventions.AttributeHTTPMethod, HttpTagHelper.GetNameForHttpMethod(request.Method));
                activity.AddTag(SemanticConventions.AttributeHTTPHost, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri));
                activity.AddTag(SemanticConventions.AttributeHTTPURL, request.RequestUri.OriginalString);

                if (this.options.SetHttpFlavor)
                {
                    activity.AddTag(SemanticConventions.AttributeHTTPFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version));
                }
            }

            if (!(this.httpClientSupportsW3C && this.options.TextFormat is TraceContextFormatActivity))
            {
                this.options.TextFormat.Inject(activity.Context, request, HttpRequestMessageHeaderValueSetter);
            }
        }
        private static void AddExceptionTags(Exception exception, Activity activity)
        {
            activity.SetCustomProperty("HttpWebRequest.Exception", exception);

            if (!activity.IsAllDataRequested)
            {
                return;
            }

            Status status;

            if (exception is WebException wexc)
            {
                if (wexc.Response is HttpWebResponse response)
                {
                    activity.AddTag(SpanAttributeConstants.HttpStatusCodeKey, HttpTagHelper.GetStatusCodeTagValueFromHttpStatusCode(response.StatusCode));

                    status = SpanHelper.ResolveSpanStatusForHttpStatusCode((int)response.StatusCode).WithDescription(response.StatusDescription);
                }
                else
                {
                    switch (wexc.Status)
                    {
                    case WebExceptionStatus.Timeout:
                        status = Status.DeadlineExceeded;
                        break;

                    case WebExceptionStatus.NameResolutionFailure:
                        status = Status.InvalidArgument.WithDescription(exception.Message);
                        break;

                    case WebExceptionStatus.SendFailure:
                    case WebExceptionStatus.ConnectFailure:
                    case WebExceptionStatus.SecureChannelFailure:
                    case WebExceptionStatus.TrustFailure:
                        status = Status.FailedPrecondition.WithDescription(exception.Message);
                        break;

                    case WebExceptionStatus.ServerProtocolViolation:
                        status = Status.Unimplemented.WithDescription(exception.Message);
                        break;

                    case WebExceptionStatus.RequestCanceled:
                        status = Status.Cancelled;
                        break;

                    case WebExceptionStatus.MessageLengthLimitExceeded:
                        status = Status.ResourceExhausted.WithDescription(exception.Message);
                        break;

                    default:
                        status = Status.Unknown.WithDescription(exception.Message);
                        break;
                    }
                }
            }
            else
            {
                status = Status.Unknown.WithDescription(exception.Message);
            }

            activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
            activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, status.Description);
        }