This is an Instrumentation Library, which instruments System.Net.Http.HttpClient and System.Net.HttpWebRequest and collects telemetry about outgoing HTTP requests.
Add a reference to the OpenTelemetry.Instrumentation.Http
package. Also, add any other instrumentations & exporters you will need.
dotnet add package OpenTelemetry.Instrumentation.Http
HTTP instrumentation must be enabled at application startup.
The following example demonstrates adding HTTP instrumentation 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.Trace;
public class Program
{
public static void Main(string[] args)
{
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation()
.AddConsoleExporter()
.Build();
}
}
For an ASP.NET Core application, adding instrumentation is typically done in
the ConfigureServices
of your Startup
class. Refer to documentation for
OpenTelemetry.Instrumentation.AspNetCore.
For an ASP.NET application, adding instrumentation is typically done in the
Global.asax.cs
. Refer to documentation for OpenTelemetry.Instrumentation.AspNet.
This instrumentation can be configured to change the default behavior by using
HttpClientInstrumentationOptions
(.NET/.NET Core applications) or
HttpWebRequestInstrumentationOptions
(.NET Framework applications). It is
important to note that even if HttpClient
is used in .NET Framework
applications, it underneath uses HttpWebRequest
. Because of this,
HttpWebRequestInstrumentationOptions
is the configuration option for .NET
Framework applications, irrespective of whether HttpWebRequest
or HttpClient
is used.
By default, this instrumentation does not add the http.flavor
attribute. The
http.flavor
attribute specifies the kind of HTTP protocol used
(e.g., 1.1
for HTTP 1.1). The SetHttpFlavor
option can be used to include
the http.flavor
attribute.
The following example shows how to use SetHttpFlavor
.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation(
(options) => options.SetHttpFlavor = true)
.AddConsoleExporter()
.Build();
This instrumentation by default collects all the outgoing HTTP requests. It
allows filtering of requests by using the Filter
function option. This defines
the condition for allowable requests. The Filter receives the request object -
HttpRequestMessage
(when using HttpClientInstrumentationOptions
) and
HttpWebRequest
(when using HttpWebRequestInstrumentationOptions
) -
representing the outgoing request and does not collect telemetry about the
request if the Filter returns false or throws exception.
The following code snippet shows how to use Filter
to only allow GET
requests.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation(
(options) => options.Filter =
(httpRequestMessage) =>
{
// only collect telemetry about HTTP GET requests
return httpRequestMessage.Method.Equals(HttpMethod.Get);
})
.AddConsoleExporter()
.Build();
It is important to note that this Filter
option is specific to this
instrumentation. OpenTelemetry has a concept of a
Sampler,
and the Filter
option does the filtering after the Sampler is invoked.
This option allows one to enrich the activity with additional information from
the raw request and response objects. The Enrich
action is called only when
activity.IsAllDataRequested
is true
. It contains the activity itself (which
can be enriched), the name of the event, and the actual raw object. The object
type is different for HttpClientInstrumentationOptions
vs
HttpWebRequestInstrumentationOptions
and is detailed below.
For event name "OnStartActivity", the actual object will be
HttpRequestMessage
.
For event name "OnStopActivity", the actual object will be
HttpResponseMessage
.
For event name "OnException", the actual object will be
Exception
.
Example:
using System.Net.Http;
var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation((options) => options.Enrich
= (activity, eventName, rawObject) =>
{
if (eventName.Equals("OnStartActivity"))
{
if (rawObject is HttpRequestMessage request)
{
activity.SetTag("requestVersion", request.Version);
}
}
else if (eventName.Equals("OnStopActivity"))
{
if (rawObject is HttpResponseMessage response)
{
activity.SetTag("responseVersion", response.Version);
}
}
else if (eventName.Equals("OnException"))
{
if (rawObject is Exception exception)
{
activity.SetTag("stackTrace", exception.StackTrace);
}
}
}).Build();
For event name "OnStartActivity", the actual object will be
HttpWebRequest
.
For event name "OnStopActivity", the actual object will be
HttpWebResponse
.
For event name "OnException", the actual object will be
Exception
.
Example:
using System.Net;
var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation((options) => options.Enrich
= (activity, eventName, rawObject) =>
{
if (eventName.Equals("OnStartActivity"))
{
if (rawObject is HttpWebRequest request)
{
activity.SetTag("requestVersion", request.ProtocolVersion);
}
}
else if (eventName.Equals("OnStopActivity"))
{
if (rawObject is HttpWebResponse response)
{
activity.SetTag("responseVersion", response.ProtocolVersion);
}
}
else if (eventName.Equals("OnException"))
{
if (rawObject is Exception 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.
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.