Skip to content

Commit

Permalink
Add a reference for new .NET 8 metrics (#37213)
Browse files Browse the repository at this point in the history
* Add a reference for new .NET 8 metrics

Part of the work for #36748

---------

Co-authored-by: Anton Firszov <antonfir@gmail.com>
  • Loading branch information
noahfalk and antonfirsov committed Oct 16, 2023
1 parent fe7431f commit e91f03b
Show file tree
Hide file tree
Showing 8 changed files with 578 additions and 13 deletions.
1 change: 1 addition & 0 deletions docs/core/diagnostics/available-counters.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ ms.date: 12/17/2020
# Well-known EventCounters in .NET

The .NET runtime and libraries implement and publish several [EventCounters](./event-counters.md) that can be used to identify and diagnose various performance issues. This article is a reference on the providers that can be used to monitor these counters and their descriptions.
See the [well-known metrics reference](built-in-metrics.md) instead if you are working with .NET's newer [System.Diagnostics.Metrics API](metrics.md).

## System.Runtime counters

Expand Down
393 changes: 393 additions & 0 deletions docs/core/diagnostics/built-in-metrics-aspnetcore.md

Large diffs are not rendered by default.

151 changes: 151 additions & 0 deletions docs/core/diagnostics/built-in-metrics-system-net.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
---
title: System.Net Metrics
description: Review the metrics available for System.Net
ms.topic: reference
ms.date: 9/21/2023
---

# System.Net Metrics

This article describes the networking metrics built-in for <xref:System.Net> produced using the
<xref:System.Diagnostics.Metrics?displayProperty=nameWithType> API. For a listing of metrics based on the alternate [EventCounters](event-counters.md) API,
see [here](available-counters.md).

- [Meter: `System.Net.NameResolution`](#meter-systemnetnameresolution) - Metrics for DNS lookups
* [Instrument: `dns.lookup.duration`](#instrument-dnslookupduration)
- [Meter: `System.Net.Http`](#meter-systemnethttp) - Metrics for outbound networking requests using HttpClient
* [Instrument: `http.client.open_connections`](#instrument-httpclientopen_connections)
* [Instrument: `http.client.connection.duration`](#instrument-httpclientconnectionduration)
* [Instrument: `http.client.request.duration`](#instrument-httpclientrequestduration)
* [Instrument: `http.client.request.time_in_queue`](#instrument-httpclientrequesttime_in_queue)
* [Instrument: `http.client.active_requests`](#instrument-httpclientactive_requests)

## Meter: `System.Net.NameResolution`

### Instrument: `dns.lookup.duration`

| Name | Instrument Type | Unit | Description |
| -------- | --------------- | ----------- | -------------- |
| `dns.lookup.duration` | Histogram | `s` | Measures the time taken to perform a DNS lookup. |

| Attribute | Type | Description | Examples | Presence |
|---|---|---|---|---|
| `dns.question.name` | string | The name being queried. | `www.example.com`; `dot.net` | Always |
| `error.type` | string | A well-known error string or the full type name of an exception that occured. | `host_not_found`; `System.Net.Sockets.SocketException` | If an error occured |

This metric measures the time take to make DNS requests. These requests can occur by calling methods on
<xref:System.Net.Dns> or indirectly wihtin higher level APIs on types such as <xref:System.Net.Http.HttpClient>.

Most errors when doing a DNS lookup throw a <xref:System.Net.Sockets.SocketException>. To better disambiguate the common error cases, SocketExceptions with specific <xref:System.Net.Sockets.SocketException.SocketErrorCode>
are given explicit error names in `error.type`:

| SocketErrorCode | `error.type` |
| --------------- | ------------ |
| <xref:System.Net.Sockets.SocketError.HostNotFound> | host_not_found |
| <xref:System.Net.Sockets.SocketError.TryAgain> | try_again |
| <xref:System.Net.Sockets.SocketError.AddressFamilyNotSupported> | address_family_not_supported |
| <xref:System.Net.Sockets.SocketError.NoRecovery> | no_recovery |

SocketExceptions with any other SocketError value are reported as `System.Net.Sockets.SocketException`.

Available starting in: .NET 8

## Meter: `System.Net.Http`

### Instrument: `http.client.open_connections`

| Name | Instrument Type | Unit (UCUM) | Description |
| -------- | --------------- | ----------- | -------------- |
| `http.client.open_connections` | UpDownCounter | `{connection}` | Number of outbound HTTP connections that are currently active or idle on the client |

| Attribute | Type | Description | Examples | Presence |
|---|---|---|---|---|
| `http.connection.state` | string | State of HTTP connection in the HTTP connection pool. | `active`; `idle` | Always |
| `network.protocol.version` | string | Version of the application layer protocol used. | `1.1`; `2` | Always |
| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always |
| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) |
| `network.peer.address` | string | Peer IP address of the socket connection. | `10.5.3.2` | Always |
| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always |

<xref:System.Net.Http.HttpClient>, when configured to use the default <xref:System.Net.Http.SocketsHttpHandler>, maintains a cached pool of network connections for sending HTTP messages. This metric counts how many connections are currently
in the pool. Active connections are handling active requests. Active connects could be transmitting data or awaiting the client or server. Idle connections aren't handling any
requests, but are left open so that future requests can be handled more quickly.

Available starting in: .NET 8

### Instrument: `http.client.connection.duration`

| Name | Instrument Type | Unit (UCUM) | Description |
| -------- | --------------- | ----------- | -------------- |
| `http.client.connection.duration` | Histogram | `s` | The duration of successfully established outbound HTTP connections. |

| Attribute | Type | Description | Examples | Presence |
|---|---|---|---|---|
| `network.protocol.version` | string | Version of the application layer protocol used. | `1.1`; `2` | Always |
| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always |
| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) |
| `network.peer.address` | string | IP address of the socket connection. | `10.5.3.2` | Always |
| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always |

This metric is only captured when <xref:System.Net.Http.HttpClient> is configured to use the default <xref:System.Net.Http.SocketsHttpHandler>.

Available starting in: .NET 8

### Instrument: `http.client.request.duration`

| Name | Instrument Type | Unit (UCUM) | Description |
| -------- | --------------- | ----------- | -------------- |
| `http.client.request.duration` | Histogram | `s` | The duration of outbound HTTP requests. |

| Attribute | Type | Description | Examples | Presence |
|---|---|---|---|---|
| `http.error.reason` | string | Request failure reason: one of [HTTP Request errors](https://github.com/dotnet/runtime/blob/c430570a01c103bc7f117be573f37d8ce8a129b8/src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestError.cs), or a full exception type, or an HTTP 4xx/5xx status code. | `System.Threading.Tasks.TaskCanceledException`; `name_resolution_error`; `secure_connection_error` ; `404` | If request has failed. |
| `http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Always |
| `http.response.status_code` | int | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). | `200` | If one was received. |
| `network.protocol.version` | string | Version of the application layer protocol used. | `1.1`; `2` | Always |
| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always |
| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) |
| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always |

HTTP client request duration measures the time the underlying client handler takes to complete the request up to reading response headers from the network
stream. It does not include the time spent reading the response body.

Available starting in: .NET 8

### Instrument: `http.client.request.time_in_queue`

| Name | Instrument Type | Unit (UCUM) | Description |
| -------- | --------------- | ----------- | -------------- |
| `http.client.request.time_in_queue` | Histogram | `s` | The amount of time requests spent on a queue waiting for an available connection. |

| Attribute | Type | Description | Examples | Presence |
|---|---|---|---|---|
| `http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Always |
| `network.protocol.version` | string | Version of the application layer protocol used. | `1.1`; `2` | Always |
| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always |
| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) |
| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always |

<xref:System.Net.Http.HttpClient>, when configured to use the default <xref:System.Net.Http.SocketsHttpHandler>, sends HTTP requests using a pool of network connections.
If all connections are already busy handling other requests, new requests are placed in a queue and wait until a network connection is available for use. This instrument
measures the amount of time HTTP requests spend waiting in that queue, prior to anything being sent across the network.

Available starting in: .NET 8

### Instrument: `http.client.active_requests`

| Name | Instrument Type | Unit (UCUM) | Description |
| -------- | --------------- | ----------- | -------------- |
| `http.client.active_requests` | UpDownCounter | `{request}` | Number of active HTTP requests. |

| Attribute | Type | Description | Examples | Presence |
|---|---|---|---|---|
| `http.request.method` | string | HTTP request method. | `GET`; `POST`; `HEAD` | Always |
| `network.protocol.version` | string | Version of the application layer protocol used. | `1.1`; `2` | Always |
| `server.address` | string | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `example.com` | Always |
| `server.port` | int | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. | `80`; `8080`; `443` | If not default (`80` for `http` scheme, `443` for `https`) |
| `url.scheme` | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `http`; `https`; `ftp` | Always |

This metric counts how many requests are considered active. Requests are active for the same time period that is measured by the [http.client.request.duration](#instrument-httpclientrequestduration) instrument.

Available starting in: .NET 8
15 changes: 15 additions & 0 deletions docs/core/diagnostics/built-in-metrics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Built-in Metrics in .NET
description: Review the metrics built-in for the .NET runtime and libraries.
ms.topic: reference
ms.date: 9/21/2023
---

# Built-in Metrics in .NET

This is a reference for [metrics](metrics.md) built-in for .NET, produced using the
<xref:System.Diagnostics.Metrics?displayProperty=nameWithType> API. For metrics produced by [alternative metric APIs](compare-metric-apis.md)
see the [EventCounters reference](available-counters.md) and [Windows Performance Counter reference](../../framework/debug-trace-profile/performance-counters.md).

- [ASP.NET Core Metrics](built-in-metrics-aspnetcore.md)
- [System.Net Metrics](built-in-metrics-system-net.md)
17 changes: 7 additions & 10 deletions docs/core/diagnostics/compare-metric-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,18 @@ Over .NET's 20+ year history, we've iterated a few times on the design for metri
### System.Diagnostics.Metrics

[System.Diagnostics.Metrics](metrics-instrumentation.md) APIs are the newest cross-platform APIs, and were designed in close collaboration with the
[OpenTelemetry](https://opentelemetry.io/) project. The OpenTelemetry effort is an industry-wide collaboration across telemetry tooling vendors,
programming languages, and application developers to create a broadly compatible standard for telemetry APIs. To eliminate any friction associated with adding third-party dependencies, .NET embeds the metrics API directly into the base class libraries.
It's available by targeting .NET 6, or in older .NET Core and .NET Framework apps by adding a reference to the .NET
[System.Diagnostics.DiagnosticsSource](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource) 6.0 NuGet package. In addition to
aiming at broad compatibility, this API adds support for many things that were lacking from EventCounters, such as:
[OpenTelemetry](https://opentelemetry.io/) project. If you don't have a specific reason to use one of the older APIs covered below, [System.Diagnostics.Metrics](metrics-instrumentation.md) is
a good default choice for new work. It's available by targeting .NET 6+, or in older .NET Core and .NET Framework apps by adding a reference to the .NET
[System.Diagnostics.DiagnosticsSource](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource) 6.0+ NuGet package. In addition to
aiming at broad compatibility, this API adds support for many things that were lacking from earlier APIs, such as:

- Histograms and percentiles
- Multi-dimensional metrics
- Strongly typed high-performance listener API
- Multiple simultaneous listeners
- Listener access to unaggregated measurements

Although this API was designed to work well with OpenTelemetry and its growing ecosystem of pluggable vendor integration libraries, applications also have the option to use the .NET built-in listener APIs directly. With this option, you can create custom metric tooling without taking any external library dependencies. At the time of writing, the [System.Diagnostics.Metrics](xref:System.Diagnostics.Metrics) support is limited to [dotnet-counters](dotnet-counters.md) and [OpenTelemetry.NET](https://opentelemetry.io/docs/net/). However, we expect support for these APIs will grow given the active nature of the OpenTelemetry project.
Although this API was designed to work well with OpenTelemetry and its growing ecosystem of pluggable vendor integration libraries, applications also have the option to use the .NET built-in listener APIs directly. With this option, you can create custom metric tooling without taking any external library dependencies.

### PerformanceCounter

Expand All @@ -68,10 +67,8 @@ access to the aggregated values, and has limitations when using more than one li
[dotnet-counters](dotnet-counters.md), and [dotnet-monitor](https://devblogs.microsoft.com/dotnet/introducing-dotnet-monitor/). For third-party
tool support, check the vendor or project documentation to see if it's available.

At the time of writing, this is the cross-platform .NET runtime API that has the broadest and most stable ecosystem support. However, it will likely be
overtaken soon by growing support for [System.Diagnostics.Metrics](metrics-instrumentation.md). The .NET team doesn't expect to
make substantial new investments on this API going forward, but as with `PerformanceCounters`, the API remains actively supported for all
current and future users.
The .NET team doesn't expect to make substantial new investments on this API going forward, but as with `PerformanceCounters`, the API remains
actively supported for all current and future users.

## Third-party APIs

Expand Down
4 changes: 2 additions & 2 deletions docs/core/diagnostics/metrics-collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ For more information on custom metric instrumentation and options, see [Compare

## Create an example app

Before metrics can be collected, measurements must be produced. This tutorial creates an app that has basic metric instrumentation. The .NET runtime also has [various metrics built-in](available-counters.md). For more information about creating new metrics using the <xref:System.Diagnostics.Metrics.Meter?displayProperty=nameWithType> API, see [the instrumentation tutorial](metrics-instrumentation.md).
Before metrics can be collected, measurements must be produced. This tutorial creates an app that has basic metric instrumentation. The .NET runtime also has [various metrics built-in](built-in-metrics.md). For more information about creating new metrics using the <xref:System.Diagnostics.Metrics.Meter?displayProperty=nameWithType> API, see [the instrumentation tutorial](metrics-instrumentation.md).

```dotnetcli
dotnet new console -o metric-instr
Expand Down Expand Up @@ -97,7 +97,7 @@ Press p to pause, r to resume, q to quit.
Working Set (MB) 30
```

For more information, see [dotnet-counters](dotnet-counters.md). To learn more about metrics in .NET, see [built-in metrics](available-counters.md).
For more information, see [dotnet-counters](dotnet-counters.md). To learn more about metrics in .NET, see [built-in metrics](built-in-metrics.md).

## View metrics in Grafana with OpenTelemetry and Prometheus

Expand Down
2 changes: 1 addition & 1 deletion docs/core/diagnostics/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ There are two parts to using metrics in a .NET app:

- [Instrumentation tutorial](metrics-instrumentation.md) - How to create new metrics in code
- [Collection tutorial](metrics-collection.md) - How to store and view metric data for your app
- [Built-in metrics](available-counters.md) - Discover metrics that are ready for use in .NET runtime libraries
- [Built-in metrics](built-in-metrics.md) - Discover metrics that are ready for use in .NET runtime libraries
- [Compare metric APIs](compare-metric-apis.md)
- [EventCounters](event-counters.md) - Learn what EventCounters are, how to implement them, and how to consume them
8 changes: 8 additions & 0 deletions docs/navigate/tools-diagnostics/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,14 @@ items:
href: ../../core/diagnostics/metrics-instrumentation.md
- name: Collection
href: ../../core/diagnostics/metrics-collection.md
- name: Built-in Metrics
items:
- name: Overview
href: ../../core/diagnostics/built-in-metrics.md
- name: ASP.NET Core Metrics
href: ../../core/diagnostics/built-in-metrics-aspnetcore.md
- name: System.Net Metrics
href: ../../core/diagnostics/built-in-metrics-system-net.md
- name: EventCounters
items:
- name: Overview
Expand Down

0 comments on commit e91f03b

Please sign in to comment.