{"id":50309,"date":"2024-02-14T13:35:00","date_gmt":"2024-02-14T21:35:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/dotnet\/?p=50309"},"modified":"2024-12-13T13:59:54","modified_gmt":"2024-12-13T21:59:54","slug":"introducing-aspnetcore-metrics-and-grafana-dashboards-in-dotnet-8","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/introducing-aspnetcore-metrics-and-grafana-dashboards-in-dotnet-8\/","title":{"rendered":"Introducing ASP.NET Core metrics and Grafana dashboards in .NET 8"},"content":{"rendered":"<p>Metrics report diagnostics about your app. .NET 8 adds over a dozen useful metrics to ASP.NET Core:<\/p>\n<ul>\n<li>HTTP request counts and duration<\/li>\n<li>Number of active HTTP requests<\/li>\n<li>Route matching results<\/li>\n<li>Rate limiting lease and queue durations<\/li>\n<li>SignalR transport usage<\/li>\n<li>Low-level connection and TLS usage from Kestrel<\/li>\n<li>Error handling diagnostics<\/li>\n<li>And more<\/li>\n<\/ul>\n<p>Metrics are numerical measurements reported over time. For example, each HTTP request handled by ASP.NET Core has its duration recorded to the <code>http.server.request.duration<\/code> metric. Tooling such as the <a href=\"https:\/\/github.com\/open-telemetry\/opentelemetry-dotnet#opentelemetry-net\">.NET OpenTelemetry SDK<\/a> can then be configured by an app to export metric data to a telemetry store such as <a href=\"https:\/\/prometheus.io\/\">Prometheus<\/a> or <a href=\"https:\/\/learn.microsoft.com\/azure\/azure-monitor\/overview\">Azure Monitor<\/a>. Metrics are part of the OpenTelemetry standard and all modern tools support them.<\/p>\n<p>Metrics data are useful when combined with tooling to monitor the health and activity of apps:<\/p>\n<ul>\n<li>Display graphs on a dashboard to observe your app over time. For example, view activity from people using the app.<\/li>\n<li>Trigger alerts in real-time if the app exceeds a threshold. For example, send an email if request duration or error count exceeds a limit.<\/li>\n<\/ul>\n<h2>Using metrics<\/h2>\n<p><a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/diagnostics\/built-in-metrics-aspnetcore\">ASP.NET Core&#8217;s built-in metrics<\/a> are automatically recorded. How you use these metrics is up to you. Let&#8217;s explore some of the options available.<\/p>\n<h3>.NET Aspire dashboard<\/h3>\n<p><a href=\"https:\/\/learn.microsoft.com\/dotnet\/aspire\/get-started\/aspire-overview\">.NET Aspire<\/a> is an opinionated stack for building observable, distributed applications. The Aspire dashboard includes a simple, user-friendly UI for viewing structured logs, traces and metrics. Aspire apps are automatically configured to send telemetry data to the dashboard during development.<\/p>\n<p><img decoding=\"async\" src=\".\/aspire-metrics.gif\" alt=\"A recording of the .NET Aspire dashboard metrics\" \/><\/p>\n<p>Here you can see a collection of available metrics, along with name, description, and a graph of values. The Aspire UI includes metrics filters. Filtering is possible using a powerful feature of metrics: attributes.<\/p>\n<p>Each time a value is recorded, it is tagged with metadata called attributes. For example, <code>http.server.request.duration<\/code> records a HTTP request duration along with attributes about that request: server address, HTTP request method, matched route, response status code and more. Attributes can then be queried to get the exact data you want:<\/p>\n<ul>\n<li>HTTP request duration to a specific endpoint in your app, e.g. <code>\/product\/{name}<\/code>.<\/li>\n<li>Count the number of requests with <code>4xx<\/code> HTTP response codes.<\/li>\n<li>View request count that threw a server exception over time.<\/li>\n<li>HTTP vs HTTPS request duration.<\/li>\n<li>Number of visitors using HTTP\/1.1 vs HTTP\/2.<\/li>\n<\/ul>\n<h3>ASP.NET Core Grafana dashboards<\/h3>\n<p><a href=\"https:\/\/grafana.com\/grafana\/\">Grafana<\/a> is powerful open-source tool for building advanced dashboards and alerts. It allows you to create interactive, customizable dashboards with a variety of panels, graphs, and charts. Once complete, a dashboard displays data from your telemetry store. Grafana is a good choice to monitor apps deployed to production and a dashboard gives a real-time view of an app health and usage.<\/p>\n<p>Grafana gives you the power to build exactly what you want, but it takes time to build high-quality dashboards. As part of adding metrics in .NET 8, the .NET team created pre-built dashboards designed for ASP.NET Core&#8217;s built-in metrics.<\/p>\n<p><img decoding=\"async\" src=\".\/dashboard-screenshot.png\" alt=\"A screenshot of the ASP.NET Core Grafana dashboard\" \/><\/p>\n<p>The ASP.NET Core Grafana dashboards are <a href=\"https:\/\/aka.ms\/dotnet\/grafana-source\">open source on GitHub<\/a> and available for <a href=\"https:\/\/aka.ms\/dotnet\/grafana-dashboards\">download on grafana.com<\/a>. You can use the dashboard as they are or customize them further to build a solution tailored to your needs.<\/p>\n<p>Quickly try out Grafana + ASP.NET Core using the <a href=\"https:\/\/learn.microsoft.com\/samples\/dotnet\/aspire-samples\/aspire-metrics\/\">.NET Aspire metrics sample app<\/a>.<\/p>\n<h3>And more<\/h3>\n<ul>\n<li>Metrics aren&#8217;t limited to what is built into .NET. You can <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/diagnostics\/metrics-instrumentation#create-a-custom-metric\">create custom metrics<\/a> for your apps.<\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/diagnostics\/dotnet-counters\">dotnet-counters<\/a> is a command-line tool that can view live metrics for .NET Core apps on demand. It doesn&#8217;t require setup, making it useful for ad-hoc investigations or verifying that metric instrumentation is working.<\/li>\n<li>Use metrics in <a href=\"https:\/\/learn.microsoft.com\/aspnet\/core\/log-mon\/metrics\/metrics#test-metrics-in-aspnet-core-apps\">unit tests<\/a>. ASP.NET Core integration testing, <code>MetricCollector<\/code> and <code>IMeterFactory<\/code> can be combined to assert values recorded by a test.<\/li>\n<\/ul>\n<h2>Try it now<\/h2>\n<p>.NET 8, ASP.NET Core Grafana dashboards and .NET Aspire (preview) are available now. Try using metrics today and let us know what you think:<\/p>\n<ul>\n<li><a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/8.0\">Download the latest .NET 8 release<\/a>.<\/li>\n<li>\n<p>Use metrics in your tool of choice:<\/p>\n<ul>\n<li>Learn more about the <a href=\"https:\/\/learn.microsoft.com\/dotnet\/aspire\/fundamentals\/dashboard\">.NET Aspire dashboard<\/a> and <a href=\"https:\/\/learn.microsoft.com\/dotnet\/aspire\/get-started\/build-your-first-aspire-app\">get started<\/a>.<\/li>\n<li>Download <a href=\"https:\/\/aka.ms\/dotnet\/grafana-dashboards\">ASP.NET Core Grafana dashboards<\/a>.<\/li>\n<li>Install <a href=\"https:\/\/learn.microsoft.com\/dotnet\/core\/diagnostics\/dotnet-counters\"><code>dotnet-counters<\/code><\/a> command-line tool.<\/li>\n<\/ul>\n<p>Want to try things hands on? Checkout our new <a href=\"https:\/\/learn.microsoft.com\/training\/paths\/create-microservices-with-dotnet\/\">cloud-native training modules<\/a> on Microsoft Learn.<\/p>\n<\/li>\n<\/ul>\n<p>Thanks for trying out .NET 8 and metrics!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>.NET 8 introduces metrics to ASP.NET Core. Check out what is new and discover how easy it is to use metrics and ASP.NET Core to monitor the health and activity of apps.<\/p>\n","protected":false},"author":11402,"featured_media":50413,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[685,7509],"tags":[7701],"class_list":["post-50309","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-aspnetcore","tag-dotnet-8"],"acf":[],"blog_post_summary":"<p>.NET 8 introduces metrics to ASP.NET Core. Check out what is new and discover how easy it is to use metrics and ASP.NET Core to monitor the health and activity of apps.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/50309","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/11402"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=50309"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/50309\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/50413"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=50309"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=50309"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=50309"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}