diff --git a/.chloggen/rpc-status-code.yaml b/.chloggen/rpc-status-code.yaml new file mode 100644 index 0000000000..a3e16e4bfd --- /dev/null +++ b/.chloggen/rpc-status-code.yaml @@ -0,0 +1,6 @@ +change_type: breaking +component: rpc +note: > + Deprecate `rpc.grpc.status_code`, `rpc.connect_rpc.error_code` and `rpc.jsonrpc.error_code` attributes + in favor of the more general `rpc.response.status_code` attribute. +issues: [1504, 2920] diff --git a/docs/cicd/cicd-metrics.md b/docs/cicd/cicd-metrics.md index 3a1c33d152..9dbe4efd3a 100644 --- a/docs/cicd/cicd-metrics.md +++ b/docs/cicd/cicd-metrics.md @@ -94,7 +94,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -250,7 +250,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -307,7 +307,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/cicd/cicd-spans.md b/docs/cicd/cicd-spans.md index 385d892269..fbabc491eb 100644 --- a/docs/cicd/cicd-spans.md +++ b/docs/cicd/cicd-spans.md @@ -72,7 +72,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -155,7 +155,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/cli/cli-spans.md b/docs/cli/cli-spans.md index 836c98b97c..498d4a9511 100644 --- a/docs/cli/cli-spans.md +++ b/docs/cli/cli-spans.md @@ -57,7 +57,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -123,7 +123,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/azure-messaging.md b/docs/messaging/azure-messaging.md index 194ba75693..8943e5f5b6 100644 --- a/docs/messaging/azure-messaging.md +++ b/docs/messaging/azure-messaging.md @@ -94,7 +94,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -220,7 +220,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/gcp-pubsub.md b/docs/messaging/gcp-pubsub.md index 441ea12378..91faf7c289 100644 --- a/docs/messaging/gcp-pubsub.md +++ b/docs/messaging/gcp-pubsub.md @@ -90,7 +90,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/kafka.md b/docs/messaging/kafka.md index b291f00b67..28bd5555ec 100644 --- a/docs/messaging/kafka.md +++ b/docs/messaging/kafka.md @@ -91,7 +91,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/messaging-metrics.md b/docs/messaging/messaging-metrics.md index 5ad3e76461..b0ab79a1c8 100644 --- a/docs/messaging/messaging-metrics.md +++ b/docs/messaging/messaging-metrics.md @@ -103,7 +103,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -218,7 +218,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -318,7 +318,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -425,7 +425,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/messaging-spans.md b/docs/messaging/messaging-spans.md index a27cee0eea..8478a8b7a2 100644 --- a/docs/messaging/messaging-spans.md +++ b/docs/messaging/messaging-spans.md @@ -415,7 +415,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/rabbitmq.md b/docs/messaging/rabbitmq.md index cb40b79f1f..3ccd5efbbb 100644 --- a/docs/messaging/rabbitmq.md +++ b/docs/messaging/rabbitmq.md @@ -92,7 +92,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/rocketmq.md b/docs/messaging/rocketmq.md index 1073432ef8..1c930227c7 100644 --- a/docs/messaging/rocketmq.md +++ b/docs/messaging/rocketmq.md @@ -87,7 +87,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/sns.md b/docs/messaging/sns.md index 96c61ee266..0d8fc3ee42 100644 --- a/docs/messaging/sns.md +++ b/docs/messaging/sns.md @@ -46,7 +46,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/messaging/sqs.md b/docs/messaging/sqs.md index 9d4571574b..de97f7f685 100644 --- a/docs/messaging/sqs.md +++ b/docs/messaging/sqs.md @@ -46,7 +46,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/nfs/nfs-metrics.md b/docs/nfs/nfs-metrics.md index 993591a854..e7cafe66b4 100644 --- a/docs/nfs/nfs-metrics.md +++ b/docs/nfs/nfs-metrics.md @@ -436,7 +436,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/otel/sdk-metrics.md b/docs/otel/sdk-metrics.md index b698ca5534..73c3d29eab 100644 --- a/docs/otel/sdk-metrics.md +++ b/docs/otel/sdk-metrics.md @@ -301,7 +301,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -478,7 +478,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -742,7 +742,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -919,7 +919,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -1102,7 +1102,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -1211,7 +1211,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -1301,9 +1301,9 @@ operations, `error.type` MUST NOT be set. For unsuccessful export operations, `e | [`http.response.status_code`](/docs/registry/attributes/http.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` when applicable | int | The HTTP status code of the last HTTP request performed in scope of this export call. | `200` | | [`otel.component.name`](/docs/registry/attributes/otel.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | A name uniquely identifying the instance of the OpenTelemetry component within its containing SDK instance. [2] | `otlp_grpc_span_exporter/0`; `custom-name` | | [`otel.component.type`](/docs/registry/attributes/otel.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | A name identifying the type of the OpenTelemetry component. [3] | `otlp_grpc_span_exporter`; `com.example.MySpanExporter` | -| [`rpc.grpc.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when applicable | int | The gRPC status code of the last gRPC requests performed in scope of this export call. | `0`; `1`; `2` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` when applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` when applicable | int | Server port number. [5] | `80`; `8080`; `443` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when applicable | string | The gRPC status code of the last gRPC request performed in scope of this export call. [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` when applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` when applicable | int | Server port number. [6] | `80`; `8080`; `443` | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -1319,7 +1319,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -1342,9 +1342,12 @@ These values will therefore be reused in the case of an application restart. **[3] `otel.component.type`:** If none of the standardized values apply, implementations SHOULD use the language-defined name of the type. E.g. for Java the fully qualified classname SHOULD be used in this case. -**[4] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[4] `rpc.response.status_code`:** Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual RPC frameworks SHOULD document what `rpc.response.status_code` means in the context of that system and which values are considered to represent errors. -**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[5] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[6] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. --- @@ -1377,30 +1380,6 @@ E.g. for Java the fully qualified classname SHOULD be used in this case. | `simple_span_processor` | The builtin SDK simple span processor | ![Development](https://img.shields.io/badge/-development-blue) | | `zipkin_http_span_exporter` | Zipkin span exporter over HTTP | ![Development](https://img.shields.io/badge/-development-blue) | ---- - -`rpc.grpc.status_code` 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 | -|---|---|---| -| `0` | OK | ![Development](https://img.shields.io/badge/-development-blue) | -| `1` | CANCELLED | ![Development](https://img.shields.io/badge/-development-blue) | -| `2` | UNKNOWN | ![Development](https://img.shields.io/badge/-development-blue) | -| `3` | INVALID_ARGUMENT | ![Development](https://img.shields.io/badge/-development-blue) | -| `4` | DEADLINE_EXCEEDED | ![Development](https://img.shields.io/badge/-development-blue) | -| `5` | NOT_FOUND | ![Development](https://img.shields.io/badge/-development-blue) | -| `6` | ALREADY_EXISTS | ![Development](https://img.shields.io/badge/-development-blue) | -| `7` | PERMISSION_DENIED | ![Development](https://img.shields.io/badge/-development-blue) | -| `8` | RESOURCE_EXHAUSTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `9` | FAILED_PRECONDITION | ![Development](https://img.shields.io/badge/-development-blue) | -| `10` | ABORTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `11` | OUT_OF_RANGE | ![Development](https://img.shields.io/badge/-development-blue) | -| `12` | UNIMPLEMENTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `13` | INTERNAL | ![Development](https://img.shields.io/badge/-development-blue) | -| `14` | UNAVAILABLE | ![Development](https://img.shields.io/badge/-development-blue) | -| `15` | DATA_LOSS | ![Development](https://img.shields.io/badge/-development-blue) | -| `16` | UNAUTHENTICATED | ![Development](https://img.shields.io/badge/-development-blue) | - diff --git a/docs/registry/attributes/error.md b/docs/registry/attributes/error.md index 91adcc5897..2a28acdc80 100644 --- a/docs/registry/attributes/error.md +++ b/docs/registry/attributes/error.md @@ -34,7 +34,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/registry/attributes/rpc.md b/docs/registry/attributes/rpc.md index 3a917a9092..1fa2ff42fb 100644 --- a/docs/registry/attributes/rpc.md +++ b/docs/registry/attributes/rpc.md @@ -14,14 +14,10 @@ This document defines attributes for remote procedure calls. | Key | Stability | Value Type | Description | Example Values | |---|---|---|---|---| -| `rpc.connect_rpc.error_code` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [error codes](https://connectrpc.com//docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled`; `unknown`; `invalid_argument` | | `rpc.connect_rpc.request.metadata.` | ![Development](https://img.shields.io/badge/-development-blue) | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [1] | `["1.2.3.4", "1.2.3.5"]` | | `rpc.connect_rpc.response.metadata.` | ![Development](https://img.shields.io/badge/-development-blue) | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [2] | `["attribute_value"]` | | `rpc.grpc.request.metadata.` | ![Development](https://img.shields.io/badge/-development-blue) | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [3] | `["1.2.3.4", "1.2.3.5"]` | | `rpc.grpc.response.metadata.` | ![Development](https://img.shields.io/badge/-development-blue) | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [4] | `["attribute_value"]` | -| `rpc.grpc.status_code` | ![Development](https://img.shields.io/badge/-development-blue) | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `2` | -| `rpc.jsonrpc.error_code` | ![Development](https://img.shields.io/badge/-development-blue) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| `rpc.jsonrpc.error_message` | ![Development](https://img.shields.io/badge/-development-blue) | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | | `rpc.jsonrpc.request_id` | ![Development](https://img.shields.io/badge/-development-blue) | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | | `rpc.jsonrpc.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | | `rpc.message.compressed_size` | ![Development](https://img.shields.io/badge/-development-blue) | int | Compressed size of the message in bytes. | | @@ -29,6 +25,7 @@ This document defines attributes for remote procedure calls. | `rpc.message.type` | ![Development](https://img.shields.io/badge/-development-blue) | string | Whether this is a received or sent message. | `SENT`; `RECEIVED` | | `rpc.message.uncompressed_size` | ![Development](https://img.shields.io/badge/-development-blue) | int | Uncompressed size of the message in bytes. | | | `rpc.method` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is the logical name of the method from the RPC interface perspective. | `exampleMethod` | +| `rpc.response.status_code` | ![Development](https://img.shields.io/badge/-development-blue) | string | Status code of the RPC returned by the RPC server or generated by the client [6] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | | `rpc.service` | ![Development](https://img.shields.io/badge/-development-blue) | string | The full (logical) name of the service being called, including its package name, if applicable. | `myservice.EchoService` | | `rpc.system` | ![Development](https://img.shields.io/badge/-development-blue) | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc`; `java_rmi`; `dotnet_wcf` | @@ -58,6 +55,58 @@ the `rpc.grpc.response.metadata.my-custom-key` attribute with value `["attribute **[5] `rpc.message.id`:** This way we guarantee that the values will be consistent between different implementations. +**[6] `rpc.response.status_code`:** Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual RPC frameworks SHOULD document what `rpc.response.status_code` means in the context of that system and which values are considered to represent errors. + +--- + +`rpc.message.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 | +|---|---|---| +| `RECEIVED` | received | ![Development](https://img.shields.io/badge/-development-blue) | +| `SENT` | sent | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + +`rpc.system` 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 | +|---|---|---| +| `apache_dubbo` | Apache Dubbo | ![Development](https://img.shields.io/badge/-development-blue) | +| `connect_rpc` | Connect RPC | ![Development](https://img.shields.io/badge/-development-blue) | +| `dotnet_wcf` | .NET WCF | ![Development](https://img.shields.io/badge/-development-blue) | +| `grpc` | gRPC | ![Development](https://img.shields.io/badge/-development-blue) | +| `java_rmi` | Java RMI | ![Development](https://img.shields.io/badge/-development-blue) | +| `jsonrpc` | JSON-RPC | ![Development](https://img.shields.io/badge/-development-blue) | +| `onc_rpc` | [ONC RPC (Sun RPC)](https://datatracker.ietf.org/doc/html/rfc5531) | ![Development](https://img.shields.io/badge/-development-blue) | + +## Deprecated RPC Attributes + +Deprecated rpc message attributes. + +**Attributes:** + +| Key | Stability | Value Type | Description | Example Values | +|---|---|---|---|---| +| `message.compressed_size` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.compressed_size`. | int | Deprecated, use `rpc.message.compressed_size` instead. | | +| `message.id` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.id`. | int | Deprecated, use `rpc.message.id` instead. | | +| `message.type` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.type`. | string | Deprecated, use `rpc.message.type` instead. | `SENT`; `RECEIVED` | +| `message.uncompressed_size` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.uncompressed_size`. | int | Deprecated, use `rpc.message.uncompressed_size` instead. | | +| `rpc.connect_rpc.error_code` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.response.status_code`. | string | Deprecated, use `rpc.response.status_code` attribute instead. | `cancelled`; `unknown`; `invalid_argument` | +| `rpc.grpc.status_code` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the gRPC status code on the `rpc.response.status_code` attribute. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `0`; `1`; `2` | +| `rpc.jsonrpc.error_code` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | +| `rpc.jsonrpc.error_message` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use the span status description or `error.message` attribute on other signals. | string | Deprecated, use span status description or `error.message` attribute on other signals. | `Parse error`; `User already exists` | + +--- + +`message.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 | +|---|---|---| +| `RECEIVED` | received | ![Development](https://img.shields.io/badge/-development-blue) | +| `SENT` | sent | ![Development](https://img.shields.io/badge/-development-blue) | + --- `rpc.connect_rpc.error_code` 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. @@ -104,48 +153,3 @@ the `rpc.grpc.response.metadata.my-custom-key` attribute with value `["attribute | `14` | UNAVAILABLE | ![Development](https://img.shields.io/badge/-development-blue) | | `15` | DATA_LOSS | ![Development](https://img.shields.io/badge/-development-blue) | | `16` | UNAUTHENTICATED | ![Development](https://img.shields.io/badge/-development-blue) | - ---- - -`rpc.message.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 | -|---|---|---| -| `RECEIVED` | received | ![Development](https://img.shields.io/badge/-development-blue) | -| `SENT` | sent | ![Development](https://img.shields.io/badge/-development-blue) | - ---- - -`rpc.system` 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 | -|---|---|---| -| `apache_dubbo` | Apache Dubbo | ![Development](https://img.shields.io/badge/-development-blue) | -| `connect_rpc` | Connect RPC | ![Development](https://img.shields.io/badge/-development-blue) | -| `dotnet_wcf` | .NET WCF | ![Development](https://img.shields.io/badge/-development-blue) | -| `grpc` | gRPC | ![Development](https://img.shields.io/badge/-development-blue) | -| `java_rmi` | Java RMI | ![Development](https://img.shields.io/badge/-development-blue) | -| `jsonrpc` | JSON-RPC | ![Development](https://img.shields.io/badge/-development-blue) | -| `onc_rpc` | [ONC RPC (Sun RPC)](https://datatracker.ietf.org/doc/html/rfc5531) | ![Development](https://img.shields.io/badge/-development-blue) | - -## Deprecated RPC Attributes - -Deprecated rpc message attributes. - -**Attributes:** - -| Key | Stability | Value Type | Description | Example Values | -|---|---|---|---|---| -| `message.compressed_size` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.compressed_size`. | int | Deprecated, use `rpc.message.compressed_size` instead. | | -| `message.id` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.id`. | int | Deprecated, use `rpc.message.id` instead. | | -| `message.type` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.type`. | string | Deprecated, use `rpc.message.type` instead. | `SENT`; `RECEIVED` | -| `message.uncompressed_size` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `rpc.message.uncompressed_size`. | int | Deprecated, use `rpc.message.uncompressed_size` instead. | | - ---- - -`message.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 | -|---|---|---| -| `RECEIVED` | received | ![Development](https://img.shields.io/badge/-development-blue) | -| `SENT` | sent | ![Development](https://img.shields.io/badge/-development-blue) | diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md index c4eae18db9..aca818d3c2 100644 --- a/docs/rpc/connect-rpc.md +++ b/docs/rpc/connect-rpc.md @@ -29,73 +29,70 @@ This span represents an outgoing Remote Procedure Call (RPC). **Span kind** MUST be `CLIENT`. -**Span status** SHOULD follow the [Recording Errors](/docs/general/recording-errors.md) document. +**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) +document for details on how to record span status. **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`rpc.connect_rpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` if available. | string | The [error codes](https://connectrpc.com//docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled`; `unknown`; `invalid_argument` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [3] | int | Server port number. [4] | `80`; `8080`; `443` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` if available. | string | The [error code](https://connectrpc.com//docs/protocol/#error-codes) of the Connect response. [3] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [4] | int | Server port number. [5] | `80`; `8080`; `443` | | [`network.peer.address`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | [`network.peer.port`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `http` | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [6] | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [7] | `tcp`; `udp` | -| [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [8] | `exampleMethod` | -| [`rpc.service`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [9] | `myservice.EchoService` | -| [`rpc.connect_rpc.request.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [10] | `["1.2.3.4", "1.2.3.5"]` | -| [`rpc.connect_rpc.response.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [11] | `["attribute_value"]` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [6] | `http` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [7] | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | +| [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [9] | `exampleMethod` | +| [`rpc.service`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [10] | `myservice.EchoService` | +| [`rpc.connect_rpc.request.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [11] | `["1.2.3.4", "1.2.3.5"]` | +| [`rpc.connect_rpc.response.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [12] | `["attribute_value"]` | **[1] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[2] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2] `error.type`:** If the RPC fails with an error before status code is returned, +`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) +or a component-specific, low cardinality error identifier. -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. +If a response status code is returned and status indicates an error, +`error.type` SHOULD be set to that status code. Check system-specific conventions +for the details on which values of `rpc.response.status_code` are considered errors. +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. -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`. -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. +**[3] `rpc.response.status_code`:** All error codes except `OK` SHOULD be considered errors. -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: +**[4] `server.port`:** if the port is supported by the network transport used for communication. -- 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. +**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[3] `server.port`:** if the port is supported by the network transport used for communication. +**[6] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[5] `network.protocol.name`:** The value SHOULD be normalized to lowercase. - -**[6] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. - -**[7] `network.transport`:** The value SHOULD be normalized to lowercase. +**[8] `network.transport`:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[8] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). +**[9] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). -**[9] `rpc.service`:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). +**[10] `rpc.service`:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). -**[10] `rpc.connect_rpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +**[11] `rpc.connect_rpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. For example, a property `my-custom-key` with value `["1.2.3.4", "1.2.3.5"]` SHOULD be recorded as the `rpc.connect_rpc.request.metadata.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]` -**[11] `rpc.connect_rpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +**[12] `rpc.connect_rpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. For example, a property `my-custom-key` with value `"attribute_value"` SHOULD be recorded as @@ -121,29 +118,6 @@ the `rpc.connect_rpc.response.metadata.my-custom-key` attribute with value `["at | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ---- - -`rpc.connect_rpc.error_code` 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` | aborted | ![Development](https://img.shields.io/badge/-development-blue) | -| `already_exists` | already_exists | ![Development](https://img.shields.io/badge/-development-blue) | -| `cancelled` | cancelled | ![Development](https://img.shields.io/badge/-development-blue) | -| `data_loss` | data_loss | ![Development](https://img.shields.io/badge/-development-blue) | -| `deadline_exceeded` | deadline_exceeded | ![Development](https://img.shields.io/badge/-development-blue) | -| `failed_precondition` | failed_precondition | ![Development](https://img.shields.io/badge/-development-blue) | -| `internal` | internal | ![Development](https://img.shields.io/badge/-development-blue) | -| `invalid_argument` | invalid_argument | ![Development](https://img.shields.io/badge/-development-blue) | -| `not_found` | not_found | ![Development](https://img.shields.io/badge/-development-blue) | -| `out_of_range` | out_of_range | ![Development](https://img.shields.io/badge/-development-blue) | -| `permission_denied` | permission_denied | ![Development](https://img.shields.io/badge/-development-blue) | -| `resource_exhausted` | resource_exhausted | ![Development](https://img.shields.io/badge/-development-blue) | -| `unauthenticated` | unauthenticated | ![Development](https://img.shields.io/badge/-development-blue) | -| `unavailable` | unavailable | ![Development](https://img.shields.io/badge/-development-blue) | -| `unimplemented` | unimplemented | ![Development](https://img.shields.io/badge/-development-blue) | -| `unknown` | unknown | ![Development](https://img.shields.io/badge/-development-blue) | - @@ -168,79 +142,83 @@ This span represents an incoming Remote Procedure Call (RPC). **Span kind** MUST be `SERVER`. -**Span status** SHOULD follow the [Recording Errors](/docs/general/recording-errors.md) document. +**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) +document for details on how to record span status. **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`rpc.connect_rpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` if available. | string | The [error codes](https://connectrpc.com//docs/protocol/#error-codes) of the Connect request. Error codes are always string values. | `cancelled`; `unknown`; `invalid_argument` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [3] | int | Server port number. [4] | `80`; `8080`; `443` | -| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | Client port number. [6] | `65123` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` if available. | string | The [error code](https://connectrpc.com//docs/protocol/#error-codes) of the Connect response. [3] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [4] | int | Server port number. [5] | `80`; `8080`; `443` | +| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | Client port number. [7] | `65123` | | [`network.peer.address`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | [`network.peer.port`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http` | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [8] | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [9] | `tcp`; `udp` | -| [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [10] | `exampleMethod` | -| [`rpc.service`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [11] | `myservice.EchoService` | -| [`rpc.connect_rpc.request.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [12] | `["1.2.3.4", "1.2.3.5"]` | -| [`rpc.connect_rpc.response.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [13] | `["attribute_value"]` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [8] | `http` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [9] | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [10] | `tcp`; `udp` | +| [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [11] | `exampleMethod` | +| [`rpc.service`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [12] | `myservice.EchoService` | +| [`rpc.connect_rpc.request.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | Connect request metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [13] | `["1.2.3.4", "1.2.3.5"]` | +| [`rpc.connect_rpc.response.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | Connect response metadata, `` being the normalized Connect Metadata key (lowercase), the value being the metadata values. [14] | `["attribute_value"]` | **[1] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[2] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2] `error.type`:** If the RPC fails with an error before status code is returned, +`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) +or a component-specific, low cardinality error identifier. -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. +If a response status code is returned and status indicates an error, +`error.type` SHOULD be set to that status code. Check system-specific conventions +for the details on which values of `rpc.response.status_code` are considered errors. +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. -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`. -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. +**[3] `rpc.response.status_code`:** The following error codes SHOULD be considered errors: -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: +- `unknown` +- `deadline_exceeded` +- `unimplemented` +- `internal` +- `unavailable` +- `data_loss` -- 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. +**[4] `server.port`:** if the port is supported by the network transport used for communication. -**[3] `server.port`:** if the port is supported by the network transport used for communication. +**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[6] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[5] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[7] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[6] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[8] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[7] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[9] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[8] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. - -**[9] `network.transport`:** The value SHOULD be normalized to lowercase. +**[10] `network.transport`:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[10] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). +**[11] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). -**[11] `rpc.service`:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). +**[12] `rpc.service`:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). -**[12] `rpc.connect_rpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +**[13] `rpc.connect_rpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. For example, a property `my-custom-key` with value `["1.2.3.4", "1.2.3.5"]` SHOULD be recorded as the `rpc.connect_rpc.request.metadata.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]` -**[13] `rpc.connect_rpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +**[14] `rpc.connect_rpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. For example, a property `my-custom-key` with value `"attribute_value"` SHOULD be recorded as @@ -266,29 +244,6 @@ the `rpc.connect_rpc.response.metadata.my-custom-key` attribute with value `["at | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ---- - -`rpc.connect_rpc.error_code` 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` | aborted | ![Development](https://img.shields.io/badge/-development-blue) | -| `already_exists` | already_exists | ![Development](https://img.shields.io/badge/-development-blue) | -| `cancelled` | cancelled | ![Development](https://img.shields.io/badge/-development-blue) | -| `data_loss` | data_loss | ![Development](https://img.shields.io/badge/-development-blue) | -| `deadline_exceeded` | deadline_exceeded | ![Development](https://img.shields.io/badge/-development-blue) | -| `failed_precondition` | failed_precondition | ![Development](https://img.shields.io/badge/-development-blue) | -| `internal` | internal | ![Development](https://img.shields.io/badge/-development-blue) | -| `invalid_argument` | invalid_argument | ![Development](https://img.shields.io/badge/-development-blue) | -| `not_found` | not_found | ![Development](https://img.shields.io/badge/-development-blue) | -| `out_of_range` | out_of_range | ![Development](https://img.shields.io/badge/-development-blue) | -| `permission_denied` | permission_denied | ![Development](https://img.shields.io/badge/-development-blue) | -| `resource_exhausted` | resource_exhausted | ![Development](https://img.shields.io/badge/-development-blue) | -| `unauthenticated` | unauthenticated | ![Development](https://img.shields.io/badge/-development-blue) | -| `unavailable` | unavailable | ![Development](https://img.shields.io/badge/-development-blue) | -| `unimplemented` | unimplemented | ![Development](https://img.shields.io/badge/-development-blue) | -| `unknown` | unknown | ![Development](https://img.shields.io/badge/-development-blue) | - diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md index 33c438dcef..b6e29a2ae3 100644 --- a/docs/rpc/grpc.md +++ b/docs/rpc/grpc.md @@ -29,73 +29,71 @@ This span represents an outgoing Remote Procedure Call (RPC). **Span kind** MUST be `CLIENT`. -**Span status** Should be set based on the grpc status code. A mapping is defined in the [grpc status](/docs/rpc/grpc.md#grpc-status) section. +**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) +document for details on how to record span status. See also `rpc.response.status_code` attribute +for the details on which values classify as errors. **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| -| [`rpc.grpc.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `2` | | [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | This is the logical name of the method from the RPC interface perspective. [1] | `exampleMethod` | -| [`rpc.service`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The full (logical) name of the service being called, including its package name, if applicable. [2] | `myservice.EchoService` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [4] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [5] | int | Server port number. [6] | `80`; `8080`; `443` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The string representation of the [status code](https://github.com/grpc/grpc/blob/v1.75.0/doc/statuscodes.md) returned by the server or generated by the client. [2] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`rpc.service`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The full (logical) name of the service being called, including its package name, if applicable. [3] | `myservice.EchoService` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [5] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [6] | int | Server port number. [7] | `80`; `8080`; `443` | | [`network.peer.address`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | [`network.peer.port`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http` | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [8] | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [9] | `tcp`; `udp` | -| [`rpc.grpc.request.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [10] | `["1.2.3.4", "1.2.3.5"]` | -| [`rpc.grpc.response.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [11] | `["attribute_value"]` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [8] | `http` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [9] | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [10] | `tcp`; `udp` | +| [`rpc.grpc.request.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [11] | `["1.2.3.4", "1.2.3.5"]` | +| [`rpc.grpc.response.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [12] | `["attribute_value"]` | **[1] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). -**[2] `rpc.service`:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). +**[2] `rpc.response.status_code`:** All status codes except `OK` SHOULD be considered errors. -**[3] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. +**[3] `rpc.service`:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). -**[4] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[4] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -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. +**[5] `error.type`:** If the RPC fails with an error before status code is returned, +`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) +or a component-specific, low cardinality error identifier. -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 a response status code is returned and status indicates an error, +`error.type` SHOULD be set to that status code. Check system-specific conventions +for the details on which values of `rpc.response.status_code` are considered errors. -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: +The `error.type` value SHOULD be predictable and SHOULD have low cardinality. +Instrumentations SHOULD document the list of errors they report. -- 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. +If the request has completed successfully, instrumentations SHOULD NOT set +`error.type`. -**[5] `server.port`:** if the port is supported by the network transport used for communication. +**[6] `server.port`:** if the port is supported by the network transport used for communication. -**[6] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[7] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[8] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[8] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[9] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[9] `network.transport`:** The value SHOULD be normalized to lowercase. +**[10] `network.transport`:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[10] `rpc.grpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +**[11] `rpc.grpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. For example, a property `my-custom-key` with value `["1.2.3.4", "1.2.3.5"]` SHOULD be recorded as `rpc.grpc.request.metadata.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]` -**[11] `rpc.grpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +**[12] `rpc.grpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. For example, a property `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as @@ -121,30 +119,6 @@ the `rpc.grpc.response.metadata.my-custom-key` attribute with value `["attribute | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ---- - -`rpc.grpc.status_code` 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 | -|---|---|---| -| `0` | OK | ![Development](https://img.shields.io/badge/-development-blue) | -| `1` | CANCELLED | ![Development](https://img.shields.io/badge/-development-blue) | -| `2` | UNKNOWN | ![Development](https://img.shields.io/badge/-development-blue) | -| `3` | INVALID_ARGUMENT | ![Development](https://img.shields.io/badge/-development-blue) | -| `4` | DEADLINE_EXCEEDED | ![Development](https://img.shields.io/badge/-development-blue) | -| `5` | NOT_FOUND | ![Development](https://img.shields.io/badge/-development-blue) | -| `6` | ALREADY_EXISTS | ![Development](https://img.shields.io/badge/-development-blue) | -| `7` | PERMISSION_DENIED | ![Development](https://img.shields.io/badge/-development-blue) | -| `8` | RESOURCE_EXHAUSTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `9` | FAILED_PRECONDITION | ![Development](https://img.shields.io/badge/-development-blue) | -| `10` | ABORTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `11` | OUT_OF_RANGE | ![Development](https://img.shields.io/badge/-development-blue) | -| `12` | UNIMPLEMENTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `13` | INTERNAL | ![Development](https://img.shields.io/badge/-development-blue) | -| `14` | UNAVAILABLE | ![Development](https://img.shields.io/badge/-development-blue) | -| `15` | DATA_LOSS | ![Development](https://img.shields.io/badge/-development-blue) | -| `16` | UNAUTHENTICATED | ![Development](https://img.shields.io/badge/-development-blue) | - @@ -169,79 +143,84 @@ This span represents an incoming Remote Procedure Call (RPC). **Span kind** MUST be `SERVER`. -**Span status** Should be set based on the grpc status code. A mapping is defined in the [grpc status](/docs/rpc/grpc.md#grpc-status) section. +**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) +document for details on how to record span status. See also `rpc.response.status_code` attribute +for the details on which values classify as errors. **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| -| [`rpc.grpc.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | int | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. | `0`; `1`; `2` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [3] | int | Server port number. [4] | `80`; `8080`; `443` | -| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | Client port number. [6] | `65123` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The string representation of the [status code](https://github.com/grpc/grpc/blob/v1.75.0/doc/statuscodes.md) returned by the server. [1] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [3] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [4] | int | Server port number. [5] | `80`; `8080`; `443` | +| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | Client port number. [7] | `65123` | | [`network.peer.address`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | [`network.peer.port`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http` | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [8] | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [9] | `tcp`; `udp` | -| [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [10] | `exampleMethod` | -| [`rpc.service`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [11] | `myservice.EchoService` | -| [`rpc.grpc.request.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [12] | `["1.2.3.4", "1.2.3.5"]` | -| [`rpc.grpc.response.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [13] | `["attribute_value"]` | - -**[1] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. - -**[2] `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. - +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [8] | `http` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [9] | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [10] | `tcp`; `udp` | +| [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [11] | `exampleMethod` | +| [`rpc.service`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [12] | `myservice.EchoService` | +| [`rpc.grpc.request.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | gRPC request metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [13] | `["1.2.3.4", "1.2.3.5"]` | +| [`rpc.grpc.response.metadata.`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string[] | gRPC response metadata, `` being the normalized gRPC Metadata key (lowercase), the value being the metadata values. [14] | `["attribute_value"]` | + +**[1] `rpc.response.status_code`:** The following status codes SHOULD be considered errors: + +- `UNKNOWN` +- `DEADLINE_EXCEEDED` +- `UNIMPLEMENTED` +- `INTERNAL` +- `UNAVAILABLE` +- `DATA_LOSS` + +**[2] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. + +**[3] `error.type`:** If the RPC fails with an error before status code is returned, +`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) +or a component-specific, low cardinality error identifier. + +If a response status code is returned and status indicates an error, +`error.type` SHOULD be set to that status code. Check system-specific conventions +for the details on which values of `rpc.response.status_code` are considered errors. + +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. -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`. -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. +**[4] `server.port`:** if the port is supported by the network transport used for communication. -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: +**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -- 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. +**[6] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[3] `server.port`:** if the port is supported by the network transport used for communication. +**[7] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[8] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[5] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[9] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[6] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. - -**[7] `network.protocol.name`:** The value SHOULD be normalized to lowercase. - -**[8] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. - -**[9] `network.transport`:** The value SHOULD be normalized to lowercase. +**[10] `network.transport`:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example different processes could be listening on TCP port 12345 and UDP port 12345. -**[10] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). +**[11] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). -**[11] `rpc.service`:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). +**[12] `rpc.service`:** This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). -**[12] `rpc.grpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +**[13] `rpc.grpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. For example, a property `my-custom-key` with value `["1.2.3.4", "1.2.3.5"]` SHOULD be recorded as `rpc.grpc.request.metadata.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]` -**[13] `rpc.grpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +**[14] `rpc.grpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. For example, a property `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as @@ -267,61 +246,9 @@ the `rpc.grpc.response.metadata.my-custom-key` attribute with value `["attribute | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | ---- - -`rpc.grpc.status_code` 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 | -|---|---|---| -| `0` | OK | ![Development](https://img.shields.io/badge/-development-blue) | -| `1` | CANCELLED | ![Development](https://img.shields.io/badge/-development-blue) | -| `2` | UNKNOWN | ![Development](https://img.shields.io/badge/-development-blue) | -| `3` | INVALID_ARGUMENT | ![Development](https://img.shields.io/badge/-development-blue) | -| `4` | DEADLINE_EXCEEDED | ![Development](https://img.shields.io/badge/-development-blue) | -| `5` | NOT_FOUND | ![Development](https://img.shields.io/badge/-development-blue) | -| `6` | ALREADY_EXISTS | ![Development](https://img.shields.io/badge/-development-blue) | -| `7` | PERMISSION_DENIED | ![Development](https://img.shields.io/badge/-development-blue) | -| `8` | RESOURCE_EXHAUSTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `9` | FAILED_PRECONDITION | ![Development](https://img.shields.io/badge/-development-blue) | -| `10` | ABORTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `11` | OUT_OF_RANGE | ![Development](https://img.shields.io/badge/-development-blue) | -| `12` | UNIMPLEMENTED | ![Development](https://img.shields.io/badge/-development-blue) | -| `13` | INTERNAL | ![Development](https://img.shields.io/badge/-development-blue) | -| `14` | UNAVAILABLE | ![Development](https://img.shields.io/badge/-development-blue) | -| `15` | DATA_LOSS | ![Development](https://img.shields.io/badge/-development-blue) | -| `16` | UNAUTHENTICATED | ![Development](https://img.shields.io/badge/-development-blue) | - -## gRPC Status - -The table below describes when -the [Span Status](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.50.0/specification/trace/api.md#set-status) MUST be set -to `Error` or remain unset -depending on the [gRPC status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) -and [Span Kind](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.50.0/specification/trace/api.md#spankind). - -| gRPC Status Code | `SpanKind.SERVER` Span Status | `SpanKind.CLIENT` Span Status | -|---|---|---| -| OK | unset | unset | -| CANCELLED | unset | `Error` | -| UNKNOWN | `Error` | `Error` | -| INVALID_ARGUMENT | unset | `Error` | -| DEADLINE_EXCEEDED | `Error` | `Error` | -| NOT_FOUND | unset | `Error` | -| ALREADY_EXISTS | unset | `Error` | -| PERMISSION_DENIED | unset | `Error` | -| RESOURCE_EXHAUSTED | unset| `Error` | -| FAILED_PRECONDITION | unset | `Error` | -| ABORTED | unset | `Error` | -| OUT_OF_RANGE | unset | `Error` | -| UNIMPLEMENTED | `Error` | `Error` | -| INTERNAL | `Error` | `Error` | -| UNAVAILABLE | `Error` | `Error` | -| DATA_LOSS | `Error` | `Error` | -| UNAUTHENTICATED | unset | `Error` | - [DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md index 0cf242cb75..3faf193c80 100644 --- a/docs/rpc/json-rpc.md +++ b/docs/rpc/json-rpc.md @@ -29,7 +29,10 @@ This span represents an outgoing Remote Procedure Call (RPC). **Span kind** MUST be `CLIENT`. -**Span status** SHOULD follow the [Recording Errors](/docs/general/recording-errors.md) document. +**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) +document for details on how to record span status. Responses that include +[`error` object](https://www.jsonrpc.org/specification#error_object) +are considered errors. **Attributes:** @@ -37,51 +40,46 @@ This span represents an outgoing Remote Procedure Call (RPC). |---|---|---|---|---|---| | [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | This is the logical name of the method from the RPC interface perspective. [1] | `exampleMethod` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` when available | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [3] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If other than the default version (`1.0`) | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [4] | int | Server port number. [5] | `80`; `8080`; `443` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` when available | string | The [`error.code`](https://www.jsonrpc.org/specification#error_object) property of response if it is an error response recorded as a string. [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [5] | int | Server port number. [6] | `80`; `8080`; `443` | | [`network.peer.address`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | [`network.peer.port`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [6] | `http` | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [7] | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [8] | `tcp`; `udp` | -| [`rpc.jsonrpc.error_message`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [8] | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [9] | `tcp`; `udp` | | [`rpc.jsonrpc.request_id`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | **[1] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). **[2] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[3] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[3] `error.type`:** If the RPC fails with an error before status code is returned, +`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) +or a component-specific, low cardinality error identifier. -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. +If a response status code is returned and status indicates an error, +`error.type` SHOULD be set to that status code. Check system-specific conventions +for the details on which values of `rpc.response.status_code` are considered errors. +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. -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`. -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. +**[4] `rpc.response.status_code`:** All JSON RPC error codes SHOULD be considered errors. -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: +**[5] `server.port`:** if the port is supported by the network transport used for communication. -- 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. +**[6] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[4] `server.port`:** if the port is supported by the network transport used for communication. +**[7] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[8] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[6] `network.protocol.name`:** The value SHOULD be normalized to lowercase. - -**[7] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. - -**[8] `network.transport`:** The value SHOULD be normalized to lowercase. +**[9] `network.transport`:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example @@ -131,7 +129,10 @@ This span represents an incoming Remote Procedure Call (RPC). **Span kind** MUST be `SERVER`. -**Span status** SHOULD follow the [Recording Errors](/docs/general/recording-errors.md) document. +**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) +document for details on how to record span status. Responses that include +[`error` object](https://www.jsonrpc.org/specification#error_object) +are considered errors. **Attributes:** @@ -139,57 +140,52 @@ This span represents an incoming Remote Procedure Call (RPC). |---|---|---|---|---|---| | [`rpc.method`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | This is the logical name of the method from the RPC interface perspective. [1] | `exampleMethod` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` when available | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [3] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If other than the default version (`1.0`) | string | Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. | `2.0`; `1.0` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [4] | int | Server port number. [5] | `80`; `8080`; `443` | -| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | Client port number. [7] | `65123` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` when available | string | The [`error.code`](https://www.jsonrpc.org/specification#error_object) property of response recorded as a string. [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [5] | int | Server port number. [6] | `80`; `8080`; `443` | +| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [7] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | Client port number. [8] | `65123` | | [`network.peer.address`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | [`network.peer.port`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [8] | `http` | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [9] | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [10] | `tcp`; `udp` | -| [`rpc.jsonrpc.error_message`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | `error.message` property of response if it is an error response. | `Parse error`; `User already exists` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [9] | `http` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The actual version of the protocol used for network communication. [10] | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [11] | `tcp`; `udp` | | [`rpc.jsonrpc.request_id`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. | `10`; `request-7`; `` | **[1] `rpc.method`:** This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function.name` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). **[2] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[3] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[3] `error.type`:** If the RPC fails with an error before status code is returned, +`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) +or a component-specific, low cardinality error identifier. -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. +If a response status code is returned and status indicates an error, +`error.type` SHOULD be set to that status code. Check system-specific conventions +for the details on which values of `rpc.response.status_code` are considered errors. +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. -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: +If the request has completed successfully, instrumentations SHOULD NOT set +`error.type`. -- 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. +**[4] `rpc.response.status_code`:** All JSON RPC error codes SHOULD be considered errors. -**[4] `server.port`:** if the port is supported by the network transport used for communication. +**[5] `server.port`:** if the port is supported by the network transport used for communication. -**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[6] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[6] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[7] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[7] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[8] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[8] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[9] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[9] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +**[10] `network.protocol.version`:** If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -**[10] `network.transport`:** The value SHOULD be normalized to lowercase. +**[11] `network.transport`:** The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port number, since a port number is ambiguous without knowing the transport. For example diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md index a65b7dc0e9..ff59f45cf6 100644 --- a/docs/rpc/rpc-metrics.md +++ b/docs/rpc/rpc-metrics.md @@ -111,7 +111,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -211,7 +211,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -311,7 +311,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -421,7 +421,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -525,7 +525,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -629,7 +629,7 @@ 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), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md index 5ceb59f66d..bf7dd3aea6 100644 --- a/docs/rpc/rpc-spans.md +++ b/docs/rpc/rpc-spans.md @@ -101,7 +101,8 @@ This span represents an outgoing Remote Procedure Call (RPC). **Span kind** MUST be `CLIENT`. -**Span status** SHOULD follow the [Recording Errors](/docs/general/recording-errors.md) document. +**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) +document for details on how to record span status. **Attributes:** @@ -109,7 +110,7 @@ This span represents an outgoing Remote Procedure Call (RPC). |---|---|---|---|---|---| | [`rpc.system`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc`; `java_rmi`; `dotnet_wcf` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [3] | int | Server port number. [4] | `80`; `8080`; `443` | | [`network.peer.address`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | | [`network.peer.port`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` | @@ -121,25 +122,19 @@ This span represents an outgoing Remote Procedure Call (RPC). **[1] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[2] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2] `error.type`:** If the RPC fails with an error before status code is returned, +`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) +or a component-specific, low cardinality error identifier. -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. +If a response status code is returned and status indicates an error, +`error.type` SHOULD be set to that status code. Check system-specific conventions +for the details on which values of `rpc.response.status_code` are considered errors. +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. -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. +If the request has completed successfully, instrumentations SHOULD NOT set +`error.type`. **[3] `server.port`:** if the port is supported by the network transport used for communication. @@ -215,7 +210,8 @@ This span represents an incoming Remote Procedure Call (RPC). **Span kind** MUST be `SERVER`. -**Span status** SHOULD follow the [Recording Errors](/docs/general/recording-errors.md) document. +**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) +document for details on how to record span status. **Attributes:** @@ -223,7 +219,7 @@ This span represents an incoming Remote Procedure Call (RPC). |---|---|---|---|---|---| | [`rpc.system`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | A string identifying the remoting system. See below for a list of well-known identifiers. | `grpc`; `java_rmi`; `dotnet_wcf` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Required` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). [1] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation failed. | string | Describes a class of error the operation ended with. [2] | `DEADLINE_EXCEEDED`; `java.net.UnknownHostException`; `-32602` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` [3] | int | Server port number. [4] | `80`; `8080`; `443` | | [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | int | Client port number. [6] | `65123` | @@ -237,25 +233,19 @@ This span represents an incoming Remote Procedure Call (RPC). **[1] `server.address`:** May contain server IP address, DNS name, or local socket name. When host component is an IP address, instrumentations SHOULD NOT do a reverse proxy lookup to obtain DNS name and SHOULD set `server.address` to the IP address provided in the host component. -**[2] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. +**[2] `error.type`:** If the RPC fails with an error before status code is returned, +`error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) +or a component-specific, low cardinality error identifier. -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. +If a response status code is returned and status indicates an error, +`error.type` SHOULD be set to that status code. Check system-specific conventions +for the details on which values of `rpc.response.status_code` are considered errors. +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. -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. +If the request has completed successfully, instrumentations SHOULD NOT set +`error.type`. **[3] `server.port`:** if the port is supported by the network transport used for communication. diff --git a/model/error/registry.yaml b/model/error/registry.yaml index 759edd0b92..927c8c636a 100644 --- a/model/error/registry.yaml +++ b/model/error/registry.yaml @@ -32,7 +32,7 @@ groups: 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), + If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute diff --git a/model/otel/metrics.yaml b/model/otel/metrics.yaml index c9285e7433..c85096260b 100644 --- a/model/otel/metrics.yaml +++ b/model/otel/metrics.yaml @@ -340,7 +340,7 @@ groups: brief: The HTTP status code of the last HTTP request performed in scope of this export call. requirement_level: recommended: when applicable - - ref: rpc.grpc.status_code - brief: The gRPC status code of the last gRPC requests performed in scope of this export call. + - ref: rpc.response.status_code + brief: The gRPC status code of the last gRPC request performed in scope of this export call. requirement_level: recommended: when applicable diff --git a/model/rpc/common.yaml b/model/rpc/common.yaml index da29afa723..33eafe45e2 100644 --- a/model/rpc/common.yaml +++ b/model/rpc/common.yaml @@ -66,6 +66,21 @@ groups: - ref: error.type requirement_level: conditionally_required: If and only if the operation failed. + examples: ['DEADLINE_EXCEEDED', 'java.net.UnknownHostException', '-32602'] + note: | + If the RPC fails with an error before status code is returned, + `error.type` SHOULD be set to the exception type (its fully-qualified class name, if applicable) + or a component-specific, low cardinality error identifier. + + If a response status code is returned and status indicates an error, + `error.type` SHOULD be set to that status code. Check system-specific conventions + for the details on which values of `rpc.response.status_code` are considered errors. + + The `error.type` value SHOULD be predictable and SHOULD have low cardinality. + Instrumentations SHOULD document the list of errors they report. + + If the request has completed successfully, instrumentations SHOULD NOT set + `error.type`. - id: rpc_service type: attribute_group brief: 'This document defines semantic conventions for remote procedure calls.' diff --git a/model/rpc/deprecated/registry-deprecated.yaml b/model/rpc/deprecated/registry-deprecated.yaml index 5eb2f01235..c900b4eac9 100644 --- a/model/rpc/deprecated/registry-deprecated.yaml +++ b/model/rpc/deprecated/registry-deprecated.yaml @@ -39,3 +39,151 @@ groups: deprecated: reason: renamed renamed_to: rpc.message.uncompressed_size + - id: rpc.grpc.status_code + type: + members: + - id: ok + brief: OK + stability: development + value: 0 + - id: cancelled + brief: CANCELLED + stability: development + value: 1 + - id: unknown + brief: UNKNOWN + stability: development + value: 2 + - id: invalid_argument + brief: INVALID_ARGUMENT + stability: development + value: 3 + - id: deadline_exceeded + brief: DEADLINE_EXCEEDED + stability: development + value: 4 + - id: not_found + brief: NOT_FOUND + stability: development + value: 5 + - id: already_exists + brief: ALREADY_EXISTS + stability: development + value: 6 + - id: permission_denied + brief: PERMISSION_DENIED + stability: development + value: 7 + - id: resource_exhausted + brief: RESOURCE_EXHAUSTED + stability: development + value: 8 + - id: failed_precondition + brief: FAILED_PRECONDITION + stability: development + value: 9 + - id: aborted + brief: ABORTED + stability: development + value: 10 + - id: out_of_range + brief: OUT_OF_RANGE + stability: development + value: 11 + - id: unimplemented + brief: UNIMPLEMENTED + stability: development + value: 12 + - id: internal + brief: INTERNAL + stability: development + value: 13 + - id: unavailable + brief: UNAVAILABLE + stability: development + value: 14 + - id: data_loss + brief: DATA_LOSS + stability: development + value: 15 + - id: unauthenticated + brief: UNAUTHENTICATED + stability: development + value: 16 + stability: development + brief: "Deprecated, use string representation on the `rpc.response.status_code` attribute instead." + deprecated: + reason: uncategorized + note: "Use string representation of the gRPC status code on the `rpc.response.status_code` attribute." + - id: rpc.connect_rpc.error_code + type: + members: + - id: cancelled + value: cancelled + stability: development + - id: unknown + value: unknown + stability: development + - id: invalid_argument + value: invalid_argument + stability: development + - id: deadline_exceeded + value: deadline_exceeded + stability: development + - id: not_found + value: not_found + stability: development + - id: already_exists + value: already_exists + stability: development + - id: permission_denied + value: permission_denied + stability: development + - id: resource_exhausted + value: resource_exhausted + stability: development + - id: failed_precondition + value: failed_precondition + stability: development + - id: aborted + value: aborted + stability: development + - id: out_of_range + value: out_of_range + stability: development + - id: unimplemented + value: unimplemented + stability: development + - id: internal + value: internal + stability: development + - id: unavailable + value: unavailable + stability: development + - id: data_loss + value: data_loss + stability: development + - id: unauthenticated + value: unauthenticated + stability: development + stability: development + brief: "Deprecated, use `rpc.response.status_code` attribute instead." + deprecated: + reason: renamed + renamed_to: rpc.response.status_code + - id: rpc.jsonrpc.error_code + type: int + stability: development + brief: "Deprecated, use string representation on the `rpc.response.status_code` attribute instead." + examples: [-32700, 100] + deprecated: + reason: uncategorized + note: "Use string representation of the error code on the `rpc.response.status_code` attribute." + - id: rpc.jsonrpc.error_message + type: string + stability: development + brief: "Deprecated, use span status description or `error.message` attribute on other signals." + examples: ['Parse error', 'User already exists'] + deprecated: + reason: uncategorized + note: "Use the span status description or `error.message` attribute on other signals." diff --git a/model/rpc/registry.yaml b/model/rpc/registry.yaml index 639e30fd05..5c9780d037 100644 --- a/model/rpc/registry.yaml +++ b/model/rpc/registry.yaml @@ -4,59 +4,6 @@ groups: display_name: Remote Procedure Call (RPC) Attributes brief: 'This document defines attributes for remote procedure calls.' attributes: - - id: rpc.connect_rpc.error_code - type: - members: - - id: cancelled - value: cancelled - stability: development - - id: unknown - value: unknown - stability: development - - id: invalid_argument - value: invalid_argument - stability: development - - id: deadline_exceeded - value: deadline_exceeded - stability: development - - id: not_found - value: not_found - stability: development - - id: already_exists - value: already_exists - stability: development - - id: permission_denied - value: permission_denied - stability: development - - id: resource_exhausted - value: resource_exhausted - stability: development - - id: failed_precondition - value: failed_precondition - stability: development - - id: aborted - value: aborted - stability: development - - id: out_of_range - value: out_of_range - stability: development - - id: unimplemented - value: unimplemented - stability: development - - id: internal - value: internal - stability: development - - id: unavailable - value: unavailable - stability: development - - id: data_loss - value: data_loss - stability: development - - id: unauthenticated - value: unauthenticated - stability: development - stability: development - brief: "The [error codes](https://connectrpc.com//docs/protocol/#error-codes) of the Connect request. Error codes are always string values." - id: rpc.connect_rpc.request.metadata type: template[string[]] stability: development @@ -81,79 +28,18 @@ groups: For example, a property `my-custom-key` with value `"attribute_value"` SHOULD be recorded as the `rpc.connect_rpc.response.metadata.my-custom-key` attribute with value `["attribute_value"]` examples: [["attribute_value"]] - - id: rpc.grpc.status_code - type: - members: - - id: ok - brief: OK - stability: development - value: 0 - - id: cancelled - brief: CANCELLED - stability: development - value: 1 - - id: unknown - brief: UNKNOWN - stability: development - value: 2 - - id: invalid_argument - brief: INVALID_ARGUMENT - stability: development - value: 3 - - id: deadline_exceeded - brief: DEADLINE_EXCEEDED - stability: development - value: 4 - - id: not_found - brief: NOT_FOUND - stability: development - value: 5 - - id: already_exists - brief: ALREADY_EXISTS - stability: development - value: 6 - - id: permission_denied - brief: PERMISSION_DENIED - stability: development - value: 7 - - id: resource_exhausted - brief: RESOURCE_EXHAUSTED - stability: development - value: 8 - - id: failed_precondition - brief: FAILED_PRECONDITION - stability: development - value: 9 - - id: aborted - brief: ABORTED - stability: development - value: 10 - - id: out_of_range - brief: OUT_OF_RANGE - stability: development - value: 11 - - id: unimplemented - brief: UNIMPLEMENTED - stability: development - value: 12 - - id: internal - brief: INTERNAL - stability: development - value: 13 - - id: unavailable - brief: UNAVAILABLE - stability: development - value: 14 - - id: data_loss - brief: DATA_LOSS - stability: development - value: 15 - - id: unauthenticated - brief: UNAUTHENTICATED - stability: development - value: 16 + - id: rpc.response.status_code + type: string stability: development - brief: "The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request." + brief: Status code of the RPC returned by the RPC server or generated by the client + note: > + Usually it represents an error code, but may also represent partial success, + warning, or differentiate between various types of successful outcomes. + + Semantic conventions for individual RPC frameworks SHOULD document what + `rpc.response.status_code` means in the context of that system and which values + are considered to represent errors. + examples: ["OK", "DEADLINE_EXCEEDED", "-32602"] - id: rpc.grpc.request.metadata type: template[string[]] stability: development @@ -178,16 +64,7 @@ groups: For example, a property `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as the `rpc.grpc.response.metadata.my-custom-key` attribute with value `["attribute_value"]` examples: [["attribute_value"]] - - id: rpc.jsonrpc.error_code - type: int - stability: development - brief: "`error.code` property of response if it is an error response." - examples: [-32700, 100] - - id: rpc.jsonrpc.error_message - type: string - stability: development - brief: "`error.message` property of response if it is an error response." - examples: ['Parse error', 'User already exists'] + - id: rpc.jsonrpc.request_id type: string stability: development diff --git a/model/rpc/spans.yaml b/model/rpc/spans.yaml index 312383cab7..00c18d2528 100644 --- a/model/rpc/spans.yaml +++ b/model/rpc/spans.yaml @@ -7,6 +7,9 @@ groups: **Span name:** refer to the [Span Name](/docs/rpc/rpc-spans.md#span-name) section. **Span kind** MUST be `CLIENT`. + + **Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) + document for details on how to record span status. extends: rpc_service span_kind: client events: [rpc.message] @@ -25,6 +28,9 @@ groups: **Span name:** refer to the [Span Name](/docs/rpc/rpc-spans.md#span-name) section. **Span kind** MUST be `SERVER`. + + **Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) + document for details on how to record span status. attributes: - ref: rpc.system requirement_level: required @@ -39,12 +45,18 @@ groups: **Span name:** refer to the [Span Name](/docs/rpc/rpc-spans.md#span-name) section. **Span kind** MUST be `CLIENT`. + + **Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) + document for details on how to record span status. extends: rpc_service span_kind: client attributes: - - ref: rpc.connect_rpc.error_code + - ref: rpc.response.status_code requirement_level: conditionally_required: if available. + brief: The [error code](https://connectrpc.com//docs/protocol/#error-codes) of the Connect response. + note: | + All error codes except `OK` SHOULD be considered errors. - ref: rpc.connect_rpc.request.metadata requirement_level: opt_in - ref: rpc.connect_rpc.response.metadata @@ -62,10 +74,23 @@ groups: **Span name:** refer to the [Span Name](/docs/rpc/rpc-spans.md#span-name) section. **Span kind** MUST be `SERVER`. + + **Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) + document for details on how to record span status. attributes: - - ref: rpc.connect_rpc.error_code + - ref: rpc.response.status_code requirement_level: conditionally_required: if available. + brief: The [error code](https://connectrpc.com//docs/protocol/#error-codes) of the Connect response. + note: | + The following error codes SHOULD be considered errors: + + - `unknown` + - `deadline_exceeded` + - `unimplemented` + - `internal` + - `unavailable` + - `data_loss` - ref: rpc.connect_rpc.request.metadata requirement_level: opt_in - ref: rpc.connect_rpc.response.metadata @@ -82,7 +107,9 @@ groups: **Span kind** MUST be `CLIENT`. - **Span status** Should be set based on the grpc status code. A mapping is defined in the [grpc status](/docs/rpc/grpc.md#grpc-status) section. + **Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) + document for details on how to record span status. See also `rpc.response.status_code` attribute + for the details on which values classify as errors. extends: rpc_service span_kind: client attributes: @@ -90,8 +117,13 @@ groups: requirement_level: required - ref: rpc.service requirement_level: required - - ref: rpc.grpc.status_code + - ref: rpc.response.status_code requirement_level: required + brief: > + The string representation of the [status code](https://github.com/grpc/grpc/blob/v1.75.0/doc/statuscodes.md) + returned by the server or generated by the client. + note: | + All status codes except `OK` SHOULD be considered errors. - ref: rpc.grpc.request.metadata requirement_level: opt_in - ref: rpc.grpc.response.metadata @@ -110,10 +142,25 @@ groups: **Span kind** MUST be `SERVER`. - **Span status** Should be set based on the grpc status code. A mapping is defined in the [grpc status](/docs/rpc/grpc.md#grpc-status) section. + **Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) + document for details on how to record span status. See also `rpc.response.status_code` attribute + for the details on which values classify as errors. attributes: - - ref: rpc.grpc.status_code + - ref: rpc.response.status_code requirement_level: required + brief: > + The string representation of the [status code](https://github.com/grpc/grpc/blob/v1.75.0/doc/statuscodes.md) + returned by the server. + note: | + The following status codes SHOULD be considered errors: + + - `UNKNOWN` + - `DEADLINE_EXCEEDED` + - `UNIMPLEMENTED` + - `INTERNAL` + - `UNAVAILABLE` + - `DATA_LOSS` + - ref: rpc.grpc.request.metadata requirement_level: opt_in - ref: rpc.grpc.response.metadata @@ -129,6 +176,11 @@ groups: **Span name:** refer to the [Span Name](/docs/rpc/rpc-spans.md#span-name) section. **Span kind** MUST be `CLIENT`. + + **Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) + document for details on how to record span status. Responses that include + [`error` object](https://www.jsonrpc.org/specification#error_object) + are considered errors. extends: rpc span_kind: client attributes: @@ -139,11 +191,14 @@ groups: conditionally_required: If other than the default version (`1.0`) - ref: rpc.jsonrpc.request_id requirement_level: recommended - - ref: rpc.jsonrpc.error_code + - ref: rpc.response.status_code + brief: > + The [`error.code`](https://www.jsonrpc.org/specification#error_object) + property of response if it is an error response recorded as a string. + note: + All JSON RPC error codes SHOULD be considered errors. requirement_level: conditionally_required: when available - - ref: rpc.jsonrpc.error_message - requirement_level: recommended - id: span.rpc.jsonrpc.server type: span @@ -157,6 +212,11 @@ groups: **Span name:** refer to the [Span Name](/docs/rpc/rpc-spans.md#span-name) section. **Span kind** MUST be `SERVER`. + + **Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md) + document for details on how to record span status. Responses that include + [`error` object](https://www.jsonrpc.org/specification#error_object) + are considered errors. attributes: - ref: rpc.method requirement_level: required @@ -165,11 +225,14 @@ groups: conditionally_required: If other than the default version (`1.0`) - ref: rpc.jsonrpc.request_id requirement_level: recommended - - ref: rpc.jsonrpc.error_code + - ref: rpc.response.status_code + brief: > + The [`error.code`](https://www.jsonrpc.org/specification#error_object) property of + response recorded as a string. + note: + All JSON RPC error codes SHOULD be considered errors. requirement_level: conditionally_required: when available - - ref: rpc.jsonrpc.error_message - requirement_level: recommended - id: event.rpc.message type: event