From e8a84998eceff73e0a931acb07770724476484aa Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Mon, 31 Aug 2026 15:25:10 -0400 Subject: [PATCH 1/2] Patterns for applying authz across Blazor apps (#37501) * Patterns for applying authz across Blazor apps * Updates * Updates * Updates * Updates * Updates * Updates * Updates * Update aspnetcore/blazor/security/webassembly/index.md Co-authored-by: Wade Pickett --------- Co-authored-by: Wade Pickett --- .../blazor/fundamentals/static-files.md | 7 +- .../blazor/security/additional-scenarios.md | 212 +++++++++++++++++- aspnetcore/blazor/security/index.md | 6 +- .../blazor/security/webassembly/index.md | 12 +- .../security/authorization/introduction.md | 14 +- 5 files changed, 232 insertions(+), 19 deletions(-) diff --git a/aspnetcore/blazor/fundamentals/static-files.md b/aspnetcore/blazor/fundamentals/static-files.md index 4f4e92e694b1..51f85a82eab2 100644 --- a/aspnetcore/blazor/fundamentals/static-files.md +++ b/aspnetcore/blazor/fundamentals/static-files.md @@ -1,10 +1,11 @@ --- title: ASP.NET Core Blazor static files +ai-usage: ai-assisted author: guardrex description: Learn how to configure and manage static files for Blazor apps. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett -ms.date: 11/11/2025 +ms.date: 08/24/2026 uid: blazor/fundamentals/static-files --- # ASP.NET Core Blazor static files @@ -505,7 +506,7 @@ To create additional file mappings with a to execute a custom static file middleware: +* You can avoid interfering with serving `_framework/blazor.server.js` by using to execute a custom static files middleware: ```csharp app.MapWhen(ctx => !ctx.Request.Path @@ -538,7 +539,7 @@ Add the following `using` statement to the top of the server project's `Program` using Microsoft.Extensions.FileProviders; ``` -In the server project's `Program` file ***before*** the call to , add the following code: +In the server project's `Program` file ***before*** any calls to and , add the following code: ```csharp var secondaryProvider = new PhysicalFileProvider( diff --git a/aspnetcore/blazor/security/additional-scenarios.md b/aspnetcore/blazor/security/additional-scenarios.md index 33faced721c4..131fba40ff1a 100644 --- a/aspnetcore/blazor/security/additional-scenarios.md +++ b/aspnetcore/blazor/security/additional-scenarios.md @@ -1,13 +1,14 @@ --- -title: ASP.NET Core server-side and Blazor Web App additional security scenarios +title: ASP.NET Core Blazor additional server-side security scenarios +ai-usage: ai-assisted author: guardrex description: Learn how to configure server-side Blazor and Blazor Web Apps for additional security scenarios. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett -ms.date: 11/11/2025 +ms.date: 08/26/2026 uid: blazor/security/additional-scenarios --- -# ASP.NET Core server-side and Blazor Web App additional security scenarios +# ASP.NET Core Blazor additional server-side security scenarios [!INCLUDE[](~/includes/not-latest-version.md)] @@ -1369,3 +1370,208 @@ The preceding example's placeholders: In [Duende IdentityServer](https://duendesoftware.com/products/identityserver), tokens are revoked automatically by setting the `CoordinateLifetimeWithUserSession` client configuration property to `true`, which automatically cleans up associated tokens when a session ends. For more information, see [Session Cleanup and Logout (Duende documentation)](https://docs.duendesoftware.com/identityserver/ui/logout/session-cleanup/). Built-in opaque access token support is under consideration for a future release of .NET. For more information, see [Opaque - reference token validation (`dotnet/aspnetcore` #46026)](https://github.com/dotnet/aspnetcore/issues/46026). + +## Server-side Blazor app authorization patterns + +*For patterns that apply to Blazor WebAssembly apps, see .* + +Server-side Blazor apps (Blazor Web Apps, Blazor Server apps) usually adopt **either** of the following approaches to require authorization: + +* The app sets an authorization fallback policy that requires authorization globally across the app and applies the [`[AllowAnonymous]` attribute](xref:Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute) to resources (for example, Razor components, static assets) that don't require an authenticated user. For more information, see the [Global authorization via a fallback authorization policy](#global-authorization-via-a-fallback-authorization-policy) section. +* Instead of requiring global authorization for resources, the app applies the [`[Authorize]` attribute](xref:blazor/security/index#authorize-attribute) to resources that require an authorized user. For more information, see the [Local authorization via `[Authorize]` attributes](#local-authorization-via-authorize-attributes) section. + +### Global authorization via a fallback authorization policy + +The following demonstration code can be used with the [`BlazorWebAppAuthorization` sample app (`dotnet/AspNetCore.Docs.Samples` GitHub repository)](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/security/authorization/BlazorWebAppAuthorization) ([how to download](xref:index#how-to-download-a-sample)). + +Set the to a policy with , which only applies when there are no authorization attributes or explicit policies set for a given resource: + +:::moniker range=">= aspnetcore-6.0" + +```csharp +builder.Services.AddAuthorization(options => +{ + options.FallbackPolicy = options.DefaultPolicy; +}); +``` + +:::moniker-end + +:::moniker range="< aspnetcore-6.0" + +```csharp +services.AddAuthorization(options => +{ + options.FallbackPolicy = options.DefaultPolicy; +}); +``` + +:::moniker-end + +The framework's requires an authenticated user. Unless the app uses a [custom policy provider](xref:security/authorization/custom-authorization-policy-providers) with a custom default policy, assigning the framework's default policy (`options.DefaultPolicy`), as shown in the preceding example, is equivalent to using the following code: + +:::moniker range=">= aspnetcore-6.0" + +```csharp +builder.Services.AddAuthorization(options => +{ + options.FallbackPolicy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .Build(); +}); +``` + +:::moniker-end + +:::moniker range="< aspnetcore-6.0" + +```csharp +services.AddAuthorization(options => +{ + options.FallbackPolicy = new AuthorizationPolicyBuilder() + .RequireAuthenticatedUser() + .Build(); +}); +``` + +:::moniker-end + +The app requires an authenticated user for any resource where no specific policy is set. + +:::moniker range=">= aspnetcore-9.0" + +If the app's security specification doesn't call for protecting static assets, call on : + +```csharp +app.MapStaticAssets().AllowAnonymous(); +``` + +To alternatively allow anonymous access for specific paths, apply the to the route pattern inside the endpoint convention lambda of . + +> [!IMPORTANT] +> When only authorizing specific endpoints for anonymous access, the [Blazor script](xref:blazor/project-structure#location-of-the-blazor-script) and other Blazor static assets, such as stylesheets, scripts, and modules, must be taken into consideration. If public Razor component pages require the assets to render and function correctly, the assets must be made available anonymously as well because they're requested separately via Map Static Assets routing endpoint conventions or static files middleware. + +Place static assets for anonymous access into a single folder. In the following example, endpoint routes with the `/public/` path segment are served anonymously: + +```csharp +app.MapStaticAssets() + .Add(endpointBuilder => + { + if (endpointBuilder is RouteEndpointBuilder routeBuilder && + routeBuilder.RoutePattern.RawText?.Contains( + "/public/", StringComparison.OrdinalIgnoreCase) == true) + { + routeBuilder.Metadata.Add(new AllowAnonymousAttribute()); + } + }); +``` + +The next example demonstrates anonymously serving the uncompressed Blazor script (`_framework/blazor.web.{FINGERPRINT}.js`, where the `{FINGERPRINT}` placeholder is the file's fingerprint): + +```csharp +// using System.Text.RegularExpressions; + +var regex = new Regex( + @"^_framework/blazor\.web\.[a-z0-9]{10}\.js$", RegexOptions.Compiled); + +app.MapStaticAssets() + .Add(endpointBuilder => + { + if (endpointBuilder is RouteEndpointBuilder routeBuilder && + regex.IsMatch(routeBuilder.RoutePattern.RawText ?? string.Empty)) + { + routeBuilder.Metadata.Add(new AllowAnonymousAttribute()); + } + }); +``` + +:::moniker-end + +:::moniker range="< aspnetcore-9.0" + +If the app's security specification doesn't call for protecting static assets, place the call to ***before*** and : + +```csharp +app.UseStaticFiles(); + +app.UseAuthentication(); +app.UseAuthorization(); +``` + +To alternatively allow anonymous access for specific paths, register a separate static files middleware before and are called. A second call to after authorization pipeline processing only serves other static assets if the user is authorized. + +> [!IMPORTANT] +> When only authorizing specific endpoints for anonymous access, the [Blazor script](xref:blazor/project-structure#location-of-the-blazor-script) and other Blazor static assets, such as stylesheets, scripts, and modules, must be taken into consideration. If public Razor component pages require the assets to render and function correctly, the assets must be made available anonymously as well because they're requested separately via static files middleware. + +In the following example, static assets in the app's `wwwroot/public` folder are served anonymously: + +```csharp +app.UseStaticFiles(new StaticFileOptions { + FileProvider = new Microsoft.Extensions.FileProviders.PhysicalFileProvider( + System.IO.Path.Combine(builder.Environment.WebRootPath, "public")), + RequestPath = "/public" +}); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.UseStaticFiles(); +``` + +:::moniker-end + +Use an [`@using`](xref:mvc/views/razor#using) directive for the namespace with an [`@attribute`](xref:mvc/views/razor#attribute) directive for the [`[AllowAnonymous]` attribute](xref:Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute) to permit anonymous access to individual components. In the following example, the `Home` component sets the attribute. + +At the top of `Components/Pages/Home.razor`: + +```razor +@page "/" +@using Microsoft.AspNetCore.Authorization +@attribute [AllowAnonymous] +``` + +Often, it's convenient to apply authorization to an entire folder of components. In the following example, a user account pages' imports file sets the [`[AllowAnonymous]` attribute](xref:Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute), so users can anonymously reach the app's sign-in, sign-out, access denied, and invalid user pages in the `Components/Account/Pages` folder. + +In `Components/Account/Pages/_Imports.razor`: + +```razor +@using Microsoft.AspNetCore.Authorization +@attribute [AllowAnonymous] +``` + +:::moniker range=">= aspnetcore-5.0" + +If the app uses one or more endpoint convention builder instances to provide additional endpoints, such as for Identity components, the endpoint builder's method call chains a call to . The following example maps additional Identity endpoints by calling `MapAdditionalIdentityEndpoints`, which returns an : + +```csharp +app.MapAdditionalIdentityEndpoints().AllowAnonymous(); +``` + +> [!NOTE] +> For an example of the preceding `MapAdditionalIdentityEndpoints` method, see [`IdentityComponentsEndpointRouteBuilderExtensions`](https://github.com/dotnet/AspNetCore.Docs.Samples/blob/main/security/authorization/BlazorWebAppAuthorization/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs) in the [`BlazorWebAppAuthorization` sample app (`dotnet/AspNetCore.Docs.Samples` GitHub repository)](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/security/authorization/BlazorWebAppAuthorization). + +:::moniker-end + +### Local authorization via `[Authorize]` attributes + +Apply [`[Authorize]` attributes](xref:blazor/security/index#authorize-attribute) ([API documentation](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute)) to Razor components using ***either*** of the following approaches: + +* In the app's imports file, add an [`@using`](xref:mvc/views/razor#using) directive for the namespace with an [`@attribute`](xref:mvc/views/razor#attribute) directive for the [`[Authorize]` attribute](xref:blazor/security/index#authorize-attribute). + + `_Imports.razor`: + + ```razor + @using Microsoft.AspNetCore.Authorization + @attribute [Authorize] + ``` + + Imports files can be applied at any level of a folder hierarchy to apply an [`[Authorize]` attribute](xref:blazor/security/index#authorize-attribute) for that folder's components and its subfolders. + +* Add the [`[Authorize]` attribute](xref:blazor/security/index#authorize-attribute) to each Razor component that requires authorization under the [`@page`](xref:mvc/views/razor#page) directive with an [`@using`](xref:mvc/views/razor#using) directive for the namespace: + + ```razor + @using Microsoft.AspNetCore.Authorization + @attribute [Authorize] + ``` + + The [`@using`](xref:mvc/views/razor#using) directive for the namespace in the preceding example can be applied broadly to the app's components by placing it into the app's imports file (`_Imports.razor`) instead of in individual components. diff --git a/aspnetcore/blazor/security/index.md b/aspnetcore/blazor/security/index.md index 09d11d1efc9d..21d33dc76eca 100644 --- a/aspnetcore/blazor/security/index.md +++ b/aspnetcore/blazor/security/index.md @@ -5,7 +5,7 @@ author: guardrex description: Learn about Blazor authentication and authorization scenarios. monikerRange: '>= aspnetcore-3.1' ms.author: wpickett -ms.date: 11/11/2025 +ms.date: 08/26/2026 uid: blazor/security/index --- # ASP.NET Core Blazor authentication and authorization @@ -1811,6 +1811,7 @@ PII refers any information relating to an identified or identifiable natural per :::moniker range=">= aspnetcore-6.0" * Server-side and Blazor Web App resources + * [Authorization patterns](xref:blazor/security/additional-scenarios#server-side-blazor-app-authorization-patterns) * [Quickstart: Add sign-in with Microsoft to an ASP.NET Core web app](/entra/identity-platform/quickstart-v2-aspnet-core-webapp) * [Quickstart: Protect an ASP.NET Core web API with Microsoft identity platform](/entra/identity-platform/quickstart-v2-aspnet-core-web-api) * : Includes guidance on: @@ -1829,12 +1830,14 @@ PII refers any information relating to an identified or identifiable natural per * [Awesome Blazor: Authentication](https://github.com/AdrienTorris/awesome-blazor#authentication) community sample links * * [Opaque (reference) access token support](xref:blazor/security/additional-scenarios#opaque-reference-access-token-support) +* [Blazor WebAssembly authorization patterns](xref:blazor/security/webassembly/index#blazor-webassembly-authorization-patterns) :::moniker-end :::moniker range="< aspnetcore-6.0" * Server-side Blazor resources + * [Authorization patterns](xref:blazor/security/additional-scenarios#server-side-blazor-app-authorization-patterns) * [Quickstart: Add sign-in with Microsoft to an ASP.NET Core web app](/entra/identity-platform/quickstart-v2-aspnet-core-webapp) * [Quickstart: Protect an ASP.NET Core web API with Microsoft identity platform](/entra/identity-platform/quickstart-v2-aspnet-core-web-api) * : Includes guidance on: @@ -1852,5 +1855,6 @@ PII refers any information relating to an identified or identifiable natural per * [Build a custom version of the Authentication.MSAL JavaScript library](xref:blazor/security/webassembly/additional-scenarios#build-a-custom-version-of-the-authenticationmsal-javascript-library) * [Awesome Blazor: Authentication](https://github.com/AdrienTorris/awesome-blazor#authentication) community sample links * [Opaque (reference) access token support](xref:blazor/security/additional-scenarios#opaque-reference-access-token-support) +* [Blazor WebAssembly authorization patterns](xref:blazor/security/webassembly/index#blazor-webassembly-authorization-patterns) :::moniker-end diff --git a/aspnetcore/blazor/security/webassembly/index.md b/aspnetcore/blazor/security/webassembly/index.md index 55ec2a3054da..b91dc611628f 100644 --- a/aspnetcore/blazor/security/webassembly/index.md +++ b/aspnetcore/blazor/security/webassembly/index.md @@ -1,11 +1,12 @@ --- title: Secure ASP.NET Core Blazor WebAssembly +ai-usage: ai-assisted author: guardrex description: Learn how to secure Blazor WebAssembly apps as single-page applications (SPAs). monikerRange: '>= aspnetcore-3.1' ms.author: wpickett ms.custom: sfi-ropc-nochange -ms.date: 11/11/2025 +ms.date: 08/26/2026 uid: blazor/security/webassembly/index --- # Secure ASP.NET Core Blazor WebAssembly @@ -170,9 +171,11 @@ The following authentication scenarios are covered in the .* + +Unlike server-side Blazor apps, Blazor WebAssembly apps don't support setting an to a policy with . Therefore, the only supported pattern for Blazor WebAssembly apps is to apply the [`[Authorize]` attribute](xref:blazor/security/index#authorize-attribute) ([API documentation](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute)) to Razor components using ***one*** of the following approaches: * In the app's imports file, add an [`@using`](xref:mvc/views/razor#using) directive for the namespace with an [`@attribute`](xref:mvc/views/razor#attribute) directive for the [`[Authorize]` attribute](xref:blazor/security/index#authorize-attribute). @@ -199,9 +202,6 @@ Apply the [`[Authorize]` attribute](xref:blazor/security/index#authorize-attribu @attribute [Authorize] ``` -> [!NOTE] -> Setting an to a policy with is **not** supported. - ## Use one identity provider app registration per app :::moniker range=">= aspnetcore-8.0" diff --git a/aspnetcore/security/authorization/introduction.md b/aspnetcore/security/authorization/introduction.md index 2e5d4ad4daef..53c4fc892833 100644 --- a/aspnetcore/security/authorization/introduction.md +++ b/aspnetcore/security/authorization/introduction.md @@ -1,12 +1,11 @@ --- title: Introduction to authorization in ASP.NET Core +ai-usage: ai-assisted author: wadepickett description: Learn the basics of authorization and how authorization works in ASP.NET Core apps. ms.author: wpickett -ms.date: 05/15/2026 +ms.date: 08/26/2026 uid: security/authorization/introduction - -# customer intent: As an ASP.NET developer, I want to learn about authorization in ASP.NET Core, so I can use authorization in my apps. --- # Introduction to authorization in ASP.NET Core @@ -22,12 +21,15 @@ ASP.NET Core authorization provides a simple declarative [role](xref:security/au ## Namespaces -Authorization components, including the `AuthorizeAttribute` and `AllowAnonymousAttribute` attributes, are defined in the `Microsoft.AspNetCore.Authorization` namespace. +Authorization components, including the [`[Authorize]` attribute](xref:Microsoft.AspNetCore.Authorization.AuthorizeAttribute) and [`[AllowAnonymous]` attribute](xref:Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute), are defined in the namespace. -Consult the documentation on [simple authorization](xref:security/authorization/simple). +For more information, see . -## Related content +## Additional resources * * * +* Blazor app authorization patterns + * [Server-side Blazor (Blazor Web Apps, Blazor Server apps)](xref:blazor/security/additional-scenarios#server-side-blazor-app-authorization-patterns) + * [Blazor WebAssembly](xref:blazor/security/webassembly/index#blazor-webassembly-authorization-patterns) From c680a4e48c897413c82b15a756cd0cd8e1899adc Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Mon, 31 Aug 2026 15:27:02 -0400 Subject: [PATCH 2/2] ToC/location/UID refactor for Metrics articles (#37547) --- .openpublishing.redirection.json | 30 ++++++++++++++ aspnetcore/blazor/performance/index.md | 4 +- .../servers/includes/memory-eviction2.md | 2 +- .../servers/kestrel/memory-management.md | 2 +- .../kestrel/security-considerations.md | 4 +- .../blazor.md} | 22 +++++----- aspnetcore/{log-mon => }/metrics/built-in.md | 14 +++---- .../diagnostics.md} | 16 ++++---- .../built-in-http.md => metrics/http.md} | 16 ++++---- .../metrics.md => metrics/overview.md} | 38 +++++++++--------- .../DisableMetrics/DisableMetrics.csproj | 0 .../metrics/samples/DisableMetrics/Program.cs | 0 .../EnrichMetrics/EnrichMetrics.csproj | 0 .../metrics/samples/EnrichMetrics/Program.cs | 0 .../samples/EnrichMetrics/appsettings.json | 0 .../samples/custom-metrics/ContosoMetrics.cs | 0 .../custom-metrics/CustomMetrics.csproj | 0 .../metrics/samples/custom-metrics/Program.cs | 0 .../samples/custom-metrics/SaleModel.cs | 0 .../samples/custom-metrics/appsettings.json | 0 .../samples/custom-metrics/prometheus.yml | 0 .../metrics/samples/custom-metrics/tests.http | 0 .../samples/metric-tests/BasicTests.cs | 0 .../samples/metric-tests/GlobalUsings.cs | 0 .../samples/metric-tests/MetricTests.csproj | 0 .../metrics/samples/web-metrics/Program.cs | 0 .../samples/web-metrics/WebMetric.csproj | 0 .../samples/web-metrics/appsettings.json | 0 .../samples/web-metrics/prometheus.yml | 0 .../security.md} | 16 ++++---- .../metrics/static/dashboard-screenshot.png | Bin .../metrics => }/metrics/static/kestrel.png | Bin .../metrics => }/metrics/static/metrics.png | Bin .../metrics => }/metrics/static/metrics2.png | Bin .../metrics/static/open_metric_exp.png | Bin .../metrics/static/prometheus_status.png | Bin aspnetcore/performance/rate-limit.md | 2 +- aspnetcore/release-notes/aspnetcore-10.0.md | 2 +- .../includes/identity-metrics.md | 2 +- .../aspnetcore-10/includes/memory-eviction.md | 2 +- .../improved-kestrel-connection-metrics.md | 4 +- .../security/authentication/identity.md | 2 +- aspnetcore/toc.yml | 30 ++++++++------ 43 files changed, 121 insertions(+), 87 deletions(-) rename aspnetcore/{log-mon/metrics/built-in-components.md => metrics/blazor.md} (87%) rename aspnetcore/{log-mon => }/metrics/built-in.md (67%) rename aspnetcore/{log-mon/metrics/built-in-diagnostics.md => metrics/diagnostics.md} (81%) rename aspnetcore/{log-mon/metrics/built-in-http.md => metrics/http.md} (98%) rename aspnetcore/{log-mon/metrics/metrics.md => metrics/overview.md} (92%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/DisableMetrics/DisableMetrics.csproj (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/DisableMetrics/Program.cs (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/EnrichMetrics/EnrichMetrics.csproj (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/EnrichMetrics/Program.cs (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/EnrichMetrics/appsettings.json (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/custom-metrics/ContosoMetrics.cs (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/custom-metrics/CustomMetrics.csproj (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/custom-metrics/Program.cs (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/custom-metrics/SaleModel.cs (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/custom-metrics/appsettings.json (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/custom-metrics/prometheus.yml (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/custom-metrics/tests.http (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/metric-tests/BasicTests.cs (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/metric-tests/GlobalUsings.cs (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/metric-tests/MetricTests.csproj (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/web-metrics/Program.cs (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/web-metrics/WebMetric.csproj (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/web-metrics/appsettings.json (100%) rename aspnetcore/{log-mon/metrics => }/metrics/samples/web-metrics/prometheus.yml (100%) rename aspnetcore/{log-mon/metrics/built-in-security.md => metrics/security.md} (93%) rename aspnetcore/{log-mon/metrics => }/metrics/static/dashboard-screenshot.png (100%) rename aspnetcore/{log-mon/metrics => }/metrics/static/kestrel.png (100%) rename aspnetcore/{log-mon/metrics => }/metrics/static/metrics.png (100%) rename aspnetcore/{log-mon/metrics => }/metrics/static/metrics2.png (100%) rename aspnetcore/{log-mon/metrics => }/metrics/static/open_metric_exp.png (100%) rename aspnetcore/{log-mon/metrics => }/metrics/static/prometheus_status.png (100%) diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index 2cee2c9b58fd..cd47aa9c5c75 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -1719,6 +1719,36 @@ "redirect_url": "/aspnet/core/fundamentals/validation", "redirect_document_id": false }, + { + "source_path": "aspnetcore/log-mon/metrics/metrics.md", + "redirect_url": "/aspnet/core/metrics/overview", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/log-mon/metrics/built-in.md", + "redirect_url": "/aspnet/core/metrics/built-in", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/log-mon/metrics/built-in-components.md", + "redirect_url": "/aspnet/core/metrics/blazor", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/log-mon/metrics/built-in-diagnostics.md", + "redirect_url": "/aspnet/core/metrics/diagnostics", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/log-mon/metrics/built-in-http.md", + "redirect_url": "/aspnet/core/metrics/http", + "redirect_document_id": false + }, + { + "source_path": "aspnetcore/log-mon/metrics/built-in-security.md", + "redirect_url": "/aspnet/core/metrics/security", + "redirect_document_id": false + }, { "source_path": "aspnetcore/blazor/hybrid/tutorials/maui.md", "redirect_url": "/dotnet/maui/get-started/first-app", diff --git a/aspnetcore/blazor/performance/index.md b/aspnetcore/blazor/performance/index.md index 17db8d8caf5f..f1084fa9c256 100644 --- a/aspnetcore/blazor/performance/index.md +++ b/aspnetcore/blazor/performance/index.md @@ -51,7 +51,7 @@ builder.Services.ConfigureOpenTelemetryTracerProvider(tracerProvider => ### Performance meters -For more information on the following performance meters, see . +For more information on the following performance meters, see . `Microsoft.AspNetCore.Components` meter: @@ -74,7 +74,7 @@ In server-side Blazor apps, additional circuit-specific metrics include: ### Blazor tracing -For more information on the following tracing activities, see . +For more information on the following tracing activities, see . The new activity tracing capabilities use the `Microsoft.AspNetCore.Components` activity source and provide three main types of tracing activities: circuit lifecycle, navigation, and event handling. diff --git a/aspnetcore/fundamentals/servers/includes/memory-eviction2.md b/aspnetcore/fundamentals/servers/includes/memory-eviction2.md index c2358185b6d4..cafaae652c72 100644 --- a/aspnetcore/fundamentals/servers/includes/memory-eviction2.md +++ b/aspnetcore/fundamentals/servers/includes/memory-eviction2.md @@ -8,7 +8,7 @@ In versions of .NET earlier than 10, memory allocated by the pool remains reserv The default memory pool used by the ASP.NET Core server implementations includes metrics, which can be used to monitor and analyze memory usage patterns. The metrics are under the name `"Microsoft.AspNetCore.MemoryPool"`. -For information about metrics and how to use them, see . +For information about metrics and how to use them, see . ## Manage memory pools diff --git a/aspnetcore/fundamentals/servers/kestrel/memory-management.md b/aspnetcore/fundamentals/servers/kestrel/memory-management.md index 29fcdbc1020f..23fd53166ede 100644 --- a/aspnetcore/fundamentals/servers/kestrel/memory-management.md +++ b/aspnetcore/fundamentals/servers/kestrel/memory-management.md @@ -25,7 +25,7 @@ This automatic eviction feature reduces overall memory usage and helps applicati The default memory pool used by the ASP.NET Core server implementations includes metrics, which can be used to monitor and analyze memory usage patterns. The metrics are under the name `"Microsoft.AspNetCore.MemoryPool"`. -For information about metrics and how to use them, see . +For information about metrics and how to use them, see . ## Manage memory pools diff --git a/aspnetcore/fundamentals/servers/kestrel/security-considerations.md b/aspnetcore/fundamentals/servers/kestrel/security-considerations.md index c45c118ac31c..0e258144a7c0 100644 --- a/aspnetcore/fundamentals/servers/kestrel/security-considerations.md +++ b/aspnetcore/fundamentals/servers/kestrel/security-considerations.md @@ -673,8 +673,8 @@ Beyond rejection-specific signals, Kestrel emits a set of built-in metrics under These metrics integrate with OpenTelemetry, `dotnet-counters`, Prometheus exporters, and Azure Monitor. For full setup guidance, see: -- [ASP.NET Core metrics overview](xref:log-mon/metrics/metrics) -- [Kestrel built-in metrics reference](xref:log-mon/metrics/built-in-http#microsoftaspnetcoreserverkestrel) +- [ASP.NET Core metrics overview](xref:metrics/overview) +- [Kestrel built-in metrics reference](xref:metrics/http#microsoftaspnetcoreserverkestrel) ### TLS-over-HTTP detection diff --git a/aspnetcore/log-mon/metrics/built-in-components.md b/aspnetcore/metrics/blazor.md similarity index 87% rename from aspnetcore/log-mon/metrics/built-in-components.md rename to aspnetcore/metrics/blazor.md index ae9f8e2ede05..0c6849e3a027 100644 --- a/aspnetcore/log-mon/metrics/built-in-components.md +++ b/aspnetcore/metrics/blazor.md @@ -1,5 +1,5 @@ --- -title: ASP.NET Core built-in Blazor (Components) metrics +title: ASP.NET Core built-in Blazor (Razor components) metrics ai-usage: ai-assisted author: guardrex description: Learn about built-in Blazor (Components) metrics for ASP.NET Core apps, including component, lifecycle, and server circuit metrics. @@ -7,13 +7,13 @@ monikerRange: '>= aspnetcore-10.0' ms.author: wpickett ms.date: 08/05/2026 ms.topic: reference -uid: log-mon/metrics/built-in-components +uid: metrics/blazor --- -# ASP.NET Core built-in Blazor (Components) metrics +# ASP.NET Core built-in Blazor (Razor components) metrics -This article describes the built-in Blazor (Components) metrics for ASP.NET Core produced using the API. These metrics cover Razor component route changes and browser events, component lifecycle events, and server-side Blazor circuits. They're available in ASP.NET Core 10.0 or later. +This article describes the built-in Blazor (Razor components) metrics for ASP.NET Core produced using the API. These metrics cover Razor component route changes and browser events, component lifecycle events, and server-side Blazor circuits. They're available in ASP.NET Core 10.0 or later. -For an overview of all built-in metrics reference pages and how to read this reference, see . For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . +For an overview of all built-in metrics reference pages and how to read this reference, see . For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . ## `Microsoft.AspNetCore.Components` @@ -128,10 +128,10 @@ Usage: * How many sessions processed? * How long do users keep the session/tab open? -## See also +## Additional resources -* -* -* -* -* +* +* +* +* +* diff --git a/aspnetcore/log-mon/metrics/built-in.md b/aspnetcore/metrics/built-in.md similarity index 67% rename from aspnetcore/log-mon/metrics/built-in.md rename to aspnetcore/metrics/built-in.md index bc041c7c1df4..50354246e06a 100644 --- a/aspnetcore/log-mon/metrics/built-in.md +++ b/aspnetcore/metrics/built-in.md @@ -6,22 +6,22 @@ description: Learn about built-in metrics for ASP.NET Core apps. ms.author: wpickett ms.date: 08/05/2026 ms.topic: reference -uid: log-mon/metrics/built-in +uid: metrics/built-in --- # ASP.NET Core built-in metrics This article is the entry point for the built-in metrics that ASP.NET Core produces using the API. The metrics reference is organized into focused pages by topic. Use the following pages to find the instruments, attributes, and usage guidance for each area. For a listing of metrics based on the older [EventCounters](/dotnet/core/diagnostics/event-counters) API, see [Available counters](/dotnet/core/diagnostics/available-counters). -For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . +For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . ## Metrics reference pages Page | Namespaces | Example metrics --- | --- | --- -[HTTP metrics](xref:log-mon/metrics/built-in-http) | `Microsoft.AspNetCore.Hosting`, `Microsoft.AspNetCore.Routing`, `Microsoft.AspNetCore.RateLimiting`, `Microsoft.AspNetCore.HeaderParsing`, `Microsoft.AspNetCore.Server.Kestrel`, `Microsoft.AspNetCore.Http.Connections` (SignalR) | `http.server.request.duration`, `aspnetcore.routing.match_attempts`, `kestrel.active_connections`, `signalr.server.active_connections` -[Diagnostics metrics](xref:log-mon/metrics/built-in-diagnostics) | `Microsoft.AspNetCore.Diagnostics` | `aspnetcore.diagnostics.exceptions` -[Blazor (Components) metrics](xref:log-mon/metrics/built-in-components) | `Microsoft.AspNetCore.Components`, `Microsoft.AspNetCore.Components.Lifecycle`, `Microsoft.AspNetCore.Components.Server.Circuits` | `aspnetcore.components.navigation`, `aspnetcore.components.circuit.active` -[Authentication and authorization metrics](xref:log-mon/metrics/built-in-security) | `Microsoft.AspNetCore.Authorization`, `Microsoft.AspNetCore.Authentication` | `aspnetcore.authorization.attempts`, `aspnetcore.authentication.challenges` +[HTTP metrics](xref:metrics/http) | `Microsoft.AspNetCore.Hosting`, `Microsoft.AspNetCore.Routing`, `Microsoft.AspNetCore.RateLimiting`, `Microsoft.AspNetCore.HeaderParsing`, `Microsoft.AspNetCore.Server.Kestrel`, `Microsoft.AspNetCore.Http.Connections` (SignalR) | `http.server.request.duration`, `aspnetcore.routing.match_attempts`, `kestrel.active_connections`, `signalr.server.active_connections` +[Diagnostics metrics](xref:metrics/diagnostics) | `Microsoft.AspNetCore.Diagnostics` | `aspnetcore.diagnostics.exceptions` +[Blazor (Components) metrics](xref:metrics/blazor) | `Microsoft.AspNetCore.Components`, `Microsoft.AspNetCore.Components.Lifecycle`, `Microsoft.AspNetCore.Components.Server.Circuits` | `aspnetcore.components.navigation`, `aspnetcore.components.circuit.active` +[Authentication and authorization metrics](xref:metrics/security) | `Microsoft.AspNetCore.Authorization`, `Microsoft.AspNetCore.Authentication` | `aspnetcore.authorization.attempts`, `aspnetcore.authentication.challenges` The Blazor (Components) and authentication and authorization metrics pages describe metrics available in ASP.NET Core 10.0 or later. Select ASP.NET Core 10.0 (or a later version) with the version selector to view that content. @@ -45,4 +45,4 @@ Each metric on the reference pages is documented with the following information: * **Presence**: When the attribute is present, for example `Always` or only under specific conditions. * **Usage**: Example questions the metric helps answer. -For guidance on how to collect, report, enrich, and test with these metrics, see . +For guidance on how to collect, report, enrich, and test with these metrics, see . diff --git a/aspnetcore/log-mon/metrics/built-in-diagnostics.md b/aspnetcore/metrics/diagnostics.md similarity index 81% rename from aspnetcore/log-mon/metrics/built-in-diagnostics.md rename to aspnetcore/metrics/diagnostics.md index 57fb6a685027..b89c73e0f763 100644 --- a/aspnetcore/log-mon/metrics/built-in-diagnostics.md +++ b/aspnetcore/metrics/diagnostics.md @@ -6,13 +6,13 @@ description: Learn about built-in diagnostics metrics for ASP.NET Core apps, rep ms.author: wpickett ms.date: 08/05/2026 ms.topic: reference -uid: log-mon/metrics/built-in-diagnostics +uid: metrics/diagnostics --- # ASP.NET Core built-in diagnostics metrics This article describes the built-in diagnostics metrics for ASP.NET Core produced using the API. These metrics report diagnostics information from the ASP.NET Core error handling middleware. -For an overview of all built-in metrics reference pages and how to read this reference, see . For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . +For an overview of all built-in metrics reference pages and how to read this reference, see . For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . ## `Microsoft.AspNetCore.Diagnostics` @@ -32,10 +32,10 @@ Attribute | Type | Description | Examples | Presence `aspnetcore.diagnostics.handler.type` | string | Full type name of the [`IExceptionHandler`](/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | If the exception was handled by this handler. `exception.type` | string | The full name of exception type. | `System.OperationCanceledException`; `Contoso.MyException` | Always -## See also +## Additional resources -* -* -* -* -* +* +* +* +* +* diff --git a/aspnetcore/log-mon/metrics/built-in-http.md b/aspnetcore/metrics/http.md similarity index 98% rename from aspnetcore/log-mon/metrics/built-in-http.md rename to aspnetcore/metrics/http.md index d3921eeca553..412f530c5fe7 100644 --- a/aspnetcore/log-mon/metrics/built-in-http.md +++ b/aspnetcore/metrics/http.md @@ -6,13 +6,13 @@ description: Learn about built-in HTTP metrics for ASP.NET Core apps, including ms.author: wpickett ms.date: 08/05/2026 ms.topic: reference -uid: log-mon/metrics/built-in-http +uid: metrics/http --- # ASP.NET Core built-in HTTP metrics This article describes the built-in HTTP-related metrics for ASP.NET Core produced using the API. These metrics cover hosting, routing, rate limiting, header parsing, the Kestrel web server, and SignalR. -For an overview of all built-in metrics reference pages and how to read this reference, see . For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . +For an overview of all built-in metrics reference pages and how to read this reference, see . For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . ## `Microsoft.AspNetCore.Hosting` @@ -356,10 +356,10 @@ Attribute | Type | Description | Examples | Presence `signalr.connection.status` | string | SignalR HTTP connection closure status. | `app_shutdown`; `timeout` | Always `signalr.transport` | string | [SignalR transport type](https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md) | `web_sockets`; `long_polling` | Always -## See also +## Additional resources -* -* -* -* -* +* +* +* +* +* diff --git a/aspnetcore/log-mon/metrics/metrics.md b/aspnetcore/metrics/overview.md similarity index 92% rename from aspnetcore/log-mon/metrics/metrics.md rename to aspnetcore/metrics/overview.md index 5960688e0c84..107f8b57aeed 100644 --- a/aspnetcore/log-mon/metrics/metrics.md +++ b/aspnetcore/metrics/overview.md @@ -8,9 +8,8 @@ ms.author: tdykstra ms.date: 08/24/2026 ms.reviewer: tdykstra ms.topic: concept-article -uid: log-mon/metrics/metrics +uid: metrics/overview --- - # ASP.NET Core metrics Metrics are numerical measurements reported over time. Use them to monitor the health of an app and generate alerts. For example, a web service might track how many: @@ -21,7 +20,7 @@ Metrics are numerical measurements reported over time. Use them to monitor the h Report these metrics to a monitoring system at regular intervals. Set up dashboards to view metrics and create alerts 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](xref:log-mon/metrics/built-in) for a comprehensive list of all instruments together with their attributes. +The comprehensive list of all instruments together with their attributes is described in . ## Use metrics @@ -53,7 +52,7 @@ 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"::: +:::code language="csharp" source="~/metrics/samples/web-metrics/Program.cs"::: ## View metrics with dotnet-counters @@ -100,7 +99,7 @@ ASP.NET Core has many built-in metrics. The `http.server.request.duration` metri The `http.server.request.duration` metric supports tag enrichment by using . Enrichment is when a library or app adds its own tags to a metric. This feature 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"::: +:::code language="csharp" source="~/metrics/samples/EnrichMetrics/Program.cs"::: The preceding example: @@ -124,14 +123,14 @@ You can exclude HTTP requests to an endpoint from metrics by adding metadata, wi * Add the [DisableHttpMetrics](xref:Microsoft.AspNetCore.Http.DisableHttpMetricsAttribute) attribute to the Web API controller, SignalR hub, or gRPC service. * Call [DisableHttpMetrics](xref:Microsoft.AspNetCore.Builder.HttpMetricsEndpointConventionBuilderExtensions.DisableHttpMetrics``1(``0)) when mapping endpoints in app startup: -:::code language="csharp" source="~/log-mon/metrics/metrics/samples/DisableMetrics/Program.cs" id="snippet_1" highlight="5"::: +:::code language="csharp" source="~/metrics/samples/DisableMetrics/Program.cs" id="snippet_1" highlight="5"::: Alternatively, the property was added for: * Advanced scenarios where a request doesn't map to an endpoint. * Dynamically disabling metrics collection for specific HTTP requests. -:::code language="csharp" source="~/log-mon/metrics/metrics/samples/DisableMetrics/Program.cs" id="snippet_2"::: +:::code language="csharp" source="~/metrics/samples/DisableMetrics/Program.cs" id="snippet_2"::: :::moniker-end @@ -147,15 +146,15 @@ ASP.NET Core registers in depend 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"::: +:::code language="csharp" source="~/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"::: +:::code language="csharp" source="~/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 used 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"::: +:::code language="csharp" source="~/metrics/samples/custom-metrics/Program.cs" id="snippet_InjectAndUseMetrics"::: To monitor the "Contoso.Web" meter, use the following [dotnet-counters](/dotnet/core/diagnostics/dotnet-counters) command. @@ -188,7 +187,7 @@ Press p to pause, r to resume, q to quit. :::moniker range=">= aspnetcore-11.0" -Starting in ASP.NET Core 11, the framework's built-in HTTP server metrics and traces comply with the required parts of the [OpenTelemetry HTTP server semantic conventions](https://opentelemetry.io/docs/specs/semconv/http/). The HTTP server request activity emits these attributes by default, matching the built-in metrics. As a result, the [`OpenTelemetry.Instrumentation.AspNetCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) NuGet package is optional for collecting HTTP server metrics and traces. The sample in this article uses only the built-in meters (`Microsoft.AspNetCore.Hosting` and `Microsoft.AspNetCore.Server.Kestrel`) and doesn't reference the instrumentation package. For the list of built-in instruments and their attributes, see . +Starting in ASP.NET Core 11, the framework's built-in HTTP server metrics and traces comply with the required parts of the [OpenTelemetry HTTP server semantic conventions](https://opentelemetry.io/docs/specs/semconv/http/). The HTTP server request activity emits these attributes by default, matching the built-in metrics. As a result, the [`OpenTelemetry.Instrumentation.AspNetCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) NuGet package is optional for collecting HTTP server metrics and traces. The sample in this article uses only the built-in meters (`Microsoft.AspNetCore.Hosting` and `Microsoft.AspNetCore.Server.Kestrel`) and doesn't reference the instrumentation package. For the list of built-in instruments and their attributes, see . Although the package is optional, it isn't a drop-in equivalent of the built-in instrumentation. The built-in instrumentation covers only the *required* parts of the semantic conventions. Consider the following differences before you remove the package: @@ -218,6 +217,7 @@ In the preceding example: Alternatively, call `AddAspNetCoreInstrumentation()` from the [`OpenTelemetry.Instrumentation.AspNetCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) package, which registers the source for you. :::moniker-end + This tutorial shows one of the integrations available for OpenTelemetry metrics using the OSS [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) projects. The metrics data flow: 1. The ASP.NET Core metric APIs record measurements from the example app. @@ -241,7 +241,7 @@ Go to the sample app. The browser shows `Hello OpenTelemetry! ticks:<3digits>` w Append `/metrics` to the URL to view the metrics endpoint. The browser displays the metrics being collected: -![metrics 2](~/log-mon/metrics/metrics/static/metrics.png) +![metrics 2](~/metrics/static/metrics.png) ### Set up and configure Prometheus @@ -249,7 +249,7 @@ Follow the [Prometheus first steps](https://prometheus.io/docs/introduction/firs Modify the *prometheus.yml* configuration file so that Prometheus scrapes the metrics endpoint that the example app exposes. 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"::: +:::code language="yaml" source="~/metrics/samples/web-metrics/prometheus.yml" highlight="31-99"::: In the preceding highlighted YAML, replace `5045` with the port number that the example app uses. @@ -258,19 +258,19 @@ In the preceding highlighted YAML, replace `5045` with the port number that the 1. Reload the configuration or restart the Prometheus server. 1. Confirm that OpenTelemetryTest is in the UP state in the **Status** > **Targets** page of the Prometheus web portal. -![Prometheus status](~/log-mon/metrics/metrics/static/prometheus_status.png) +![Prometheus status](~/metrics/static/prometheus_status.png) Select the **Open metric explorer** icon to see available metrics: -![Prometheus open_metric_exp](~/log-mon/metrics/metrics/static/open_metric_exp.png) +![Prometheus open_metric_exp](~/metrics/static/open_metric_exp.png) Enter a counter category such as `http_` in the **Expression** input box to see the available metrics: -![available metrics](~/log-mon/metrics/metrics/static/metrics2.png) +![available metrics](~/metrics/static/metrics2.png) Alternatively, enter a counter category such as `kestrel` in the **Expression** input box to see the available metrics: -![Prometheus kestrel](~/log-mon/metrics/metrics/static/kestrel.png) +![Prometheus kestrel](~/metrics/static/kestrel.png) ### Show metrics on a Grafana dashboard @@ -278,13 +278,13 @@ Alternatively, enter a counter category such as `kestrel` in the **Expression** * Follow [Creating a Prometheus graph](https://prometheus.io/docs/visualization/grafana/#creating-a-prometheus-graph). Alternatively, pre-built dashboards for .NET metrics are available to download at [.NET team dashboards @ grafana.com](https://aka.ms/dotnet/grafana-dashboards). Downloaded dashboard JSON can be [imported into Grafana](https://grafana.com/docs/grafana/latest/dashboards/manage-dashboards/#import-a-dashboard). -![dashboard-screenshot2](~/log-mon/metrics/metrics/static/dashboard-screenshot.png) +![dashboard-screenshot2](~/metrics/static/dashboard-screenshot.png) ## Test metrics in ASP.NET Core apps You can test metrics in ASP.NET Core apps. One way to do this is to collect and assert metrics values in [ASP.NET Core integration tests](xref:test/integration-tests) by using . -:::code language="csharp" source="~/log-mon/metrics/metrics/samples/metric-tests/BasicTests.cs" id="snippet_TestClass"::: +:::code language="csharp" source="~/metrics/samples/metric-tests/BasicTests.cs" id="snippet_TestClass"::: The preceding test: diff --git a/aspnetcore/log-mon/metrics/metrics/samples/DisableMetrics/DisableMetrics.csproj b/aspnetcore/metrics/samples/DisableMetrics/DisableMetrics.csproj similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/DisableMetrics/DisableMetrics.csproj rename to aspnetcore/metrics/samples/DisableMetrics/DisableMetrics.csproj diff --git a/aspnetcore/log-mon/metrics/metrics/samples/DisableMetrics/Program.cs b/aspnetcore/metrics/samples/DisableMetrics/Program.cs similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/DisableMetrics/Program.cs rename to aspnetcore/metrics/samples/DisableMetrics/Program.cs diff --git a/aspnetcore/log-mon/metrics/metrics/samples/EnrichMetrics/EnrichMetrics.csproj b/aspnetcore/metrics/samples/EnrichMetrics/EnrichMetrics.csproj similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/EnrichMetrics/EnrichMetrics.csproj rename to aspnetcore/metrics/samples/EnrichMetrics/EnrichMetrics.csproj diff --git a/aspnetcore/log-mon/metrics/metrics/samples/EnrichMetrics/Program.cs b/aspnetcore/metrics/samples/EnrichMetrics/Program.cs similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/EnrichMetrics/Program.cs rename to aspnetcore/metrics/samples/EnrichMetrics/Program.cs diff --git a/aspnetcore/log-mon/metrics/metrics/samples/EnrichMetrics/appsettings.json b/aspnetcore/metrics/samples/EnrichMetrics/appsettings.json similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/EnrichMetrics/appsettings.json rename to aspnetcore/metrics/samples/EnrichMetrics/appsettings.json diff --git a/aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/ContosoMetrics.cs b/aspnetcore/metrics/samples/custom-metrics/ContosoMetrics.cs similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/ContosoMetrics.cs rename to aspnetcore/metrics/samples/custom-metrics/ContosoMetrics.cs diff --git a/aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/CustomMetrics.csproj b/aspnetcore/metrics/samples/custom-metrics/CustomMetrics.csproj similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/CustomMetrics.csproj rename to aspnetcore/metrics/samples/custom-metrics/CustomMetrics.csproj diff --git a/aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/Program.cs b/aspnetcore/metrics/samples/custom-metrics/Program.cs similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/Program.cs rename to aspnetcore/metrics/samples/custom-metrics/Program.cs diff --git a/aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/SaleModel.cs b/aspnetcore/metrics/samples/custom-metrics/SaleModel.cs similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/SaleModel.cs rename to aspnetcore/metrics/samples/custom-metrics/SaleModel.cs diff --git a/aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/appsettings.json b/aspnetcore/metrics/samples/custom-metrics/appsettings.json similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/appsettings.json rename to aspnetcore/metrics/samples/custom-metrics/appsettings.json diff --git a/aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/prometheus.yml b/aspnetcore/metrics/samples/custom-metrics/prometheus.yml similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/prometheus.yml rename to aspnetcore/metrics/samples/custom-metrics/prometheus.yml diff --git a/aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/tests.http b/aspnetcore/metrics/samples/custom-metrics/tests.http similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/custom-metrics/tests.http rename to aspnetcore/metrics/samples/custom-metrics/tests.http diff --git a/aspnetcore/log-mon/metrics/metrics/samples/metric-tests/BasicTests.cs b/aspnetcore/metrics/samples/metric-tests/BasicTests.cs similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/metric-tests/BasicTests.cs rename to aspnetcore/metrics/samples/metric-tests/BasicTests.cs diff --git a/aspnetcore/log-mon/metrics/metrics/samples/metric-tests/GlobalUsings.cs b/aspnetcore/metrics/samples/metric-tests/GlobalUsings.cs similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/metric-tests/GlobalUsings.cs rename to aspnetcore/metrics/samples/metric-tests/GlobalUsings.cs diff --git a/aspnetcore/log-mon/metrics/metrics/samples/metric-tests/MetricTests.csproj b/aspnetcore/metrics/samples/metric-tests/MetricTests.csproj similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/metric-tests/MetricTests.csproj rename to aspnetcore/metrics/samples/metric-tests/MetricTests.csproj diff --git a/aspnetcore/log-mon/metrics/metrics/samples/web-metrics/Program.cs b/aspnetcore/metrics/samples/web-metrics/Program.cs similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/web-metrics/Program.cs rename to aspnetcore/metrics/samples/web-metrics/Program.cs diff --git a/aspnetcore/log-mon/metrics/metrics/samples/web-metrics/WebMetric.csproj b/aspnetcore/metrics/samples/web-metrics/WebMetric.csproj similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/web-metrics/WebMetric.csproj rename to aspnetcore/metrics/samples/web-metrics/WebMetric.csproj diff --git a/aspnetcore/log-mon/metrics/metrics/samples/web-metrics/appsettings.json b/aspnetcore/metrics/samples/web-metrics/appsettings.json similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/web-metrics/appsettings.json rename to aspnetcore/metrics/samples/web-metrics/appsettings.json diff --git a/aspnetcore/log-mon/metrics/metrics/samples/web-metrics/prometheus.yml b/aspnetcore/metrics/samples/web-metrics/prometheus.yml similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/samples/web-metrics/prometheus.yml rename to aspnetcore/metrics/samples/web-metrics/prometheus.yml diff --git a/aspnetcore/log-mon/metrics/built-in-security.md b/aspnetcore/metrics/security.md similarity index 93% rename from aspnetcore/log-mon/metrics/built-in-security.md rename to aspnetcore/metrics/security.md index fd681664e231..47ab20746dfd 100644 --- a/aspnetcore/log-mon/metrics/built-in-security.md +++ b/aspnetcore/metrics/security.md @@ -7,13 +7,13 @@ monikerRange: '>= aspnetcore-10.0' ms.author: wpickett ms.date: 08/05/2026 ms.topic: reference -uid: log-mon/metrics/built-in-security +uid: metrics/security --- # ASP.NET Core built-in authentication and authorization metrics This article describes the built-in authentication and authorization metrics for ASP.NET Core produced using the API. These metrics cover authorization attempts and authentication operations. They're available in ASP.NET Core 10.0 or later. -For an overview of all built-in metrics reference pages and how to read this reference, see . For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . +For an overview of all built-in metrics reference pages and how to read this reference, see . For information on how to collect, report, enrich, and test with ASP.NET Core metrics, see . ## `Microsoft.AspNetCore.Authorization` @@ -100,10 +100,10 @@ Attribute | Type | Description | Examples | Presence `aspnetcore.authentication.scheme` | string | The name of the authentication scheme. | `Bearer`; `Cookies` | `Conditionally Required` if the request did not end with an error. `error.type` | string | The full name of the exception type. | `System.InvalidOperationException`; `Contoso.MyException` | `Conditionally Required` if the request has ended with an error. -## See also +## Additional resources -* -* -* -* -* +* +* +* +* +* diff --git a/aspnetcore/log-mon/metrics/metrics/static/dashboard-screenshot.png b/aspnetcore/metrics/static/dashboard-screenshot.png similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/static/dashboard-screenshot.png rename to aspnetcore/metrics/static/dashboard-screenshot.png diff --git a/aspnetcore/log-mon/metrics/metrics/static/kestrel.png b/aspnetcore/metrics/static/kestrel.png similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/static/kestrel.png rename to aspnetcore/metrics/static/kestrel.png diff --git a/aspnetcore/log-mon/metrics/metrics/static/metrics.png b/aspnetcore/metrics/static/metrics.png similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/static/metrics.png rename to aspnetcore/metrics/static/metrics.png diff --git a/aspnetcore/log-mon/metrics/metrics/static/metrics2.png b/aspnetcore/metrics/static/metrics2.png similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/static/metrics2.png rename to aspnetcore/metrics/static/metrics2.png diff --git a/aspnetcore/log-mon/metrics/metrics/static/open_metric_exp.png b/aspnetcore/metrics/static/open_metric_exp.png similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/static/open_metric_exp.png rename to aspnetcore/metrics/static/open_metric_exp.png diff --git a/aspnetcore/log-mon/metrics/metrics/static/prometheus_status.png b/aspnetcore/metrics/static/prometheus_status.png similarity index 100% rename from aspnetcore/log-mon/metrics/metrics/static/prometheus_status.png rename to aspnetcore/metrics/static/prometheus_status.png diff --git a/aspnetcore/performance/rate-limit.md b/aspnetcore/performance/rate-limit.md index ee77706112dc..1d36352b3930 100644 --- a/aspnetcore/performance/rate-limit.md +++ b/aspnetcore/performance/rate-limit.md @@ -465,7 +465,7 @@ In the preceding controller: ## Rate limiting metrics -The rate limiting middleware provides [built-in metrics and monitoring](/aspnet/core/log-mon/metrics/metrics) capabilities to help understand how rate limits are affecting app performance and user experience. See [`Microsoft.AspNetCore.RateLimiting`](/dotnet/core/diagnostics/built-in-metrics-aspnetcore#microsoftaspnetcoreratelimiting) for a list of metrics. +The rate limiting middleware provides [built-in metrics and monitoring](/aspnet/core/metrics/overview) capabilities to help understand how rate limits are affecting app performance and user experience. See [`Microsoft.AspNetCore.RateLimiting`](/dotnet/core/diagnostics/built-in-metrics-aspnetcore#microsoftaspnetcoreratelimiting) for a list of metrics. diff --git a/aspnetcore/release-notes/aspnetcore-10.0.md b/aspnetcore/release-notes/aspnetcore-10.0.md index 7a34601cb336..e4dc4984bc9d 100644 --- a/aspnetcore/release-notes/aspnetcore-10.0.md +++ b/aspnetcore/release-notes/aspnetcore-10.0.md @@ -90,7 +90,7 @@ The following image shows an example of the Authenticated request duration metri ![Authenticated request duration in the Aspire dashboard](https://github.com/user-attachments/assets/170615e9-ef25-48a1-a482-4933e2e03f03) -For more information, see . +For more information, see . [!INCLUDE[](~/release-notes/aspnetcore-10/includes/identity-metrics.md)] diff --git a/aspnetcore/release-notes/aspnetcore-10/includes/identity-metrics.md b/aspnetcore/release-notes/aspnetcore-10/includes/identity-metrics.md index b32afa1b5652..96dffb64f613 100644 --- a/aspnetcore/release-notes/aspnetcore-10/includes/identity-metrics.md +++ b/aspnetcore/release-notes/aspnetcore-10/includes/identity-metrics.md @@ -22,4 +22,4 @@ The new metrics are in the `Microsoft.AspNetCore.Identity` meter: * `aspnetcore.identity.sign_in.two_factor_clients_remembered` * `aspnetcore.identity.sign_in.two_factor_clients_forgotten` -For more information about using metrics in ASP.NET Core, see . +For more information about using metrics in ASP.NET Core, see . diff --git a/aspnetcore/release-notes/aspnetcore-10/includes/memory-eviction.md b/aspnetcore/release-notes/aspnetcore-10/includes/memory-eviction.md index 77673a233b9e..641d24a7d4a4 100644 --- a/aspnetcore/release-notes/aspnetcore-10/includes/memory-eviction.md +++ b/aspnetcore/release-notes/aspnetcore-10/includes/memory-eviction.md @@ -10,7 +10,7 @@ Previously, memory allocated by the pool would remain reserved, even when not in Metrics have been added to the default memory pool used by our server implementations. The new metrics are under the name `"Microsoft.AspNetCore.MemoryPool"`. -For information about metrics and how to use them, see . +For information about metrics and how to use them, see . #### Manage memory pools diff --git a/aspnetcore/release-notes/aspnetcore-9/includes/improved-kestrel-connection-metrics.md b/aspnetcore/release-notes/aspnetcore-9/includes/improved-kestrel-connection-metrics.md index bedb67160b9b..e78044925606 100644 --- a/aspnetcore/release-notes/aspnetcore-9/includes/improved-kestrel-connection-metrics.md +++ b/aspnetcore/release-notes/aspnetcore-9/includes/improved-kestrel-connection-metrics.md @@ -11,7 +11,7 @@ Here is a small sample of the `error.type` values: Previously, diagnosing Kestrel connection issues required a server to record detailed, low-level logging. However, logs can be expensive to generate and store, and it can be difficult to find the right information among the noise. -Metrics are a much cheaper alternative that can be left on in a production environment with minimal impact. Collected metrics can [drive dashboards and alerts](/aspnet/core/log-mon/metrics/metrics#show-metrics-on-a-grafana-dashboard). Once a problem is identified at a high-level with metrics, further investigation using logging and other tooling can begin. +Metrics are a much cheaper alternative that can be left on in a production environment with minimal impact. Collected metrics can [drive dashboards and alerts](xref:metrics/overview#show-metrics-on-a-grafana-dashboard). Once a problem is identified at a high-level with metrics, further investigation using logging and other tooling can begin. We expect improved connection metrics to be useful in many scenarios: @@ -19,4 +19,4 @@ We expect improved connection metrics to be useful in many scenarios: * Observing ongoing external attacks on Kestrel that impact performance and stability. * Recording attempted external attacks on Kestrel that Kestrel's built-in security hardening prevented. -For more information, see [ASP.NET Core metrics](/aspnet/core/log-mon/metrics/metrics). +For more information, see . diff --git a/aspnetcore/security/authentication/identity.md b/aspnetcore/security/authentication/identity.md index 84f3e6c3acbd..0f4b8e73a132 100644 --- a/aspnetcore/security/authentication/identity.md +++ b/aspnetcore/security/authentication/identity.md @@ -211,7 +211,7 @@ For more information on `IdentityOptions`, see . +For complete details on available metrics and how to use them, see . :::moniker-end diff --git a/aspnetcore/toc.yml b/aspnetcore/toc.yml index 044cd6935996..c1e87ac552bd 100644 --- a/aspnetcore/toc.yml +++ b/aspnetcore/toc.yml @@ -550,20 +550,9 @@ items: - name: Health checks displayName: logging, monitoring uid: host-and-deploy/health-checks - - name: Metrics overview + - name: Metrics displayName: logging, monitoring - uid: log-mon/metrics/metrics - - name: Built-in metrics - uid: log-mon/metrics/built-in - items: - - name: HTTP metrics - uid: log-mon/metrics/built-in-http - - name: Diagnostics metrics - uid: log-mon/metrics/built-in-diagnostics - - name: Blazor (Components) metrics - uid: log-mon/metrics/built-in-components - - name: Authentication and authorization metrics - uid: log-mon/metrics/built-in-security + uid: metrics/overview - name: HttpContext uid: fundamentals/use-httpcontext - name: Routing @@ -1679,6 +1668,21 @@ items: - name: Diagnosing proxy issues displayName: yarp uid: fundamentals/servers/yarp/diagnosing-yarp-issues + - name: Metrics + items: + - name: Overview + displayName: logging, monitoring + uid: metrics/overview + - name: Built-in metrics + uid: metrics/built-in + - name: HTTP metrics + uid: metrics/http + - name: Diagnostics metrics + uid: metrics/diagnostics + - name: Blazor (Razor components) metrics + uid: metrics/blazor + - name: Authentication and authorization metrics + uid: metrics/security - name: Test items: - name: .NET Hot Reload