ApplicationInsights.OwinExtensions 0.5.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package ApplicationInsights.OwinExtensions --version 0.5.1
NuGet\Install-Package ApplicationInsights.OwinExtensions -Version 0.5.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ApplicationInsights.OwinExtensions" Version="0.5.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ApplicationInsights.OwinExtensions --version 0.5.1
#r "nuget: ApplicationInsights.OwinExtensions, 0.5.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ApplicationInsights.OwinExtensions as a Cake Addin
#addin nuget:?package=ApplicationInsights.OwinExtensions&version=0.5.1

// Install ApplicationInsights.OwinExtensions as a Cake Tool
#tool nuget:?package=ApplicationInsights.OwinExtensions&version=0.5.1

Application Insights OWIN extensions

This library is a set of extensions, that allow you to easily get some features normally not available for OWIN based applications out-of-the-box (but are available when using the classic ASP.NET pipeline).

Features

  • Sets the common Context.Operation.Id property for all telemetries within one request (even asynchronously called dependencies)
  • Pass Context.Operation.Id property between multiple dependencies request chains
  • Creates Request telemetry with proper name, id and execution time
  • Useable with both self-hosted and System.Web hosted OWIN applications

Installation

Required steps

Install Application Insights within the project like you would normally do. You may also want to update related nuget packages to latest versions.

Install the extensions package:

Install-Package ApplicationInsights.OwinExtensions

In your Startup class, add as a first step of the pipeline:

public class Startup
{
	public void Configuration(IAppBuilder app)
	{
		app.UseApplicationInsights();
		
		// rest of the config here...
	}
}

Cleanup the ApplicationInsights.config by removing telemetry initializers and modules with overlapping functionality.

  • Microsoft.ApplicationInsights.Web.OperationCorrelationTelemetryInitializer
  • Microsoft.ApplicationInsights.Web.OperationIdTelemetryInitializer
  • Microsoft.ApplicationInsights.Web.OperationNameTelemetryInitializer

and also the Microsoft.ApplicationInsights.Web.RequestTrackingTelemetryModule

One last thing to do is to configure the Operation Id telemetry initializer. With XML in ApplicationInsights.config:

<TelemetryInitializers>
	
	<Add Type="ApplicationInsights.OwinExtensions.OperationIdTelemetryInitializer, ApplicationInsights.OwinExtensions"/>
</TelemetryInitializers>

or in code:

TelemetryConfiguration.Active
	.TelemetryInitializers.Add(new OperationIdTelemetryInitializer());

Possibly required steps

Note: If you are using Microsoft.Owin.Security.* middlewares, you need to restore the Operation Id context one step after the authentication middleware - otherwise the Operation Id context will be lost. This problem is most probably related to the security middleware taking advantage of the old System.Web pipeline integration and setting the stage markers. The problem will probably surface also with other middlewares using the stage markers.

// ...
app.UseOAuthBearerTokens(OAuthOptions);
// ...

// now restore the Operation Id context from the OWIN environment dictionary
app.RestoreOperationIdContext();

Advanced usage

Selectively tracing requests

You can pass a parameter to the UseApplicationInsights method specifying request filtering callback.

appBuilder.UseApplicationInsights(new RequestTrackingConfiguration
{
    ShouldTrackRequest = ctx => Task.FromResult(ctx.Request.Method != "OPTIONS")
});

Adding custom properties to telemetry

You can also extend the traced telemetry with custom properties. Note: if your custom properties are not related to the request or the response, you can alternatively specify additional TelemetryInitializer in your Application Insights telemetry configuration.

appBuilder.UseApplicationInsights(new RequestTrackingConfiguration
{
    GetAdditionalContextProperties = ctx =>
        Task.FromResult(new[] { new KeyValuePair<string, string>("Content-Type", ctx.Request.ContentType)}
            .AsEnumerable())
});

Passing OperationId via header

