-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[API Proposal]: HttpClient telemetry extensibility #103130
Comments
Tagging subscribers to this area: @dotnet/ncl |
@antonfirsov instead of a "list of callbacks" or |
I know the examples are just that, but they made me consider something, so I'm going to mention it here for something to consider towards the design. The examples use hard-coded URLs, so the conditional filters/templates etc are also specified inline to do the redaction using the same hard-coded values. For applications where the host is configured through IConfiguration, it should be relatively simple to match a request URI against resolved configuration/options. Sometimes callback-based APIs cause friction here due to lack of access to the service provider or needing to capture state into it because of that. |
Wouldn't that matching be also done by a callback? Or would you expect the HttpClientFactory middleware to implement it? Can you elaborate on your idea with some examples? |
So with OpenTelemetry as an example, the enrichment is typically configured as part of the IoC registrations, and the Essentially, anything regarding Configuration: services.AddHttpClient("MyClient", (client, serviceProvider) =>
{
var configuration = serviceProvider.GetRequiredService<IConfiguration>();
client.BaseAddress = new(configuration["MyClientBaseAddress"]);
}).ConfigureDiagnosticOptions((options, serviceProvider) =>
{
// This example is just illustrative - as written it's not very efficient or well-named
options.UriRedactorCallback = uri =>
{
// If IConfiguration supports being reloaded remotely, it needs to be retrieved per-request.
// A better approach would be via IOptionsMonitor<T> with bound configuration, for example.
var configuration = serviceProvider.GetRequiredService<IConfiguration>();
var baseAddress = new(configuration["MyClientBaseAddress"])
if (uri.Host == baseAddress.Host && uri.LocalPath.StartsWith("/u/"))
{
return $"{baseAddress}/u/REDACTED";
}
return "REDIRECTED";
};
}); Usage: using HttpClient client = httpClientFactory.CreateClient("MyClient");
using HttpRequestMessage request = new(HttpMethod.Get, "/u/321");
using HttpResponseMessage response = await client.SendAsync(request); |
There was a strong pushback against the proposed API shape because the way it's tied to a request. We were not able to gather enough information on time to create a better design everyone will be happy about. Pushing this to .NET 10. |
Background and motivation
There are 2 feature requests for .NET 9 which require configuring HttpClient telemetry and logging behavior on per-request basis:
.NET 9.0
Native Trace Instrumentation Support for HttpClient as per OTel specification #93019 requires us to introduce enrichment and filtering capabilities for HttpClient's Distributed Tracing. It seems reasonable to matchMetricsEnrichmentContext
functionality enabling the registration of enricher and filtering callbacks per-request, enabling various extension points (eg. handlers) to add their own callbacks independently.Besides redaction, in the future we may want to implement a url templatization mechanism so we can emit
url.template
for metrics and activities where the template has to be set on a per-request basis.We could introduce distinct utility methods for each feature like we did when we added
MetricsEnrichmentContext.AddCallback
. However, this would lead to API friction and poor discoverability.Instead, I'm proposing a new type,
HttpRequestDiagnosticOptions
to encapsulate all settings that allow customizing telemetry behavior on a per-request basis. I'm also proposing to move the existing metrics enrichment callback registration functionality to the new type.API Proposal
API Usage
1. Redacting
Uri
-sIf redirects are not expected, the application can configure a constant placeholder string to log instead of the actual
Uri
:One possible way to handle redirects:
2. Activity enrichment
3. Activity filtering
[TODO]
4. Metrics enrichment
[TODO]
Alternative Designs
There are several aspects where we could consider alternative apporoaches.
1. Overall API shape
HttpRequestDiagnosticOptions
expose utility methods.2. Expose callback collections via
IList<T>
properties instead ofAdd*Callback()
methods:This would make it more difficult to expose additional enrichment callbacks registration when the request is being sent. With the current method approach we can do the following:
3. Instead of
UriRedactorCallback
, expose pre-defined redaction modes.This might be easier to use for the most common use-cases, but less flexible. Eg. it wouldn't allow users to handle redirects.
Risks
UriRedactionCallback
turns out to be too difficult to useThe text was updated successfully, but these errors were encountered: