Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inconsistent metric usage of http.target #2818

Merged
merged 9 commits into from
Oct 3, 2022
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ release.
- Add `process.context_switches`, and `process.open_file_descriptors`, to the
metrics semantic conventions
([#2706](https://github.com/open-telemetry/opentelemetry-specification/pull/2706))
- Update http metrics to use `http.route` instead of `http.target` for servers,
drop `http.url` for clients
([#2818](https://github.com/open-telemetry/opentelemetry-specification/pull/2818)).

### Compatibility

Expand Down
48 changes: 14 additions & 34 deletions specification/metrics/semantic_conventions/http-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,20 @@ Below is a table of HTTP client metric instruments.
Below is a table of the attributes that SHOULD be included on `duration` and `size` metric events
and whether they should be on server, client, or both types of HTTP metric events:

| Name | Type | Requirement Level | Notes and examples |
|----------------------|---------------------|--------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `http.method` | `client` & `server` | Required | The HTTP request method. E.g. `"GET"` |
| `http.scheme` | `server` | Required | The URI scheme identifying the used protocol in lowercase: `"http"` or `"https"` |
| `http.status_code` | `client` & `server` | Conditionally Required: if and only if one was received/sent. | [HTTP response status code][]. E.g. `200` (String) |
| `http.flavor` | `client` & `server` | Recommended | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. |
| `net.peer.name` | `client` | Required | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. |
| `net.peer.port` | `client` | Conditionally Required: If not default (`80` for `http`, `443` for `https`). | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. |
| `net.sock.peer.addr` | `client` | Recommended | See [general network connection attributes](../../trace/semantic_conventions/span-general.md#general-network-connection-attributes) |
| `net.host.name` | `server` | Required | Host of the local HTTP server that received the request. |
| `net.host.port` | `server` | Conditionally Required: If not default (`80` for `http`, `443` for `https`). | Port of the local HTTP server that received the request. |
| Name | Type | Requirement Level | Notes and examples |
|----------------------|---------------------|------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------|
| `http.method` | `client` & `server` | Required | The HTTP request method. E.g. `"GET"` |
| `http.scheme` | `server` | Required | The URI scheme identifying the used protocol in lowercase: `"http"` or `"https"` |
| `http.route` | `server` | Conditionally Required: If and only if it's available | The matched route (path template in the format used by the respective server framework). See note below [1]. E.g. `"/path/{id}/?q={}"`. |
| `http.status_code` | `client` & `server` | Conditionally Required: if and only if one was received/sent. | [HTTP response status code][]. E.g. `200` (String) |
| `http.flavor` | `client` & `server` | Recommended | Kind of HTTP protocol used: `"1.0"`, `"1.1"`, `"2"`, `"SPDY"` or `"QUIC"`. |
| `net.peer.name` | `client` | Required | Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. |
| `net.peer.port` | `client` | Conditionally Required: If not default (`80` for `http`, `443` for `https`). | Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. |
| `net.sock.peer.addr` | `client` | Recommended | See [general network connection attributes](../../trace/semantic_conventions/span-general.md#general-network-connection-attributes) |
| `net.host.name` | `server` | Required | Host of the local HTTP server that received the request. |
| `net.host.port` | `server` | Conditionally Required: If not default (`80` for `http`, `443` for `https`). | Port of the local HTTP server that received the request. |

**[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.

The following attributes SHOULD be included in the `http.server.active_requests` observation:

Expand All @@ -67,26 +70,3 @@ The following attributes SHOULD be included in the `http.server.active_requests`
[HTTP host header]: https://www.rfc-editor.org/rfc/rfc9110.html#name-host-and-authority
[HTTP response status code]: https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes
[HTTP reason phrase]: https://www.rfc-editor.org/rfc/rfc9110.html#section-15.1

### Parameterized attributes

To avoid high cardinality the following attributes SHOULD substitute any parameters when added as attributes to http metric events as described below:

| Attribute name | Type | Requirement Level | Notes and examples |
|----------------|---------|-------------------|--------------------------------------------------------------------------------------------------------|
| `http.url` | `client` | Required | The originally requested URL |
| `http.target` | `server` | Required | The full request target as passed in a [HTTP request target][] or equivalent, e.g. `"/path/{id}/?q={}"`. |

[Http request target]: https://www.rfc-editor.org/rfc/rfc9110.html#name-determining-the-target-reso

Many REST APIs encode parameters into the URI path, e.g. `/api/users/123` where `123`
is a user id, which creates high cardinality value space not suitable for attributes on metric events.
In case of HTTP servers, these endpoints are often mapped by the server
frameworks to more concise _HTTP routes_, e.g. `/api/users/{user_id}`, which are
recommended as the low cardinality attribute values. However, the same approach usually
does not work for HTTP client attributes, especially when instrumentation is provided
by a lower-level middleware that is not aware of the specifics of how the URIs
are formed. Therefore, HTTP client attributes SHOULD be using conservative, low
cardinality names formed from the available parameters of an HTTP request,
such as `"HTTP {METHOD_NAME}"`. These attributes MUST NOT default to using URI
path.