11 KiB
title | description | author | ms.author | monikerRange | ms.date | ms.topic | ms.prod | uid |
---|---|---|---|---|---|---|---|---|
ASP.NET Core metrics | Metrics for ASP.NET Core apps | rick-anderson | riande | >= aspnetcore-8.0 | 6/30/2023 | article | aspnet-core | log-mon/metrics/metrics |
ASP.NET Core metrics
Metrics are numerical measurements reported over time. They're typically used to monitor the health of an app and generate alerts. For example, a web service might track how many:
- Requests it received per second.
- Milliseconds it took to respond.
- Responses sent an error.
These metrics can be reported to a monitoring system at regular intervals. Dashboards can be setup to view metrics and alerts created to notify people of problems. If the web service is intended to respond to requests within 400 ms and starts responding in 600 ms, the monitoring system can notify the operations staff that the app response is slower than normal.
See ASP.NET Core metrics for ASP.NET Core specific metrics. See .NET metrics for .NET metrics.
Using metrics
There are two parts to using metrics in a .NET app:
- Instrumentation: Code in .NET libraries takes measurements and associates these measurements with a metric name. .NET and ASP.NET Core include many built-in metrics.
- Collection: A .NET app configures named metrics to be transmitted from the app for external storage and analysis. Some tools may perform configuration outside the app using configuration files or a UI tool.
Instrumented code can record numeric measurements, but the measurements need to be aggregated, transmitted, and stored to create useful metrics for monitoring. The process of aggregating, transmitting, and storing data is called collection. This tutorial shows several examples of collecting metrics:
- Populating metrics in Grafana with OpenTelemetry and Prometheus.
- Viewing metrics in real time with
dotnet-counters
Measurements can also be associated with key-value pairs called tags that allow data to be categorized for analysis. For more information, see Multi-dimensional metrics.
Create the starter app
Create a new ASP.NET Core app with the following command:
dotnet new web -o WebMetric
cd WebMetric
dotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore --prerelease
dotnet add package OpenTelemetry.Extensions.Hosting
Replace the contents of Program.cs
with the following code:
:::code language="csharp" source="~/log-mon/metrics/metrics/samples/Program.cs":::
View metrics with dotnet-counters
dotnet-counters is a command-line tool that can view live metrics for .NET Core apps on demand. It doesn't require setup, making it useful for ad-hoc investigations or verifying that metric instrumentation is working. It works with both xref:System.Diagnostics.Metrics?displayProperty=nameWithType based APIs and EventCounters.
If the dotnet-counters tool isn't installed, run the following command:
dotnet tool update -g dotnet-counters
While the test app is running, launch dotnet-counters. The following command shows an example of dotnet-counters
monitoring all metrics from the Microsoft.AspNetCore.Hosting
meter.
dotnet-counters monitor -n WebMetric --counters Microsoft.AspNetCore.Hosting
Output similar to the following is displayed:
Press p to pause, r to resume, q to quit.
Status: Running
[Microsoft.AspNetCore.Hosting]
http-server-current-requests
host=localhost,method=GET,port=5045,scheme=http 0
http-server-request-duration (s)
host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro 0.001
host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro 0.001
host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro 0.001
host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro 0
host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro 0
host=localhost,method=GET,port=5045,protocol=HTTP/1.1,ro 0 12
For more information, see dotnet-counters.
Create custom metrics
See Create custom metrics for information on creating custom metrics.
View metrics in Grafana with OpenTelemetry and Prometheus
Overview
- Is a vendor-neutral open-source project supported by the Cloud Native Computing Foundation.
- Standardizes generating and collecting telemetry for cloud-native software.
- Works with .NET using the .NET metric APIs.
- Is endorsed by Azure Monitor and many APM vendors.
This tutorial shows one of the integrations available for OpenTelemetry metrics using the OSS Prometheus and Grafana projects. The metrics data flow:
-
The ASP.NET Core metric APIs record measurements from the example app.
-
The OpenTelemetry .NET library running in the app aggregates the measurements.
-
The Prometheus exporter library makes the aggregated data available via an HTTP metrics endpoint. 'Exporter' is what OpenTelemetry calls the libraries that transmit telemetry to vendor-specific backends.
-
A Prometheus server:
- Polls the metrics endpoint
- Reads the data
- Stores the data in a database for long-term persistence. Prometheus refers to reading and storing data as scraping an endpoint.
- Can run on a different machine
-
The Grafana server:
- Queries the data stored in Prometheus and displays it on a web-based monitoring dashboard.
- Can run on a different machine.
View metrics from sample app
Navigate to the sample app. The browser displays Hello OpenTelemetry! ticks:<3digits>
where 3digits
are the last 3 digits of the current DateTime.Ticks.
Append /metrics
to the URL to view the metrics endpoint. The browser displays the metrics being collected:
Set up and configure Prometheus
Follow the Prometheus first steps to set up a Prometheus server and confirm it's working.
Modify the prometheus.yml configuration file so that Prometheus scrapes the metrics endpoint that the example app is exposing. Add the following highlighted text in the scrape_configs
section:
:::code language="yaml" source="~/log-mon/metrics/metrics/samples/prometheus.yml" highlight="31-99":::
In the preceding highlighted YAML, replace 5045
with the port number that the example app is running on.
Start Prometheus
- Reload the configuration or restart the Prometheus server.
- Confirm that OpenTelemetryTest is in the UP state in the Status > Targets page of the Prometheus web portal.
Select the Open metric explorer icon to see available metrics:
Enter counter category such as http_
in the Expression input box to see the available metrics:
Alternatively, enter counter category such as kestrel
in the Expression input box to see the available metrics:
Show metrics on a Grafana dashboard
-
Follow the installation instructions to install Grafana and connect it to a Prometheus data source.
-
Follow Creating a Prometheus graph. Alternatively, download a JSON file from aspnetcore-grafana dashboards to configure Grafana.
Test metrics in ASP.NET Core apps
It's possible to test metrics in ASP.NET Core apps. One way to do that is collect and assert metrics values in ASP.NET Core integration tests using xref:Microsoft.Extensions.Telemetry.Testing.Metering.MetricCollector%601.
public class BasicTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
public BasicTests(WebApplicationFactory<Program> factory) => _factory = factory;
[Fact]
public async Task Get_RequestCounterIncreased()
{
// Arrange
var client = _factory.CreateClient();
var meterFactory = _factory.Services.GetRequiredService<IMeterFactory>();
var collector = new MetricCollector<double>(meterFactory,
"Microsoft.AspNetCore.Hosting", "http.server.request.duration");
// Act
var response = await client.GetAsync("/");
// Assert
Assert.Equal("Hello World!", await response.Content.ReadAsStringAsync());
await collector.WaitForMeasurementsAsync(minCount: 1).WaitAsync(TimeSpan.FromSeconds(5));
Assert.Collection(collector.GetMeasurementSnapshot(),
measurement =>
{
Assert.Equal("http", measurement.Tags["url.scheme"]);
Assert.Equal("GET", measurement.Tags["http.request.method"]);
Assert.Equal("/", measurement.Tags["http.route"]);
});
}
}
The proceeding test:
- Bootstraps a web app in memory with xref:Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory%601.
Program
in the factory's generic argument specifies the web app. - Collects metrics values with xref:Microsoft.Extensions.Telemetry.Testing.Metering.MetricCollector%601.
- Requires a package reference to
Microsoft.Extensions.Telemetry.Testing
. - The
MetricCollector
is created using the web app'sIMeterFactory
. This allows the collector to only report metrics values recorded by test. - Includes the meter name,
Microsoft.AspNetCore.Hosting
, and counter name,http.server.request.duration
to collect.
- Requires a package reference to
- Makes an HTTP request to the web app.
- Asserts the test using results from the metrics collector.