Skip to content
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

[Instrumentation.AspNetCore, Instrumentation.HttpClient] Add Enrichment instructions #2059

Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/OpenTelemetry.Instrumentation.AspNetCore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,56 @@ the library you can do so as follows:
});
```

#### Enriching ASP.NET Core Request Metrics

> [!IMPORTANT]
> Only applicable for .NET 8 and newer.

ASP.NET Core supports enriching request metrics using `IHttpMetricsTagsFeature`.
ysolomchenko marked this conversation as resolved.
Show resolved Hide resolved
This feature allows you to add custom tags to metrics.

Here's an example of enriching the `http.server.request.duration` metric:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where do user specify that they intend to enrich http.server.request.duration metric, and nothing else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 99a4211

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still confused. Where does user specify that they intend to enrich "http.server.request.duration" metric, and nothing else?
The example just shows how to get IHttpMetricsTagsFeature and add tags to it. But don't see any place where user selects which metric is this applied to.


```csharp
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using Microsoft.AspNetCore.Http.Features;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
.WithMetrics(builder => builder
.AddAspNetCoreInstrumentation()
.AddConsoleExporter());

var app = builder.Build();

// Middleware to enrich the request metric with a custom tag
app.Use(async (context, next) =>
{
var tagsFeature = context.Features.Get<IHttpMetricsTagsFeature>();
if (tagsFeature != null)
{
// Add a custom tag based on the "utm_medium" query parameter
var source = context.Request.Query["utm_medium"].ToString();
ysolomchenko marked this conversation as resolved.
Show resolved Hide resolved
tagsFeature.Tags.Add(new KeyValuePair<string, object?>("utm_medium", source));
}

await next.Invoke();
});

app.MapGet("/", () => "Hello OpenTelemetry!");

app.Run();
```

In this example:

* Middleware is used to add a custom tag `utm_medium` to the
`http.server.request.duration` metric.
* `IHttpMetricsTagsFeature` is obtained from the `HttpContext`.
This feature is only available if someone is listening to the metric.

#### RecordException

This instrumentation automatically sets Activity Status to Error if an unhandled
Expand Down
59 changes: 59 additions & 0 deletions src/OpenTelemetry.Instrumentation.Http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,65 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder()
.Build();
```

#### Enriching HttpClient Metrics

> [!IMPORTANT]
> Only applicable for .NET 8 and newer.

Metrics enrichment in HttpClient allows adding custom tags to metrics.
This is especially useful for categorizing metrics in dashboards or alerts.
ysolomchenko marked this conversation as resolved.
Show resolved Hide resolved

Using `HttpMetricsEnrichmentContext` for Enrichment
To enrich metrics, you can register callbacks with `HttpMetricsEnrichmentContext`.
This requires setting up a custom `DelegatingHandler` that intercepts requests
and adds custom tags before they are sent to the server.

Here's how you can implement a custom `DelegatingHandler` to enrich metrics:

```csharp
using System.Net.Http.Metrics;

using HttpClient client = new(new EnrichmentHandler() { InnerHandler = new HttpClientHandler() });

await client.GetStringAsync("https://example.com");

sealed class EnrichmentHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpMetricsEnrichmentContext.AddCallback(request, static context =>
{
if (context.Request is not null) // Ensure the request is available.
{
// Use request information to add custom tags
string? userAgent = context.Request.Headers.UserAgent.ToString();
context.AddCustomTag("user_agent", userAgent ?? "unknown");
}
});

return base.SendAsync(request, cancellationToken);
}
}

```

If you're working with `IHttpClientFactory`, you can use `AddHttpMessageHandler`
to register the `EnrichmentHandler`:

```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Net.Http.Metrics;

ServiceCollection services = new();
services.AddHttpClient(Options.DefaultName).AddHttpMessageHandler(() => new EnrichmentHandler());

ServiceProvider serviceProvider = services.BuildServiceProvider();
HttpClient client = serviceProvider.GetRequiredService<HttpClient>();

await client.GetStringAsync("https://example.com");
```

#### .NET Framework

##### Filter HttpWebRequest API
Expand Down