# Semantic conventions for ASP.NET Core metrics **Status**: [Stable][DocumentStatus] This article defines semantic conventions for ASP.NET Core metrics. - [Server](#server) - [Routing](#routing) - [Metric: `aspnetcore.routing.match_attempts`](#metric-aspnetcoreroutingmatch_attempts) - [Exceptions](#exceptions) - [Metric: `aspnetcore.diagnostics.exceptions`](#metric-aspnetcorediagnosticsexceptions) - [Rate-limiting](#rate-limiting) - [Metric: `aspnetcore.rate_limiting.active_request_leases`](#metric-aspnetcorerate_limitingactive_request_leases) - [Metric: `aspnetcore.rate_limiting.request_lease.duration`](#metric-aspnetcorerate_limitingrequest_leaseduration) - [Metric: `aspnetcore.rate_limiting.queued_requests`](#metric-aspnetcorerate_limitingqueued_requests) - [Metric: `aspnetcore.rate_limiting.request.time_in_queue`](#metric-aspnetcorerate_limitingrequesttime_in_queue) - [Metric: `aspnetcore.rate_limiting.requests`](#metric-aspnetcorerate_limitingrequests) ## Server ## Routing All routing metrics are reported by the `Microsoft.AspNetCore.Routing` meter. ### Metric: `aspnetcore.routing.match_attempts` | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `aspnetcore.routing.match_attempts` | Counter | `{match_attempt}` | Number of requests that were attempted to be matched to an endpoint. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | **[1]:** Meter name: `Microsoft.AspNetCore.Routing`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`aspnetcore.routing.match_status`](/docs/registry/attributes/aspnetcore.md) | string | Match result - success or failure | `success`; `failure` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`aspnetcore.routing.is_fallback`](/docs/registry/attributes/aspnetcore.md) | boolean | A value that indicates whether the matched route is a fallback route. | `true` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`http.route`](/docs/registry/attributes/http.md) | string | The matched route, that is, the path template in the format used by the respective server framework. [1] | `/users/:userID?`; `{controller}/{action}/{id?}` | `Conditionally Required` if and only if a route was successfully matched. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1] `http.route`:** MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. --- `aspnetcore.routing.match_status` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | |---|---|---| | `failure` | Match failed | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `success` | Match succeeded | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Exceptions Exceptions Metric is reported by the `Microsoft.AspNetCore.Diagnostics` meter. ### Metric: `aspnetcore.diagnostics.exceptions` | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `aspnetcore.diagnostics.exceptions` | Counter | `{exception}` | Number of exceptions caught by exception handling middleware. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | **[1]:** Meter name: `Microsoft.AspNetCore.Diagnostics`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`aspnetcore.diagnostics.exception.result`](/docs/registry/attributes/aspnetcore.md) | string | ASP.NET Core exception middleware handling result | `handled`; `unhandled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`error.type`](/docs/registry/attributes/error.md) | string | The full name of exception type. [1] | `System.OperationCanceledException`; `Contoso.MyException` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`aspnetcore.diagnostics.handler.type`](/docs/registry/attributes/aspnetcore.md) | string | Full type name of the [`IExceptionHandler`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.diagnostics.iexceptionhandler) implementation that handled the exception. | `Contoso.MyHandler` | `Conditionally Required` [2] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. When `error.type` is set to a type (e.g., an exception type), its canonical class name identifying the type within the artifact SHOULD be used. Instrumentations SHOULD document the list of errors they report. The cardinality of `error.type` within one instrumentation library SHOULD be low. Telemetry consumers that aggregate data from multiple instrumentation libraries and applications should be prepared for `error.type` to have high cardinality at query time when no additional filters are applied. If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute - Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. **[2] `aspnetcore.diagnostics.handler.type`:** if and only if the exception was handled by this handler. --- `aspnetcore.diagnostics.exception.result` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | |---|---|---| | `aborted` | Exception handling didn't run because the request was aborted. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `handled` | Exception was handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `skipped` | Exception handling was skipped because the response had started. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unhandled` | Exception was not handled by the exception handling middleware. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | |---|---|---| | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ## Rate-limiting All rate-limiting metrics are reported by the `Microsoft.AspNetCore.RateLimiting` meter. ### Metric: `aspnetcore.rate_limiting.active_request_leases` | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `aspnetcore.rate_limiting.active_request_leases` | UpDownCounter | `{request}` | Number of requests that are currently active on the server that hold a rate limiting lease. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | **[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`aspnetcore.rate_limiting.policy`](/docs/registry/attributes/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1] `aspnetcore.rate_limiting.policy`:** if the matched endpoint for the request had a rate-limiting policy. ### Metric: `aspnetcore.rate_limiting.request_lease.duration` this metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.44.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `aspnetcore.rate_limiting.request_lease.duration` | Histogram | `s` | The duration of rate limiting lease held by requests on the server. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | **[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`aspnetcore.rate_limiting.policy`](/docs/registry/attributes/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1] `aspnetcore.rate_limiting.policy`:** if the matched endpoint for the request had a rate-limiting policy. ### Metric: `aspnetcore.rate_limiting.queued_requests` | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `aspnetcore.rate_limiting.queued_requests` | UpDownCounter | `{request}` | Number of requests that are currently queued, waiting to acquire a rate limiting lease. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | **[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`aspnetcore.rate_limiting.policy`](/docs/registry/attributes/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1] `aspnetcore.rate_limiting.policy`:** if the matched endpoint for the request had a rate-limiting policy. ### Metric: `aspnetcore.rate_limiting.request.time_in_queue` this metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.44.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `aspnetcore.rate_limiting.request.time_in_queue` | Histogram | `s` | The time the request spent in a queue waiting to acquire a rate limiting lease. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | **[1]:** Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`aspnetcore.rate_limiting.result`](/docs/registry/attributes/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`aspnetcore.rate_limiting.policy`](/docs/registry/attributes/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1] `aspnetcore.rate_limiting.policy`:** if the matched endpoint for the request had a rate-limiting policy. --- `aspnetcore.rate_limiting.result` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | |---|---|---| | `acquired` | Lease was acquired | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `endpoint_limiter` | Lease request was rejected by the endpoint limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `global_limiter` | Lease request was rejected by the global limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ### Metric: `aspnetcore.rate_limiting.requests` | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `aspnetcore.rate_limiting.requests` | Counter | `{request}` | Number of requests that tried to acquire a rate limiting lease. [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | **[1]:** Requests could be: * Rejected by global or endpoint rate limiting policies * Canceled while waiting for the lease. Meter name: `Microsoft.AspNetCore.RateLimiting`; Added in: ASP.NET Core 8.0 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| | [`aspnetcore.rate_limiting.result`](/docs/registry/attributes/aspnetcore.md) | string | Rate-limiting result, shows whether the lease was acquired or contains a rejection reason | `acquired`; `request_canceled` | `Required` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`aspnetcore.rate_limiting.policy`](/docs/registry/attributes/aspnetcore.md) | string | Rate limiting policy name. | `fixed`; `sliding`; `token` | `Conditionally Required` [1] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | **[1] `aspnetcore.rate_limiting.policy`:** if the matched endpoint for the request had a rate-limiting policy. --- `aspnetcore.rate_limiting.result` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | |---|---|---| | `acquired` | Lease was acquired | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `endpoint_limiter` | Lease request was rejected by the endpoint limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `global_limiter` | Lease request was rejected by the global limiter | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `request_canceled` | Lease request was canceled | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | [DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status