.NET Framework instrumentation configuration
OpenTelemetry supports both .NET and .NET Framework (an older Windows-based .NET implementation).
If you’re already using the modern, cross-platform implementation of .NET, you can skip this article.
ASP.NET Initialization
Initialization for ASP.NET is a little different than for ASP.NET Core.
First, install the following NuGet packages:
Next, modify your Web.Config
file to add a required HttpModule:
<system.webServer>
<modules>
<add
name="TelemetryHttpModule"
type="OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule,
OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule"
preCondition="integratedMode,managedHandler" />
</modules>
</system.webServer>
Finally, initialize ASP.NET instrumentation in your Global.asax.cs
file along
with other OpenTelemetry initialization:
using OpenTelemetry;
using OpenTelemetry.Trace;
public class WebApiApplication : HttpApplication
{
private TracerProvider _tracerProvider;
protected void Application_Start()
{
_tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAspNetInstrumentation()
// Other configuration, like adding an exporter and setting resources
.AddConsoleExporter()
.AddSource("my-service-name")
.SetResourceBuilder(
ResourceBuilder.CreateDefault()
.AddService(serviceName: "my-service-name", serviceVersion: "1.0.0"))
.Build();
}
protected void Application_End()
{
_tracerProvider?.Dispose();
}
}
Advanced ASP.NET configuration
ASP.NET instrumentation can be configured to change the default behavior.
Filter
ASP.NET instrumentation collects all incoming HTTP requests by default. However,
you can filter incoming requests by using the Filter
method in
AspNetInstrumentationOptions
. This works similar to a LINQ Where
clause,
where only requests that match a condition will be collected.
The following code snippet shows how to use Filter
to only allow GET requests.
this.tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAspNetInstrumentation(
(options) => options.Filter =
(httpContext) =>
{
// only collect telemetry about HTTP GET requests
return httpContext.Request.HttpMethod.Equals("GET");
})
.Build();
Filtering happens at an early stage, and is different from Sampling, which occurs after data has been collected. Filtering will limit what gets collected in the first place.
Enrich
If you have data that you’d like to have added to every Activity
that’s
generated by OpenTelemetry, you can use the Enrich
method.
The Enrich
action is called only when activity.IsAllDataRequested
is true
.
It contains the Activity
created, the name of the event, and the raw object
The following code snippet shows how to add additional tags using Enrich
.
this.tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAspNetInstrumentation((options) => options.Enrich
= (activity, eventName, rawObject) =>
{
if (eventName.Equals("OnStartActivity"))
{
if (rawObject is HttpRequest httpRequest)
{
activity?.SetTag("physicalPath", httpRequest.PhysicalPath);
}
}
else if (eventName.Equals("OnStopActivity"))
{
if (rawObject is HttpResponse httpResponse)
{
activity?.SetTag("responseType", httpResponse.ContentType);
}
}
})
.Build();
See Add tags to an Activity for annotating trace data more generally.
RecordException
ASP.NET instrumentation automatically sets a given Activity
’s status to
Error
if an unhandled exception is thrown.
You can also set the RecordException
property to true
, which will store an
exception on the Activity
itself as an ActivityEvent
.
Next steps
After you have observability generated automatically with instrumentation libraries, you may want to add manual instrumentation to collect custom telemetry data.
You’ll also want to configure an appropriate exporter to export your telemetry data to one or more telemetry backends.
You can also check the automatic instrumentation for .NET, which is currently in beta.