Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ release.
([#276](https://github.com/open-telemetry/semantic-conventions/pull/276))
- Add host cpu resource attributes.
([#209](https://github.com/open-telemetry/semantic-conventions/pull/209))
- Introduce `error.type` attribute and use it in HTTP conventions
([#205](https://github.com/open-telemetry/semantic-conventions/pull/205))

## v1.21.0 (2023-07-13)

Expand Down
252 changes: 195 additions & 57 deletions docs/http/http-metrics.md

Large diffs are not rendered by default.

86 changes: 79 additions & 7 deletions docs/http/http-spans.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ and various HTTP versions like 1.1, 2 and SPDY.
* [HTTP client retries examples](#http-client-retries-examples)
* [HTTP client authorization retry examples](#http-client-authorization-retry-examples)
* [HTTP client redirects examples](#http-client-redirects-examples)
* [HTTP client call: DNS error](#http-client-call-dns-error)
* [HTTP client call: Internal Server Error](#http-client-call-internal-server-error)
* [HTTP server call: connection dropped before response body was sent](#http-server-call-connection-dropped-before-response-body-was-sent)

<!-- tocstop -->

Expand Down Expand Up @@ -88,6 +91,12 @@ failed to interpret, span status MUST be set to `Error`.

Don't set the span status description if the reason can be inferred from `http.response.status_code`.

HTTP request may fail if it was cancelled or an error occurred preventing
the client or server from sending/receiving the request/response fully.

When instrumentation detects such errors it MUST set span status to `Error`
and MUST set the `error.type` attribute.

## Common Attributes

The common attributes listed in this section apply to both HTTP clients and servers in addition to
Expand All @@ -101,16 +110,33 @@ sections below.
| `http.request.method_original` | string | Original HTTP method sent by the client in the request line. | `GeT`; `ACL`; `foo` | Conditionally Required: [1] |
| `http.request.body.size` | int | The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. | `3495` | Recommended |
| `http.response.body.size` | int | The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. | `3495` | Recommended |
| `http.request.method` | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | Required |
| `error.type` | string | Describes a class of error the operation ended with. [2] | `timeout`; `name_resolution_error`; `500` | Conditionally Required: If request has ended with an error. |
| `http.request.method` | string | HTTP request method. [3] | `GET`; `POST`; `HEAD` | Required |
| [`network.protocol.name`](../general/attributes.md) | string | [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `http`; `spdy` | Recommended: if not default (`http`). |
| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [3] | `1.0`; `1.1`; `2`; `3` | Recommended |
| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Conditionally Required: [4] |
| [`network.protocol.version`](../general/attributes.md) | string | Version of the application layer protocol used. See note below. [4] | `1.0`; `1.1`; `2`; `3` | Recommended |
| [`network.transport`](../general/attributes.md) | string | [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. | `tcp`; `udp` | Conditionally Required: [5] |
| [`network.type`](../general/attributes.md) | string | [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. | `ipv4`; `ipv6` | Recommended |
| `user_agent.original` | string | Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. | `CERN-LineMode/2.15 libwww/2.17b3` | Recommended |

**[1]:** If and only if it's different than `http.request.method`.

**[2]:** HTTP request method value SHOULD be "known" to the instrumentation.
**[2]:** If the request fails with an error before response status code was sent or received,
`error.type` SHOULD be set to exception type or a component-specific low cardinality error code.

If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md),
`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code.

The `error.type` value SHOULD be predictable and SHOULD have low cardinality.
Instrumentations SHOULD document the list of errors they report.

The cardinality of `error.type` within one instrumentation library SHOULD be low, but
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 request has completed successfully, instrumentations SHOULD NOT set `error.type`.

**[3]:** HTTP request method value SHOULD be "known" to the instrumentation.
By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)
and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).

Expand All @@ -125,14 +151,20 @@ HTTP method names are case-sensitive and `http.request.method` attribute value M
Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.
Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.

**[3]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.
**[4]:** `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.

**[4]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`).
**[5]:** If not default (`tcp` for `HTTP/1.1` and `HTTP/2`, `udp` for `HTTP/3`).

Following attributes MUST be provided **at span creation time** (when provided at all), so they can be considered for sampling decisions:

* `http.request.method`

`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 |
|---|---|
| `_OTHER` | A fallback error value to be used when the instrumentation does not define a custom value for it. |

`http.request.method` 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 |
Expand Down Expand Up @@ -412,7 +444,7 @@ Span name: `GET`
| Attribute name | Value |
| :------------------- | :-------------------------------------------------------|
| `http.request.method`| `"GET"` |
| `network.protocol.version` | `"1.1"` |
| `network.protocol.version` | `"1.1"` |
| `url.full` | `"https://example.com:8080/webshop/articles/4?s=1"` |
| `server.address` | `example.com` |
| `server.port` | 8080 |
Expand Down Expand Up @@ -530,4 +562,44 @@ GET /hello - 200 (CLIENT, trace=t2, span=s1, http.resend_count=1)
--- server (SERVER, trace=t2, span=s2)
```

### HTTP client call: DNS error

As an example, if a user requested `https://does-not-exist-123.com`, we may have the following span on the client side:

| Attribute name | Value |
| :------------------- | :-------------------------------------------------------|
| `http.request.method`| `"GET"` |
| `network.protocol.version` | `"1.1"` |
| `url.full` | `"https://does-not-exist-123.com"` |
| `server.address` | `"does-not-exist-123.com"` |
| `error.type` | `"java.net.UnknownHostException"` |

### HTTP client call: Internal Server Error

As an example, if a user requested `https://example.com` and server returned 500, we may have the following span on the client side:

| Attribute name | Value |
| :------------------- | :-------------------------------------------------------|
| `http.request.method`| `"GET"` |
| `network.protocol.version` | `"1.1"` |
| `url.full` | `"https://example.com"` |
| `server.address` | `"example.com"` |
| `http.response.status_code` | `500` |
| `error.type` | `"500"` |

### HTTP server call: connection dropped before response body was sent

As an example, if a user sent a `POST` request with a body to `https://example.com:8080/uploads/4`, we may see the following span on a server side:

Span name: `POST /uploads/:document_id`.

| Attribute name | Value |
| :------------------- | :---------------------------------------------- |
| `http.request.method`| `"GET"` |
| `url.path` | `"/uploads/4"` |
| `url.scheme` | `"https"` |
| `http.route` | `"/uploads/:document_id"` |
| `http.response.status_code` | `201` |
| `error.type` | `WebSocketDisconnect` |

[DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.22.0/specification/document-status.md
31 changes: 31 additions & 0 deletions model/error.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
groups:
- id: error
type: attribute_group
prefix: error
brief: >
This document defines the shared attributes used to
report an error.
attributes:
- id: type
brief: 'Describes a class of error the operation ended with.'
type:
allow_custom_values: true
members:
- id: other
value: "_OTHER"
brief: 'A fallback error value to be used when the instrumentation does not define a custom value for it.'
examples: ['timeout', 'java.net.UnknownHostException', 'server_certificate_invalid', '500']
note: |
The `error.type` SHOULD be predictable and SHOULD have low cardinality.
Instrumentations SHOULD document the list of errors they report.

The cardinality of `error.type` within one instrumentation library SHOULD be low, but
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 codes (such as HTTP or gRPC status codes),
it's RECOMMENDED to use a domain-specific attribute and also set `error.type` to capture
all errors, regardless of whether they are defined within the domain-specific set or not.
20 changes: 20 additions & 0 deletions model/http-common.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,26 @@ groups:
conditionally_required: If and only if one was received/sent.
brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).'
examples: [200]
- ref: error.type
requirement_level:
conditionally_required: If request has ended with an error.
examples: ['timeout', 'name_resolution_error', '500']
note: |
If the request fails with an error before response status code was sent or received,
`error.type` SHOULD be set to exception type or a component-specific low cardinality error code.

If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md),
`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code.

The `error.type` value SHOULD be predictable and SHOULD have low cardinality.
Instrumentations SHOULD document the list of errors they report.

The cardinality of `error.type` within one instrumentation library SHOULD be low, but
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 request has completed successfully, instrumentations SHOULD NOT set `error.type`.
- ref: network.protocol.name
examples: ['http', 'spdy']
requirement_level:
Expand Down
40 changes: 40 additions & 0 deletions model/metrics/http.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ groups:
if it's sent in absolute-form.
- Port identifier of the `Host` header
# todo (lmolkova) build tools don't populate grandparent attributes
- ref: error.type
requirement_level:
conditionally_required: If request has ended with an error.
examples: ['timeout', 'name_resolution_error', '500']
note: |
If the request fails with an error before response status code was sent or received,
`error.type` SHOULD be set to exception type or a component-specific low cardinality error code.

If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md),
`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code.

The `error.type` value SHOULD be predictable and SHOULD have low cardinality.
Instrumentations SHOULD document the list of errors they report.

The cardinality of `error.type` within one instrumentation library SHOULD be low, but
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 request has completed successfully, instrumentations SHOULD NOT set `error.type`.
- ref: http.request.method
- ref: http.response.status_code
- ref: network.protocol.name
Expand All @@ -47,6 +67,26 @@ groups:
- ref: network.protocol.name
- ref: network.protocol.version
- ref: server.socket.address
- ref: error.type
requirement_level:
conditionally_required: If request has ended with an error.
examples: ['timeout', 'name_resolution_error', '500']
note: |
If the request fails with an error before response status code was sent or received,
`error.type` SHOULD be set to exception type or a component-specific low cardinality error code.

If response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md),
`error.type` SHOULD be set to the string representation of the status code, an exception type (if thrown) or a component-specific error code.

The `error.type` value SHOULD be predictable and SHOULD have low cardinality.
Instrumentations SHOULD document the list of errors they report.

The cardinality of `error.type` within one instrumentation library SHOULD be low, but
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 request has completed successfully, instrumentations SHOULD NOT set `error.type`.

- id: metric.http.server.request.duration
type: metric
Expand Down