aspnetcore/log-mon/metrics/metrics.md
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:
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 a comprehensive list of all instruments together with their attributes.
Using metrics involves the following:
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 and displaying metrics:
dotnet-countersMeasurements 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 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/web-metrics/Program.cs":::
dotnet-counters is a command-line tool that can view live metrics for .NET 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
For more information, see dotnet-counters.
ASP.NET Core has many built-in metrics. The http.server.request.duration metric:
The http.server.request.duration metric supports tag enrichment using xref:Microsoft.AspNetCore.Http.Features.IHttpMetricsTagsFeature. Enrichment is when a library or app adds its own tags to a metric. This is useful if an app wants to add a custom categorization to dashboards or alerts built with metrics.
:::code language="csharp" source="~/log-mon/metrics/metrics/samples/EnrichMetrics/Program.cs":::
The proceeding example:
HttpContext. The feature is only present on the context if someone is listening to the metric. Verify IHttpMetricsTagsFeature is not null before using it.http.server.request.duration metric.
mkt_medium and a value based on the utm_medium query string value. The utm_medium value is resolved to a known range of values.[!NOTE] Follow the multi-dimensional metrics best practices when enriching with custom tags. Tags that are too numerous or have an unbound range create many tag combinations, resulting in high dimensions. Collection tools have limits on supported dimensions for a counter and may filter results to prevent excessive memory use.
:::moniker range=">= aspnetcore-9.0"
Opting out of recording metrics is beneficial for endpoints frequently called by automated systems, such as health checks. Recording metrics for these requests is generally unnecessary. Unwanted telemetry uses resources to collect and store, and can distort results displayed in a telemetry dashboard.
HTTP requests to an endpoint can be excluded from metrics by adding metadata, with either the DisableHttpMetrics attribute or the DisableHttpMetrics method:
:::code language="csharp" source="~/log-mon/metrics/metrics/samples/DisableMetrics/Program.cs" id="snippet_1" highlight="5":::
Alternatively, the xref:Microsoft.AspNetCore.Http.Features.IHttpMetricsTagsFeature.MetricsDisabled?displayProperty=nameWithType property has been added for:
:::code language="csharp" source="~/log-mon/metrics/metrics/samples/DisableMetrics/Program.cs" id="snippet_2":::
:::moniker-end
Metrics are created using APIs in the xref:System.Diagnostics.Metrics namespace. See Create custom metrics for information on creating custom metrics.
IMeterFactoryWe recommended creating xref:System.Diagnostics.Metrics.Meter instances in ASP.NET Core apps with xref:System.Diagnostics.Metrics.IMeterFactory.
ASP.NET Core registers xref:System.Diagnostics.Metrics.IMeterFactory in dependency injection (DI) by default. The meter factory integrates metrics with DI, making isolating and collecting metrics easy. IMeterFactory is especially useful for testing. It allows for multiple tests to run side-by-side and only collecting metrics values that are recorded in a test.
To use IMeterFactory in an app, create a type that uses IMeterFactory to create the app's custom metrics:
:::code language="csharp" source="~/log-mon/metrics/metrics/samples/custom-metrics/ContosoMetrics.cs" id="snippet_ContosoMetrics":::
Register the metrics type with DI in Program.cs:
:::code language="csharp" source="~/log-mon/metrics/metrics/samples/custom-metrics/Program.cs" id="snippet_RegisterMetrics":::
Inject the metrics type and record values where needed. Because the metrics type is registered in DI it can be use with MVC controllers, Minimal APIs, or any other type that is created by DI:
:::code language="csharp" source="~/log-mon/metrics/metrics/samples/custom-metrics/Program.cs" id="snippet_InjectAndUseMetrics":::
To monitor the "Contoso.Web" meter, use the following dotnet-counters command.
dotnet-counters monitor -n WebMetric --counters Contoso.Web
Output similar to the following is displayed:
Press p to pause, r to resume, q to quit.
Status: Running
[Contoso.Web]
contoso.product.sold (Count / 1 sec)
contoso.product.name=Eggs 12
contoso.product.name=Milk 0
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:
The Grafana server:
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:
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/web-metrics/prometheus.yml" highlight="31-99":::
In the preceding highlighted YAML, replace 5045 with the port number that the example app is running on.
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:
Follow the installation instructions to install Grafana and connect it to a Prometheus data source.
Follow Creating a Prometheus graph. Alternatively, pre-built dashboards for .NET metrics are available to download at .NET team dashboards @ grafana.com. Downloaded dashboard JSON can be imported into Grafana.
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.Diagnostics.Metrics.Testing.MetricCollector%601.
:::code language="csharp" source="~/log-mon/metrics/metrics/samples/metric-tests/BasicTests.cs" id="snippet_TestClass":::
The proceeding test:
Program in the factory's generic argument specifies the web app.Microsoft.Extensions.Diagnostics.Testing.MetricCollector<T> is created using the web app's xref:System.Diagnostics.Metrics.IMeterFactory. This allows the collector to only report metrics values recorded by test.Microsoft.AspNetCore.Hosting, and counter name, http.server.request.duration to collect.:::moniker range=">= aspnetcore-10.0"
ASP.NET Core Identity observability help you monitor user management activities and authentication processes.
The metrics are in the Microsoft.AspNetCore.Identity meter and are described in the following sections.
aspnetcore.identity.user.create.duration measures the duration of user creation operations.aspnetcore.identity.user.update.duration measures the duration of user update operations.aspnetcore.identity.user.delete.duration measures the duration of user deletion operationsaspnetcore.identity.user.check_password_attempts counts password verification attempts.aspnetcore.identity.user.generated_tokens counts tokens generated for users, such as password reset tokens.aspnetcore.identity.user.verify_token_attempts counts token verification attempts.aspnetcore.identity.sign_in.authenticate.duration measures the duration of authentication operations.aspnetcore.identity.sign_in.check_password_attempts counts password check attempts during sign-in.aspnetcore.identity.sign_in.sign_ins counts successful sign-ins.aspnetcore.identity.sign_in.sign_outs counts sign-outs.aspnetcore.identity.sign_in.two_factor_clients_remembered counts remembered two-factor clients.aspnetcore.identity.sign_in.two_factor_clients_forgotten counts forgotten two-factor clients.These metrics can be used to:
You can view these metrics using dotnet-counters to monitor them in real-time or export them to Prometheus and visualize them in Grafana using the techniques described earlier in this article.
For example, to monitor all Identity metrics with dotnet-counters:
dotnet-counters monitor -n YourAppName --counters Microsoft.AspNetCore.Identity
:::moniker-end
See ASP.NET Core metrics for a list of ASP.NET Core meters and counters.