Skip to content

Latest commit

 

History

History
291 lines (235 loc) · 11.2 KB

File metadata and controls

291 lines (235 loc) · 11.2 KB

HttpClient and HttpWebRequest instrumentation for OpenTelemetry

NuGet NuGet

This is an Instrumentation Library, which instruments System.Net.Http.HttpClient and System.Net.HttpWebRequest and collects metrics and traces about outgoing HTTP requests.

Note: This component is based on the OpenTelemetry semantic conventions for metrics and traces. These conventions are Experimental, and hence, this package is a pre-release. Until a stable version is released, there can be breaking changes. You can track the progress from milestones.

Steps to enable OpenTelemetry.Instrumentation.Http

Step 1: Install Package

Add a reference to the OpenTelemetry.Instrumentation.Http package. Also, add any other instrumentations & exporters you will need.

dotnet add package --prerelease OpenTelemetry.Instrumentation.Http

Step 2: Enable HTTP Instrumentation at application startup

HTTP instrumentation must be enabled at application startup.

Traces

The following example demonstrates adding HttpClient instrumentation with the extension method .AddHttpClientInstrumentation() on TracerProviderBuilder to a console application. This example also sets up the OpenTelemetry Console Exporter, which requires adding the package OpenTelemetry.Exporter.Console to the application.

using OpenTelemetry;
using OpenTelemetry.Trace;

public class Program
{
    public static void Main(string[] args)
    {
        using var tracerProvider = Sdk.CreateTracerProviderBuilder()
            .AddHttpClientInstrumentation()
            .AddConsoleExporter()
            .Build();
    }
}

Metrics

Note Metrics are not available for .NET Framework.

The following example demonstrates adding HttpClient instrumentation with the extension method .AddHttpClientInstrumentation() on MeterProviderBuilder to a console application. This example also sets up the OpenTelemetry Console Exporter, which requires adding the package OpenTelemetry.Exporter.Console to the application.

using OpenTelemetry;
using OpenTelemetry.Metrics;

public class Program
{
    public static void Main(string[] args)
    {
        using var meterProvider = Sdk.CreateMeterProviderBuilder()
            .AddHttpClientInstrumentation()
            .AddConsoleExporter()
            .Build();
    }
}

Refer to this example to see how to enable this instrumentation in an ASP.NET core application.

Refer to this example to see how to enable this instrumentation in an ASP.NET application.

List of metrics produced

The instrumentation is implemented based on metrics semantic conventions. Currently, the instrumentation supports the following metric.

Name Instrument Type Unit Description
http.client.duration Histogram ms Measures the duration of outbound HTTP requests.

Advanced configuration

This instrumentation can be configured to change the default behavior by using HttpClientInstrumentationOptions. It is important to note that there are differences between .NET Framework and newer .NET/.NET Core runtimes which govern what options are used. On .NET Framework, HttpClient uses the HttpWebRequest API. On .NET & .NET Core, HttpWebRequest uses the HttpClient API. As such, depending on the runtime, only one half of the "filter" & "enrich" options are used.

.NET & .NET Core

Filter HttpClient API

This instrumentation by default collects all the outgoing HTTP requests. It allows filtering of requests by using the FilterHttpRequestMessage function option. This defines the condition for allowable requests. The filter function receives the request object (HttpRequestMessage) representing the outgoing request and does not collect telemetry about the request if the filter function returns false or throws an exception.

The following code snippet shows how to use FilterHttpRequestMessage to only allow GET requests.

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddHttpClientInstrumentation(
        // Note: Only called on .NET & .NET Core runtimes.
        (options) => options.FilterHttpRequestMessage =
            (httpRequestMessage) =>
            {
                // Example: Only collect telemetry about HTTP GET requests.
                return httpRequestMessage.Method.Equals(HttpMethod.Get);
            })
    .AddConsoleExporter()
    .Build();

