diff --git a/.chloggen/rpc-consistent-attributes-metrics-spans.yaml b/.chloggen/rpc-consistent-attributes-metrics-spans.yaml
new file mode 100644
index 0000000000..8f042ed289
--- /dev/null
+++ b/.chloggen/rpc-consistent-attributes-metrics-spans.yaml
@@ -0,0 +1,8 @@
+change_type: enhancement
+component: rpc
+note: Use consistent set of attributes between RPC spans and metrics
+issues: [2922, 3197]
+subtext: |
+ - Use `rpc.response.status_code` on common metrics and spans.
+ - Make `error.type` note consistent between metrics and spans.
+ - Promote notes on `rpc.method` and `rpc.service` to attribute definition.
diff --git a/docs/registry/attributes/rpc.md b/docs/registry/attributes/rpc.md
index 2685bcffd2..37fc8f6944 100644
--- a/docs/registry/attributes/rpc.md
+++ b/docs/registry/attributes/rpc.md
@@ -18,31 +18,35 @@ This document defines attributes for remote procedure calls.
| `rpc.message.id` |  | int | MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. [1] | |
| `rpc.message.type` |  | string | Whether this is a received or sent message. | `SENT`; `RECEIVED` |
| `rpc.message.uncompressed_size` |  | int | Uncompressed size of the message in bytes. | |
-| `rpc.method` |  | string | This is the logical name of the method from the RPC interface perspective. | `exampleMethod` |
-| `rpc.request.metadata.` |  | string[] | RPC request metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. [2] | `["1.2.3.4", "1.2.3.5"]` |
-| `rpc.response.metadata.` |  | string[] | RPC response metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. [3] | `["attribute_value"]` |
-| `rpc.response.status_code` |  | string | Status code of the RPC returned by the RPC server or generated by the client [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
-| `rpc.service` |  | string | The full (logical) name of the service being called, including its package name, if applicable. | `myservice.EchoService` |
-| `rpc.system.name` |  | string | The Remote Procedure Call (RPC) system. [5] | `grpc`; `dubbo`; `connectrpc` |
+| `rpc.method` |  | string | This is the logical name of the method from the RPC interface perspective. [2] | `exampleMethod` |
+| `rpc.request.metadata.` |  | string[] | RPC request metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. [3] | `["1.2.3.4", "1.2.3.5"]` |
+| `rpc.response.metadata.` |  | string[] | RPC response metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. [4] | `["attribute_value"]` |
+| `rpc.response.status_code` |  | string | Status code of the RPC returned by the RPC server or generated by the client [5] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| `rpc.service` |  | string | The full (logical) name of the service being called, including its package name, if applicable. [6] | `myservice.EchoService` |
+| `rpc.system.name` |  | string | The Remote Procedure Call (RPC) system. [7] | `grpc`; `dubbo`; `connectrpc` |
**[1] `rpc.message.id`:** This way we guarantee that the values will be consistent between different implementations.
-**[2] `rpc.request.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured.
+**[2] `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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method on the client side.
+
+**[3] `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
`rpc.request.metadata.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]`
-**[3] `rpc.response.metadata.`:** Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured.
+**[4] `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
the `rpc.response.metadata.my-custom-key` attribute with value `["attribute_value"]`
-**[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.
+**[5] `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] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
+**[6] `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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
+
+**[7] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
---
diff --git a/docs/rpc/connect-rpc.md b/docs/rpc/connect-rpc.md
index a847098671..c12b8d1cdd 100644
--- a/docs/rpc/connect-rpc.md
+++ b/docs/rpc/connect-rpc.md
@@ -80,9 +80,9 @@ 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.
-**[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.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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method 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.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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
**[11] `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.
@@ -203,9 +203,9 @@ 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.
-**[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.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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method 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.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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
**[13] `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.
diff --git a/docs/rpc/grpc.md b/docs/rpc/grpc.md
index 7b69c66c6a..96d6541c49 100644
--- a/docs/rpc/grpc.md
+++ b/docs/rpc/grpc.md
@@ -49,11 +49,11 @@ for the details on which values classify as errors.
| [`rpc.request.metadata.`](/docs/registry/attributes/rpc.md) |  | `Opt-In` | string[] | RPC request metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. [11] | `["1.2.3.4", "1.2.3.5"]` |
| [`rpc.response.metadata.`](/docs/registry/attributes/rpc.md) |  | `Opt-In` | string[] | RPC response metadata, `` being the normalized RPC 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).
+**[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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method on the client side.
**[2] `rpc.response.status_code`:** All status codes except `OK` SHOULD be considered errors.
-**[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).
+**[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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
**[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.
@@ -205,9 +205,9 @@ 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.
-**[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.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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method 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.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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
**[13] `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.
diff --git a/docs/rpc/json-rpc.md b/docs/rpc/json-rpc.md
index baeecfbc3d..0f7453a802 100644
--- a/docs/rpc/json-rpc.md
+++ b/docs/rpc/json-rpc.md
@@ -49,7 +49,7 @@ are considered errors.
| [`network.protocol.version`](/docs/registry/attributes/network.md) |  | `Recommended` | string | The actual version of the protocol used for network communication. [9] | `1.1`; `2` |
| [`network.transport`](/docs/registry/attributes/network.md) |  | `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` |
-**[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).
+**[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 record the fully-qualified method actually executing the call on the server side, or the 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.
@@ -151,7 +151,7 @@ are considered errors.
| [`network.protocol.version`](/docs/registry/attributes/network.md) |  | `Recommended` | string | The actual version of the protocol used for network communication. [11] | `1.1`; `2` |
| [`network.transport`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [12] | `tcp`; `udp` |
-**[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).
+**[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 record the fully-qualified method actually executing the call on the server side, or the 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.
diff --git a/docs/rpc/rpc-metrics.md b/docs/rpc/rpc-metrics.md
index b41b0f5ab0..67f7353433 100644
--- a/docs/rpc/rpc-metrics.md
+++ b/docs/rpc/rpc-metrics.md
@@ -88,47 +88,49 @@ SHOULD be the same as the RPC server span duration.
| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`rpc.system.name`](/docs/registry/attributes/rpc.md) |  | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `grpc`; `dubbo`; `connectrpc` |
-| [`error.type`](/docs/registry/attributes/error.md) |  | `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` |
-| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [3] | `http` |
-| [`network.protocol.version`](/docs/registry/attributes/network.md) |  | `Recommended` | string | The actual version of the protocol used for network communication. [4] | `1.1`; `2` |
-| [`network.transport`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [5] | `tcp`; `udp` |
-| [`rpc.method`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. | `exampleMethod` |
-| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. | `myservice.EchoService` |
-| [`server.address`](/docs/registry/attributes/server.md) |  | `Opt-In` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
+| [`error.type`](/docs/registry/attributes/error.md) |  | `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) |  | `Conditionally Required` if available. | string | Status code of the RPC returned by the RPC server or generated by the client [3] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http` |
+| [`network.protocol.version`](/docs/registry/attributes/network.md) |  | `Recommended` | string | The actual version of the protocol used for network communication. [5] | `1.1`; `2` |
+| [`network.transport`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [6] | `tcp`; `udp` |
+| [`rpc.method`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [7] | `exampleMethod` |
+| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [8] | `myservice.EchoService` |
+| [`server.address`](/docs/registry/attributes/server.md) |  | `Opt-In` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
| [`server.port`](/docs/registry/attributes/server.md) |  | `Opt-In` | int | Server port number. | `80`; `8080`; `443` |
**[1] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
-**[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`:** 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.
-If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes),
-it's RECOMMENDED to:
+**[4] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
-- 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] `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.
-**[3] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
-
-**[4] `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.transport`:** The value SHOULD be normalized to lowercase.
+**[6] `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.
+**[7] `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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method on the client side.
+
+**[8] `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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
+
---
`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
@@ -184,47 +186,49 @@ This metric is [recommended][MetricRecommended].
| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`rpc.system.name`](/docs/registry/attributes/rpc.md) |  | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `grpc`; `dubbo`; `connectrpc` |
-| [`error.type`](/docs/registry/attributes/error.md) |  | `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` |
-| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [3] | `http` |
-| [`network.protocol.version`](/docs/registry/attributes/network.md) |  | `Recommended` | string | The actual version of the protocol used for network communication. [4] | `1.1`; `2` |
-| [`network.transport`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [5] | `tcp`; `udp` |
-| [`rpc.method`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. | `exampleMethod` |
-| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. | `myservice.EchoService` |
-| [`server.address`](/docs/registry/attributes/server.md) |  | `Opt-In` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
+| [`error.type`](/docs/registry/attributes/error.md) |  | `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) |  | `Conditionally Required` if available. | string | Status code of the RPC returned by the RPC server or generated by the client [3] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http` |
+| [`network.protocol.version`](/docs/registry/attributes/network.md) |  | `Recommended` | string | The actual version of the protocol used for network communication. [5] | `1.1`; `2` |
+| [`network.transport`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [6] | `tcp`; `udp` |
+| [`rpc.method`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [7] | `exampleMethod` |
+| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [8] | `myservice.EchoService` |
+| [`server.address`](/docs/registry/attributes/server.md) |  | `Opt-In` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
| [`server.port`](/docs/registry/attributes/server.md) |  | `Opt-In` | int | Server port number. | `80`; `8080`; `443` |
**[1] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
-**[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 RPC 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.
+**[3] `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.
-**[3] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
+**[4] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
-**[4] `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.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.transport`:** The value SHOULD be normalized to lowercase.
+**[6] `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.
+**[7] `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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method on the client side.
+
+**[8] `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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
+
---
`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
@@ -280,47 +284,49 @@ This metric is [recommended][MetricRecommended].
| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`rpc.system.name`](/docs/registry/attributes/rpc.md) |  | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `grpc`; `dubbo`; `connectrpc` |
-| [`error.type`](/docs/registry/attributes/error.md) |  | `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` |
-| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [3] | `http` |
-| [`network.protocol.version`](/docs/registry/attributes/network.md) |  | `Recommended` | string | The actual version of the protocol used for network communication. [4] | `1.1`; `2` |
-| [`network.transport`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [5] | `tcp`; `udp` |
-| [`rpc.method`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. | `exampleMethod` |
-| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. | `myservice.EchoService` |
-| [`server.address`](/docs/registry/attributes/server.md) |  | `Opt-In` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
+| [`error.type`](/docs/registry/attributes/error.md) |  | `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) |  | `Conditionally Required` if available. | string | Status code of the RPC returned by the RPC server or generated by the client [3] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http` |
+| [`network.protocol.version`](/docs/registry/attributes/network.md) |  | `Recommended` | string | The actual version of the protocol used for network communication. [5] | `1.1`; `2` |
+| [`network.transport`](/docs/registry/attributes/network.md) |  | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [6] | `tcp`; `udp` |
+| [`rpc.method`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [7] | `exampleMethod` |
+| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [8] | `myservice.EchoService` |
+| [`server.address`](/docs/registry/attributes/server.md) |  | `Opt-In` | string | RPC server [host name](https://grpc.github.io/grpc/core/md_doc_naming.html). | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
| [`server.port`](/docs/registry/attributes/server.md) |  | `Opt-In` | int | Server port number. | `80`; `8080`; `443` |
**[1] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
-**[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 the request has completed successfully, instrumentations SHOULD NOT set
+`error.type`.
-If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes),
-it's RECOMMENDED to:
+**[3] `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.
-- 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] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
-**[3] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
+**[5] `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.
-**[4] `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.transport`:** The value SHOULD be normalized to lowercase.
+**[6] `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.
+**[7] `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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method on the client side.
+
+**[8] `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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
+
---
`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
@@ -385,51 +391,53 @@ SHOULD be the same as the RPC client span duration.
| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`rpc.system.name`](/docs/registry/attributes/rpc.md) |  | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `grpc`; `dubbo`; `connectrpc` |
-| [`server.address`](/docs/registry/attributes/server.md) |  | `Required` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
-| [`error.type`](/docs/registry/attributes/error.md) |  | `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` |
-| [`server.port`](/docs/registry/attributes/server.md) |  | `Conditionally Required` If applicable. | int | Server port number. [4] | `80`; `8080`; `443` |
-| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [6] | `1.1`; `2` |
-| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. | `exampleMethod` |
-| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. | `myservice.EchoService` |
+| [`server.address`](/docs/registry/attributes/server.md) |  | `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) |  | `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.response.status_code`](/docs/registry/attributes/rpc.md) |  | `Conditionally Required` if available. | string | Status code of the RPC returned by the RPC server or generated by the client [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| [`server.port`](/docs/registry/attributes/server.md) |  | `Conditionally Required` If applicable. | int | Server port number. [5] | `80`; `8080`; `443` |
+| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [7] | `1.1`; `2` |
+| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [9] | `exampleMethod` |
+| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [10] | `myservice.EchoService` |
**[1] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
-**[2] `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.
+**[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`:** 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.
-If a specific domain defines its own set of error identifiers (such as HTTP or RPC 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] `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.
+**[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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method 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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
+
---
`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
@@ -485,51 +493,53 @@ This metric is [recommended][MetricRecommended].
| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`rpc.system.name`](/docs/registry/attributes/rpc.md) |  | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `grpc`; `dubbo`; `connectrpc` |
-| [`server.address`](/docs/registry/attributes/server.md) |  | `Required` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
-| [`error.type`](/docs/registry/attributes/error.md) |  | `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` |
-| [`server.port`](/docs/registry/attributes/server.md) |  | `Conditionally Required` If applicable. | int | Server port number. [4] | `80`; `8080`; `443` |
-| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [6] | `1.1`; `2` |
-| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. | `exampleMethod` |
-| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. | `myservice.EchoService` |
+| [`server.address`](/docs/registry/attributes/server.md) |  | `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) |  | `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.response.status_code`](/docs/registry/attributes/rpc.md) |  | `Conditionally Required` if available. | string | Status code of the RPC returned by the RPC server or generated by the client [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| [`server.port`](/docs/registry/attributes/server.md) |  | `Conditionally Required` If applicable. | int | Server port number. [5] | `80`; `8080`; `443` |
+| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [7] | `1.1`; `2` |
+| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [9] | `exampleMethod` |
+| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [10] | `myservice.EchoService` |
**[1] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
-**[2] `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.
+**[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 RPC 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`:** 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.
-**[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.
+**[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] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
+**[6] `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.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.
+**[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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method 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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
+
---
`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
@@ -585,51 +595,53 @@ This metric is [recommended][MetricRecommended].
| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`rpc.system.name`](/docs/registry/attributes/rpc.md) |  | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `grpc`; `dubbo`; `connectrpc` |
-| [`server.address`](/docs/registry/attributes/server.md) |  | `Required` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
-| [`error.type`](/docs/registry/attributes/error.md) |  | `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` |
-| [`server.port`](/docs/registry/attributes/server.md) |  | `Conditionally Required` If applicable. | int | Server port number. [4] | `80`; `8080`; `443` |
-| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [6] | `1.1`; `2` |
-| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. | `exampleMethod` |
-| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. | `myservice.EchoService` |
+| [`server.address`](/docs/registry/attributes/server.md) |  | `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) |  | `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.response.status_code`](/docs/registry/attributes/rpc.md) |  | `Conditionally Required` if available. | string | Status code of the RPC returned by the RPC server or generated by the client [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| [`server.port`](/docs/registry/attributes/server.md) |  | `Conditionally Required` If applicable. | int | Server port number. [5] | `80`; `8080`; `443` |
+| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [7] | `1.1`; `2` |
+| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [9] | `exampleMethod` |
+| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [10] | `myservice.EchoService` |
**[1] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
-**[2] `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.
+**[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 the request has completed successfully, instrumentations SHOULD NOT set
+`error.type`.
-If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes),
-it's RECOMMENDED to:
+**[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.
-- 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.
-**[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] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
-**[5] `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.
-**[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.
+**[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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method 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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
+
---
`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
diff --git a/docs/rpc/rpc-spans.md b/docs/rpc/rpc-spans.md
index 57966ae926..f312adaff6 100644
--- a/docs/rpc/rpc-spans.md
+++ b/docs/rpc/rpc-spans.md
@@ -119,14 +119,15 @@ document for details on how to record span status.
| [`rpc.system.name`](/docs/registry/attributes/rpc.md) |  | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `grpc`; `dubbo`; `connectrpc` |
| [`server.address`](/docs/registry/attributes/server.md) |  | `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) |  | `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) |  | `Conditionally Required` [4] | int | Server port number. [5] | `80`; `8080`; `443` |
+| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) |  | `Conditionally Required` if available. | string | Status code of the RPC returned by the RPC server or generated by the client [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| [`server.port`](/docs/registry/attributes/server.md) |  | `Conditionally Required` [5] | int | Server port number. [6] | `80`; `8080`; `443` |
| [`network.peer.address`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` |
-| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [7] | `1.1`; `2` |
-| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [9] | `exampleMethod` |
-| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [10] | `myservice.EchoService` |
+| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [8] | `1.1`; `2` |
+| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [10] | `exampleMethod` |
+| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [11] | `myservice.EchoService` |
**[1] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
@@ -146,23 +147,26 @@ Instrumentations SHOULD document the list of errors they report.
If the request has completed successfully, instrumentations SHOULD NOT set
`error.type`.
-**[4] `server.port`:** if the port is supported by the network transport used for communication.
+**[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.port`:** if the port is supported by the network transport used for communication.
-**[6] `network.protocol.name`:** The value SHOULD be normalized to lowercase.
+**[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] `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.protocol.name`:** The value SHOULD be normalized to lowercase.
-**[8] `network.transport`:** 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.
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.
-**[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).
+**[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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method 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).
+**[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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
---
@@ -231,16 +235,17 @@ document for details on how to record span status.
| [`rpc.system.name`](/docs/registry/attributes/rpc.md) |  | `Required` | string | The Remote Procedure Call (RPC) system. [1] | `grpc`; `dubbo`; `connectrpc` |
| [`server.address`](/docs/registry/attributes/server.md) |  | `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) |  | `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) |  | `Conditionally Required` [4] | int | Server port number. [5] | `80`; `8080`; `443` |
-| [`client.address`](/docs/registry/attributes/client.md) |  | `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) |  | `Recommended` | int | Client port number. [7] | `65123` |
+| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) |  | `Conditionally Required` if available. | string | Status code of the RPC returned by the RPC server or generated by the client [4] | `OK`; `DEADLINE_EXCEEDED`; `-32602` |
+| [`server.port`](/docs/registry/attributes/server.md) |  | `Conditionally Required` [5] | int | Server port number. [6] | `80`; `8080`; `443` |
+| [`client.address`](/docs/registry/attributes/client.md) |  | `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) |  | `Recommended` | int | Client port number. [8] | `65123` |
| [`network.peer.address`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` If `network.peer.address` is set. | int | Peer port number of the network connection. | `65123` |
-| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [9] | `1.1`; `2` |
-| [`network.transport`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [11] | `exampleMethod` |
-| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [12] | `myservice.EchoService` |
+| [`network.protocol.name`](/docs/registry/attributes/network.md) |  | `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) |  | `Recommended` | string | The actual version of the protocol used for network communication. [10] | `1.1`; `2` |
+| [`network.transport`](/docs/registry/attributes/network.md) |  | `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.method`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | This is the logical name of the method from the RPC interface perspective. [12] | `exampleMethod` |
+| [`rpc.service`](/docs/registry/attributes/rpc.md) |  | `Recommended` | string | The full (logical) name of the service being called, including its package name, if applicable. [13] | `myservice.EchoService` |
**[1] `rpc.system.name`:** The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC.
@@ -260,27 +265,30 @@ Instrumentations SHOULD document the list of errors they report.
If the request has completed successfully, instrumentations SHOULD NOT set
`error.type`.
-**[4] `server.port`:** if the port is supported by the network transport used for communication.
+**[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`:** 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
different processes could be listening on TCP port 12345 and UDP port 12345.
-**[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).
+**[12] `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 record the fully-qualified method actually executing the call on the server side, or the RPC client stub method 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).
+**[13] `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.function.name` attribute may be used to record the fully-qualified method actually executing the call on the server side, or the RPC client stub class on the client side.
---
diff --git a/model/aws/sdk-spans.yaml b/model/aws/sdk-spans.yaml
index 9fcd9f6232..8f87a69096 100644
--- a/model/aws/sdk-spans.yaml
+++ b/model/aws/sdk-spans.yaml
@@ -26,11 +26,13 @@ groups:
examples:
- DynamoDB
- S3
+ note: ""
- ref: rpc.method
brief: "The name of the operation corresponding to the request, as returned by the AWS SDK"
examples:
- GetItem
- PutItem
+ note: ""
- ref: aws.request_id
requirement_level: recommended
- ref: aws.extended_request_id
diff --git a/model/rpc/common.yaml b/model/rpc/common.yaml
index bdb4478faf..2d34805920 100644
--- a/model/rpc/common.yaml
+++ b/model/rpc/common.yaml
@@ -1,57 +1,10 @@
groups:
- - id: attributes.metrics.rpc.client
+ - id: common.rpc.attributes
type: attribute_group
- brief: "Describes RPC metric attributes."
+ brief: 'Common attributes for RPC spans and metrics.'
attributes:
- - ref: rpc.system.name
- requirement_level: required
- - ref: rpc.service
- - ref: rpc.method
- - ref: network.protocol.name
- examples: ["http"]
- - ref: network.protocol.version
- - ref: network.transport
- - ref: server.address
- requirement_level: required
- - ref: server.port
- requirement_level:
- conditionally_required: If applicable.
- - ref: error.type
- requirement_level:
- conditionally_required: If and only if the operation failed.
- - id: attributes.metrics.rpc.server
- type: attribute_group
- brief: "Describes RPC metric attributes."
- extends: attributes.metrics.rpc.client
- attributes:
- - ref: server.address
- note: ""
- requirement_level: opt_in
- - ref: server.port
- note: ""
- requirement_level: opt_in
- - id: rpc
- type: attribute_group
- brief: 'This document defines semantic conventions for remote procedure calls.'
- attributes:
- - ref: network.protocol.name
- examples: ["http"]
- - ref: network.protocol.version
- ref: rpc.method
requirement_level: recommended
- note: >
- 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).
- - ref: network.peer.address
- requirement_level: recommended
- - ref: network.peer.port
- requirement_level:
- recommended: If `network.peer.address` is set.
- - ref: network.transport
- requirement_level: recommended
- ref: server.address
requirement_level: required
brief: >
@@ -63,6 +16,9 @@ groups:
- ref: server.port
requirement_level:
conditionally_required: if the port is supported by the network transport used for communication.
+ - ref: rpc.response.status_code
+ requirement_level:
+ conditionally_required: if available.
- ref: error.type
requirement_level:
conditionally_required: If and only if the operation failed.
@@ -81,41 +37,8 @@ groups:
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.'
- extends: rpc
- attributes:
- - ref: rpc.service
- requirement_level: recommended
- note: >
- 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).
-
- - id: rpc.server
- type: attribute_group
- brief: 'This document defines semantic conventions for remote procedure calls.'
- extends: rpc
- attributes:
- - ref: client.address
- requirement_level: recommended
- - ref: client.port
- requirement_level: recommended
- - ref: network.transport
- requirement_level: recommended
-
- - id: rpc_service.server
- type: attribute_group
- brief: 'This document defines semantic conventions for remote procedure calls.'
- extends: rpc_service
- attributes:
- - ref: client.address
- requirement_level: recommended
- - ref: client.port
- requirement_level: recommended
+ - ref: network.protocol.name
+ examples: ["http"]
+ - ref: network.protocol.version
- ref: network.transport
requirement_level: recommended
diff --git a/model/rpc/metrics.yaml b/model/rpc/metrics.yaml
index ba4f0ce603..f1d1d6c928 100644
--- a/model/rpc/metrics.yaml
+++ b/model/rpc/metrics.yaml
@@ -1,4 +1,30 @@
groups:
+ - id: attributes.metrics.rpc.client
+ type: attribute_group
+ brief: "Describes RPC metric attributes."
+ extends: common.rpc.attributes
+ attributes:
+ - ref: rpc.system.name
+ requirement_level: required
+ - ref: rpc.service
+ - ref: server.address
+ requirement_level: required
+ - ref: server.port
+ requirement_level:
+ conditionally_required: If applicable.
+ - id: attributes.metrics.rpc.server
+ type: attribute_group
+ brief: "Describes RPC metric attributes."
+ extends: attributes.metrics.rpc.client
+ attributes:
+ - ref: rpc.system.name
+ requirement_level: required
+ - ref: server.address
+ note: ""
+ requirement_level: opt_in
+ - ref: server.port
+ note: ""
+ requirement_level: opt_in
# RPC Server metrics
- id: metric.rpc.server.call.duration
type: metric
@@ -44,7 +70,6 @@ groups:
**Streaming**: Recorded per response in a streaming batch
extends: attributes.metrics.rpc.server
-
# RPC Client metrics
- id: metric.rpc.client.call.duration
type: metric
diff --git a/model/rpc/registry.yaml b/model/rpc/registry.yaml
index 74211a043d..6b1f5683d5 100644
--- a/model/rpc/registry.yaml
+++ b/model/rpc/registry.yaml
@@ -45,11 +45,23 @@ groups:
stability: development
brief: This is the logical name of the method from the RPC interface perspective.
examples: "exampleMethod"
+ note: >
+ 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 record the fully-qualified
+ method actually executing the call on the server side, or the
+ RPC client stub method on the client side.
- id: rpc.service
type: string
stability: development
brief: 'The full (logical) name of the service being called, including its package name, if applicable.'
examples: "myservice.EchoService"
+ note: >
+ 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.function.name` attribute may be used to record the fully-qualified
+ method actually executing the call on the server side, or the
+ RPC client stub class on the client side.
- id: rpc.system.name
brief: 'The Remote Procedure Call (RPC) system.'
note: >
diff --git a/model/rpc/spans.yaml b/model/rpc/spans.yaml
index 01990b037a..9f96c17f57 100644
--- a/model/rpc/spans.yaml
+++ b/model/rpc/spans.yaml
@@ -1,4 +1,38 @@
groups:
+
+ - id: rpc
+ type: attribute_group
+ brief: 'This document defines semantic conventions for remote procedure calls.'
+ extends: common.rpc.attributes
+ attributes:
+ - ref: network.peer.address
+ requirement_level: recommended
+ - ref: network.peer.port
+ requirement_level:
+ recommended: If `network.peer.address` is set.
+
+ - id: rpc.server
+ type: attribute_group
+ brief: 'This document defines semantic conventions for remote procedure calls.'
+ extends: rpc
+ attributes:
+ - ref: client.address
+ requirement_level: recommended
+ - ref: client.port
+ requirement_level: recommended
+
+ - id: rpc_service.server
+ type: attribute_group
+ brief: 'This document defines semantic conventions for remote procedure calls.'
+ extends: rpc
+ attributes:
+ - ref: client.address
+ requirement_level: recommended
+ - ref: client.port
+ requirement_level: recommended
+ - ref: rpc.service
+ requirement_level: recommended
+
- id: span.rpc.call.client
type: span
stability: development
@@ -20,12 +54,13 @@ groups:
**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md)
document for details on how to record span status.
- extends: rpc_service
+ extends: rpc
span_kind: client
events: [rpc.message]
attributes:
- ref: rpc.system.name
requirement_level: required
+ - ref: rpc.service
- id: span.rpc.call.server
type: span
@@ -65,7 +100,7 @@ groups:
**Span status** Refer to the [Recording Errors](/docs/general/recording-errors.md)
document for details on how to record span status.
- extends: rpc_service
+ extends: rpc
span_kind: client
attributes:
- ref: rpc.response.status_code
@@ -78,6 +113,7 @@ groups:
requirement_level: opt_in
- ref: rpc.response.metadata
requirement_level: opt_in
+ - ref: rpc.service
- id: span.rpc.connect_rpc.call.server
type: span
@@ -127,7 +163,7 @@ groups:
**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
+ extends: rpc
span_kind: client
attributes:
- ref: rpc.method