Let's presume that your system is build of many services communicating by http requests with each other . You probably would like to be able to track how the specific operation propagate through your system's components. To achieve this you should append the operation id to each request with a header. Provided middleware can acquire that id, use it with its own telemetry and then it can be passed to next component. And so on...

This behaviour is turned off by default. Following snippets present how to turn it on.

public class Startup
{
	public void Configuration(IAppBuilder app)
	{
		app.UseApplicationInsights(			
		  new OperationIdContexMiddlewareConfiguration {ShouldTryGetIdFromHeader = true});
		  
		// rest of the config here...
	}
}

Default header name for Context.Operation.Id value is X-Operation-Id, but it can also be customized.

public class Startup
{
	public void Configuration(IAppBuilder app)
	{
		app.UseApplicationInsights(			
		  new OperationIdContextMiddlewareConfiguration {
		  		ShouldTryGetIdFromHeader = true,
				  OperationIdHeaderName = "Custom-Header-Name"});
				  
		// rest of the config here...
	}
}

Example how to perform http request with appended Context.Operation.Id value:

using (var client = new HttpClient())
{
	var request = new HttpRequestMessage
	{
		Method = HttpMethod.Get,
		RequestUri = new Uri($"http://{serviceHost}:{servicePort}")
	};

	request.Headers.Add("X-Operation-Id", OperationIdContext.Get());
	await client.SendAsync(request);
}

The OperationIdContext is a static class storing current request Context.Operation.Id value.

Optional steps

You can use ComponentNameTelemetryInitializer to add ComponentName property to your telemetry. It will simplify filtering telemetries connected with specific component of your system.

TelemetryConfiguration.Active
	.TelemetryInitializers.Add(new ComponentNameTelemetryInitializer("MyComponentName"));

How this stuff works

First middleware in the pipeline establishes a new Operation Id context (Guid.NewGuid() by default). This value is stored both in OWIN environment dictionary under the ApplicationInsights.OwinExtensions.OperationIdContext key, and in the CallContext. There is the OperationIdContext class that can be used to access the current value of Operation Id from anywhere within the call context. The telemetry initializer makes use of that and sets appropriate property on the telemetries.

Contributing

If you would like to contribute, please create a PR against the develop branch.

Release notes

0.5.1

  • [FIX] - #24 temporary fix for operation parent id not set on telemetry

0.5.0

  • [BREAKING] (possibly) - UseApplicationInsights now accepts an instance of RequestTrackingConfiguration instead of separate configuration parameters. Old overload has been deprecated
  • [FEATURE] - IOwinContext is passed to request filter and additional properties extractor delegates
  • [FEATURE] - request filter and additional properties extractor delegates are now async

0.4.1

  • [FIX] Fixed #17 - incorrect logging when exception thrown from downstream OWIN pipeline

0.4.0

  • [FEATURE] It is now possible to add custom properties to the logged request telemetry by providing a delegate in UseApplicationInsights

0.3.0

  • [FEATURE] It is now possible to filter logged request telemetries by providing a delegate in UseApplicationInsights
Product Compatible and additional computed target framework versions.
.NET Framework net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on ApplicationInsights.OwinExtensions:

Repository Stars
riganti/dotvvm
Open source MVVM framework for Web Apps
Version Downloads Last updated
0.9.0 381,420 10/17/2020
0.8.1 86,123 7/7/2020
0.8.0 11,247 6/30/2020
0.7.0 132,652 9/4/2019
0.6.0 536,450 11/21/2017
0.5.1 44,898 10/15/2017
0.5.0 139,479 8/7/2017
0.4.1 262,785 4/4/2017
0.4.0 30,390 1/25/2017
0.3.0 75,607 8/11/2016
0.2.0 21,206 5/3/2016
0.1.1 2,063 3/21/2016
0.1.0 1,654 12/13/2015
0.1.0-unstable0010 1,025 12/10/2015
0.1.0-unstable0009 1,015 12/6/2015
0.1.0-unstable0008 985 12/6/2015