It is important to note that this FilterHttpRequestMessage option is specific to this instrumentation. OpenTelemetry has a concept of a Sampler, and the FilterHttpRequestMessage option does the filtering after the Sampler is invoked.

Enrich HttpClient API

This instrumentation library provides options that can be used to enrich the activity with additional information. These actions are called only when activity.IsAllDataRequested is true. It contains the activity itself (which can be enriched) and the actual raw object.

HttpClientInstrumentationOptions provides 3 enrich options: EnrichWithHttpRequestMessage, EnrichWithHttpResponseMessage and EnrichWithException. These are based on the raw object that is passed in to the action to enrich the activity.

Example:

using System.Net.Http;

var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddHttpClientInstrumentation((options) =>
    {
        // Note: Only called on .NET & .NET Core runtimes.
        options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) =>
        {
            activity.SetTag("requestVersion", httpRequestMessage.Version);
        };
        // Note: Only called on .NET & .NET Core runtimes.
        options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) =>
        {
            activity.SetTag("responseVersion", httpResponseMessage.Version);
        };
        // Note: Called for all runtimes.
        options.EnrichWithException = (activity, exception) =>
        {
            activity.SetTag("stackTrace", exception.StackTrace);
        };
    })
    .Build();

.NET Framework

Filter HttpWebRequest API

This instrumentation by default collects all the outgoing HTTP requests. It allows filtering of requests by using the FilterHttpWebRequest function option. This defines the condition for allowable requests. The filter function receives the request object (HttpWebRequest) representing the outgoing request and does not collect telemetry about the request if the filter function returns false or throws an exception.

The following code snippet shows how to use FilterHttpWebRequest to only allow GET requests.

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddHttpClientInstrumentation(
        // Note: Only called on .NET Framework.
        (options) => options.FilterHttpWebRequest =
            (httpWebRequest) =>
            {
                // Example: Only collect telemetry about HTTP GET requests.
                return httpWebRequest.Method.Equals(HttpMethod.Get.Method);
            })
    .AddConsoleExporter()
    .Build();

It is important to note that this FilterHttpWebRequest option is specific to this instrumentation. OpenTelemetry has a concept of a Sampler, and the FilterHttpWebRequest option does the filtering after the Sampler is invoked.

Enrich HttpWebRequest API

This instrumentation library provides options that can be used to enrich the activity with additional information. These actions are called only when activity.IsAllDataRequested is true. It contains the activity itself (which can be enriched) and the actual raw object.

HttpClientInstrumentationOptions provides 3 enrich options: EnrichWithHttpWebRequest, EnrichWithHttpWebResponse and EnrichWithException. These are based on the raw object that is passed in to the action to enrich the activity.

Example:

using System.Net;

var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddHttpClientInstrumentation((options) =>
    {
        // Note: Only called on .NET Framework.
        options.EnrichWithHttpWebRequest = (activity, httpWebRequest) =>
        {
            activity.SetTag("requestVersion", httpWebRequest.Version);
        };
        // Note: Only called on .NET Framework.
        options.EnrichWithHttpWebResponse = (activity, httpWebResponse) =>
        {
            activity.SetTag("responseVersion", httpWebResponse.Version);
        };
        // Note: Called for all runtimes.
        options.EnrichWithException = (activity, exception) =>
        {
            activity.SetTag("stackTrace", exception.StackTrace);
        };
    })
    .Build();

Processor, is the general extensibility point to add additional properties to any activity. The Enrich option is specific to this instrumentation, and is provided to get access to raw request, response, and exception objects.

RecordException

This instrumentation automatically sets Activity Status to Error if the Http StatusCode is >= 400. Additionally, RecordException feature may be turned on, to store the exception to the Activity itself as ActivityEvent.

Troubleshooting

This component uses an EventSource with the name "OpenTelemetry-Instrumentation-Http" for its internal logging. Please refer to SDK troubleshooting for instructions on seeing these internal logs.

References