2

In an ASP.NET Core Web Application I want to measure how many request units have been spent in a single web request. With this information I could identify "expensive" calls and look for optimizing them.

I know how to option the request unit count from a single CosmosDB Rest call. But this is a layered application where the persistence level that interacts with the ComosDB does not have access to the Request-Object in ASP.NET Core.

Is there a way to optain somehow some kind of request id? I wonder how Application Insights keeps track what are dependent internal calls for a specific web request.

Or is there a way to get this information in Application Insights?

Ralf Bönning
  • 14,515
  • 5
  • 49
  • 67
  • If you track metrics with the AI TelemetryClient, the operation id will be attached to them. You can then group them in AI's Analytics to get per operation stats. – juunas Mar 14 '19 at 08:30
  • Which SDK are you using? The default v2, Cosmonaut or EF Core? – Nick Chapsas Mar 14 '19 at 10:22
  • @NickChapsas I use the default .net SDK. The connection mode is TCP therefore the default Application Insights dendency tracking does not work (HTTP support only) – Ralf Bönning Mar 14 '19 at 10:43

2 Answers2

4

This depends on multiple things including which SDK you are using.

If you are using the default Cosmos DB SDK also known as v2 SDK, then (assuming you enabled Application Insights support) Cosmos DB will only log it's dependency calls if you are using HTTP/HTTPS connection. TCP mode won't be captured by Application Insights. This means you would either have to use HTTPS which is bad in terms of performance or code something custom.

If you are using Cosmonaut then it comes out of the box with a general purpose EventSource which tracks each call as a dependency no matter the connection type and it also collects multiple metrics such as the RUs and a lot more. You would need to reference the Cosmonaut.ApplicationInsights nuget package and initialise the AppInsightsTelemetryModule like this:

AppInsightsTelemetryModule.Instance.Initialize(TelemetryConfiguration.Active);

or use the IoC alternative of:

services.AddSingleton(AppInsightsTelemetryModule.Instance);

This will give you logging for every action with detailed metrics such as the following (including the request charge):

enter image description here

You can then use a query like this to see spikes and further investigate, or just query for requests with Cosmos dependencies which exceed a threshold.

dependencies
| where type contains "Cosmos" and customDimensions.RequestCharge != ""
| summarize sum(toint(customDimensions.RequestCharge)) by bin(timestamp, 1m) 

PS: You don't have to use the CosmosStore if you don't need it. Using the CosmonautClient instead of the DocumentClient will do the logging job as well.

Nick Chapsas
  • 6,872
  • 1
  • 20
  • 29
0

This is available in the CosmosDB REST API response's header. You will need to create a correlation between your web call and the CosmosDB operations and then aggregate.

From the docs:

x-ms-request-charge This is the number of normalized requests a.k.a. request units (RU) for the operation. For more information, see Request units in Azure Cosmos DB.

Murray Foxcroft
  • 12,785
  • 7
  • 58
  • 86
  • 1
    Thanks, but this does not solve my problem yet. I have one web request and probably multiple CosmosDB requests. I just do not know how to correlate / group them. The code where Cosmos requests are made does not have access to the issuing Request-object. – Ralf Bönning Mar 14 '19 at 08:45
  • You will need to pass a correlation id and aggregate yourself, the API header provides the lowest level of grain. – Murray Foxcroft Mar 14 '19 at 08:47