-
Notifications
You must be signed in to change notification settings - Fork 764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modify httpclient instrumentation to take advantage of sampling decision #1894
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,49 +67,67 @@ public HttpHandlerDiagnosticListener(HttpClientInstrumentationOptions options) | |
|
||
public override void OnStartActivity(Activity activity, object payload) | ||
{ | ||
// The overall flow of what HttpClient library does is as below: | ||
// Activity.Start() | ||
// DiagnosticSource.WriteEvent("Start", payload) | ||
// DiagnosticSource.WriteEvent("Stop", payload) | ||
// Activity.Stop() | ||
|
||
// This method is in the WriteEvent("Start", payload) path. | ||
// By this time, samplers have already run and | ||
// activity.IsAllDataRequested populated accordingly. | ||
|
||
if (Sdk.SuppressInstrumentation) | ||
{ | ||
return; | ||
} | ||
|
||
if (!this.startRequestFetcher.TryFetch(payload, out HttpRequestMessage request) || request == null) | ||
{ | ||
HttpInstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener), nameof(this.OnStartActivity)); | ||
return; | ||
} | ||
|
||
// TODO: Investigate why this check is needed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it was put for redirection cases where a redirect request might already have the context in the headers. But I don't think the listener callback gets called for redirect cases. I tried this scenario: Call In the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know there were cases when I was working on HttpWebRequest instrumentation where it would re-use the request, but it has been a while so my memory is foggy. I think SSL upgrade/downgrade was one of them? Pretty sure I added a test or two for it. That is for the .NET Framework stuff but posting here because there are probably many similarities with the .NET Core side. |
||
if (Propagators.DefaultTextMapPropagator.Extract(default, request, HttpRequestMessageContextPropagation.HeaderValuesGetter) != default) | ||
{ | ||
// this request is already instrumented, we should back off | ||
activity.IsAllDataRequested = false; | ||
return; | ||
} | ||
|
||
// Propagate context irrespective of sampling decision | ||
var textMapPropagator = Propagators.DefaultTextMapPropagator; | ||
|
||
if (!(this.httpClientSupportsW3C && textMapPropagator is TraceContextPropagator)) | ||
{ | ||
textMapPropagator.Inject(new PropagationContext(activity.Context, Baggage.Current), request, HttpRequestMessageContextPropagation.HeaderValueSetter); | ||
} | ||
|
||
try | ||
// enrich Activity from payload only if sampling decision | ||
// is favorable. | ||
if (activity.IsAllDataRequested) | ||
{ | ||
if (this.options.EventFilter(activity.OperationName, request) == false) | ||
try | ||
{ | ||
HttpInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); | ||
if (this.options.EventFilter(activity.OperationName, request) == false) | ||
{ | ||
HttpInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); | ||
activity.IsAllDataRequested = false; | ||
return; | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
HttpInstrumentationEventSource.Log.RequestFilterException(ex); | ||
activity.IsAllDataRequested = false; | ||
return; | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
HttpInstrumentationEventSource.Log.RequestFilterException(ex); | ||
activity.IsAllDataRequested = false; | ||
return; | ||
} | ||
|
||
activity.DisplayName = HttpTagHelper.GetOperationNameForHttpMethod(request.Method); | ||
activity.DisplayName = HttpTagHelper.GetOperationNameForHttpMethod(request.Method); | ||
|
||
ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); | ||
ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Client); | ||
ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); | ||
ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Client); | ||
|
||
if (activity.IsAllDataRequested) | ||
{ | ||
activity.SetTag(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method)); | ||
activity.SetTag(SemanticConventions.AttributeHttpHost, HttpTagHelper.GetHostTagValueFromRequestUri(request.RequestUri)); | ||
activity.SetTag(SemanticConventions.AttributeHttpUrl, request.RequestUri.OriginalString); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this check is done to make sure to have no side-effect if under supression. Even without this, TracerProviderSdk drops the activity if under supressions, but this method does propagation. This check prevents every side effect including propagation if under suppression.