diff --git a/docs/attributes-registry/dns.md b/docs/attributes-registry/dns.md index f4d37f8331..18de006b70 100644 --- a/docs/attributes-registry/dns.md +++ b/docs/attributes-registry/dns.md @@ -12,7 +12,7 @@ This document defines the shared attributes used to report a DNS query. | Attribute | Type | Description | Examples | Stability | | ------------------- | -------- | -------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------- | -| `dns.answer` | string[] | The list of resolved IPv4 or IPv6 addresses. | `["10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `dns.answers` | string[] | The list of resolved IPv4 or IPv6 addresses. | `["10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | `dns.question.name` | string | The name being queried. [1] | `www.example.com`; `opentelemetry.io` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | **[1]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. diff --git a/docs/dotnet/dotnet-connection-traces.md b/docs/dotnet/dotnet-network-traces.md similarity index 52% rename from docs/dotnet/dotnet-connection-traces.md rename to docs/dotnet/dotnet-network-traces.md index 47b84ecff6..0637823ee5 100644 --- a/docs/dotnet/dotnet-connection-traces.md +++ b/docs/dotnet/dotnet-network-traces.md @@ -2,7 +2,7 @@ linkTitle: HTTP client and server ---> -# Semantic Conventions for HTTP client spans emitted by .NET +# Semantic Conventions for network spans emitted by .NET **Status**: [Experimental][DocumentStatus] @@ -10,22 +10,20 @@ This article defines semantic conventions for HTTP client, DNS and TLS spans emi -- [HTTP Request: wait for connection](#http-request-wait-for-connection) +- [HTTP client request](#http-client-request-wait-for-connection) +- [HTTP client request: wait for connection](#http-client-request-wait-for-connection) - [HTTP connection setup](#http-connection-setup) -- [Socket connection setup](#socket-connection-setup) +- [Socket connect](#socket-connect) - [DNS](#dns) - [TLS](#tls) - [Examples](#examples) - [HTTP request was performed on a connection that was immediately available](#http-request-was-performed-on-a-connection-that-was-immediately-available) - - [HTTP request that has to wait for existing connection to become available](#http-request-that-has-to-wait-for-existing-connection-to-become-available) - [HTTP request has to wait for connection setup](#http-request-has-to-wait-for-connection-setup) - [HTTP request has to wait for connection setup and other requests on that connection to complete](#http-request-has-to-wait-for-connection-setup-and-other-requests-on-that-connection-to-complete) -.NET `HttpClient` reports HTTP client spans according to [HTTP Semantic Conventions](/docs/http/http-spans.md#http-client). - -TODO: we might need to describe some .NET specifics. Leaving it out for now. +.NET `HttpClient` reports HTTP client request spans according to [HTTP Semantic Conventions](/docs/http/http-spans.md#http-client). In addition to HTTP request spans, `HttpClient` reports spans describing HTTP connection establishment and its stages. @@ -33,19 +31,31 @@ While such spans represent low-level details, connection lifetime is usually mea when application is under the load, the rate of connection-related spans is expected to be much lower than the rate of HTTP client spans. Application developers are encouraged to enable corresponding instrumentation in development or test environments. Using connection-level -instrumentation in production should be done with caution as it increases the volume of reported telemetry and has performance overhead that +instrumentation in production should be done after appropriate validation as it increases the volume of reported telemetry and has performance overhead that depends on the application. -## HTTP Request: wait for connection +## HTTP client request + +.NET `HttpClient` reports client request spans according to [HTTP Client Semantic Conventions](/docs/http/http-spans.md#http-client) with the following +specific details: + +- `network.protocol.name`, `network.peer.port`, and `http.request.resend_count` are not reported +- `url.full` is redacted by default - query parameter values are replaced with `*`. Redaction can be disabled by setting `AppContext` switch `System.Net.Http.DisableQueryRedaction` to `true`. +- all attributes are reported after `Activity` is started, none are provided at creation time. + +Corresponding `Activity.OperationName` is `System.Net.Http.HttpRequestOut`, `ActivitySource` name - `System.Net.Http`. +Span with HTTP semantics was added in .NET Core 9. + +## HTTP client request: wait for connection The span describes the time it takes for the HTTP request to obtain a connection from the connection pool. -The span is reported only if there is no connection that's readily available. It's reported as a child of HTTP client span. +The span is reported only if there is no connection that's readily available. It's reported as a child of *HTTP client request* span. The span ends when the connection is obtained - it could happen when an existing connection becomes available or once -a new connection is established, so the time wait-for-connection span tracks is different than one describing [*HTTP connection setup*](#http-connection-setup). +a new connection is established, so the duration of *Wait For Connection* span is different from duration of the [*HTTP connection setup*](#http-connection-setup) span. If a new connection was created to serve the request and the corresponding [*HTTP connection setup*](#http-connection-setup) was reported, the instrumentation adds the -link to the *HTTP connection setup* on the *Wait for connection* span. +link to the *HTTP connection setup* from the *Wait for connection* span. Span name SHOULD be `wait_for_connection {server.address}:{server.port}`. @@ -66,55 +76,7 @@ The time it takes to get a connection from the pool is also reported by the | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `System.OperationCanceledException` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`http.request.method`](/docs/attributes-registry/http.md) | string | HTTP request method. [2] | `GET`; `POST`; `HEAD` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [3] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [5] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - -**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. - -When `error.type` is set to a type (e.g., an exception type), its -canonical class name identifying the type within the artifact SHOULD be used. - -Instrumentations SHOULD document the list of errors they report. - -The cardinality of `error.type` within one instrumentation library SHOULD be low. -Telemetry consumers that aggregate data from multiple instrumentation libraries and applications -should be prepared for `error.type` to have high cardinality at query time when no -additional filters are applied. - -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. - -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: - -* Use a domain-specific attribute -* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. - -**[2]:** HTTP request method value SHOULD be "known" to the instrumentation. -By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) -and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. - -If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override -the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named -OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods -(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). - -HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. -Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. -Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. - -**[3]:** 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]:** 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. - -**[5]:** 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. - - +| [`error.type`](/docs/attributes-registry/error.md) | string | The full name of exception type. | `System.OperationCanceledException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `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. @@ -123,22 +85,6 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -`http.request.method` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. - -| Value | Description | Stability | -|---|---|---| -| `_OTHER` | Any HTTP method that the instrumentation has no prior knowledge of. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `CONNECT` | CONNECT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `DELETE` | DELETE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `GET` | GET method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `HEAD` | HEAD method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `OPTIONS` | OPTIONS method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `PATCH` | PATCH method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `POST` | POST method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `PUT` | PUT method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| `TRACE` | TRACE method. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - - @@ -168,38 +114,18 @@ Added in .NET Core 9. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | The full name of exception type. | `System.OperationCanceledException`; `System.Net.Sockets.SocketException` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](/docs/attributes-registry/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [1] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | 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` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/attributes-registry/server.md) | int | Server port number. [3] | `80`; `8080`; `443` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`url.scheme`](/docs/attributes-registry/url.md) | string | The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. | `https`; `ftp`; `telnet` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. - -When `error.type` is set to a type (e.g., an exception type), its -canonical class name identifying the type within the artifact SHOULD be used. - -Instrumentations SHOULD document the list of errors they report. - -The cardinality of `error.type` within one instrumentation library SHOULD be low. -Telemetry consumers that aggregate data from multiple instrumentation libraries and applications -should be prepared for `error.type` to have high cardinality at query time when no -additional filters are applied. - -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. - -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: +**[1]:** 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. -* 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. +**[2]:** 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]:** 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]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. - -**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[3]:** 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. @@ -216,20 +142,20 @@ it's RECOMMENDED to: -## Socket connection setup +## Socket connect The span describes the establishment of the socket connection. -It's different from [*HTTP connection setup*](#http-connection-setup) span, which covers the DNS and TLS handshake duration in addition to socket connection setup. +It's different from [*HTTP connection setup*](#http-connection-setup) span, which also covers the DNS lookup and TLS handshake. -When *Socket connection setup* span is reported along with *HTTP connection setup* span, the socket span becomes a child of HTTP connection setup. +When *Socket connect* span is reported along with *HTTP connection setup* span, the socket span becomes a child of HTTP connection setup. -Span name SHOULD be `socket connection_setup {network.peer.address}:{network.peer.port}`. +Span name SHOULD be `socket connect {network.peer.address}:{network.peer.port}`. Span kind SHOULD be `CLIENT`. Corresponding `Activity.OperationName` is `System.Net.Sockets.ConnectionSetup`, `ActivitySource` name - `System.Net.Sockets`. Added in .NET Core 9. - + @@ -238,41 +164,41 @@ Added in .NET Core 9. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Socket error code. [1] | `connection_refused`; `address_not_available` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`network.peer.address`](/docs/attributes-registry/network.md) | string | Peer address of the network connection - IP address or Unix domain socket name. | `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.protocol.version`](/docs/attributes-registry/network.md) | string | The actual version of the protocol used for network communication. [2] | `1.1`; `2` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [3] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [4] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - -**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. - -When `error.type` is set to a type (e.g., an exception type), its -canonical class name identifying the type within the artifact SHOULD be used. - -Instrumentations SHOULD document the list of errors they report. - -The cardinality of `error.type` within one instrumentation library SHOULD be low. -Telemetry consumers that aggregate data from multiple instrumentation libraries and applications -should be prepared for `error.type` to have high cardinality at query time when no -additional filters are applied. - -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. - -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: - -* Use a domain-specific attribute -* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. - -**[2]:** 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]:** The value SHOULD be normalized to lowercase. +| [`network.peer.port`](/docs/attributes-registry/network.md) | int | Peer port number of the network connection. | `65123` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/attributes-registry/network.md) | string | [OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.type`](/docs/attributes-registry/network.md) | string | [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. [3] | `ipv4`; `ipv6` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1]:** The following errors codes are reported: + +- `network_down` +- `address_already_in_use` +- `interrupted` +- `in_progress` +- `already_in_progress` +- `address_not_available` +- `address_family_not_supported` +- `connection_refused` +- `fault` +- `invalid_argument` +- `is_connected` +- `network_unreachable` +- `host_unreachable` +- `no_buffer_space_available` +- `timed_out` +- `access_denied` +- `protocol_type` + +See socket errors on [Windows]( https://learn.microsoft.com/windows/win32/api/winsock2/nf-winsock2-connect#return-value) and [Linux](https://man7.org/linux/man-pages/man2/connect.2.html) for more details. + +**[2]:** 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. -**[4]:** The value SHOULD be normalized to lowercase. +**[3]:** The value SHOULD be normalized to lowercase. @@ -307,17 +233,22 @@ different processes could be listening on TCP port 12345 and UDP port 12345. -## DNS - -The span describes DNS lookup duration and outcome. +## DNS resolution +The span describes DNS lookups performed with one of the methods on [System.Net.Dns](https://learn.microsoft.com/dotnet/api/system.net.dns) class. DNS lookup duration is also reported by [`dns.lookup.duration` metric](/docs/dotnet/dotnet-dns-metrics.md#metric-dnslookupduration). -When *DNS* span is reported along with *HTTP connection setup* and *Socket connection setup* span, the *DNS* span becomes a child of *HTTP connection setup* -and a sibling of *Socket connection setup*. +DNS spans track logical operations rather than physical DNS calls and the actual behavior depends on the resolver implementation which could be changed in the future versions of .NET. +.NET 9 uses OS DNS resolver which may do zero or more physical lookups for one API call. + +When *DNS* span is reported along with *HTTP connection setup* and *Socket connect* span, the *DNS* span becomes a child of *HTTP connection setup* +and a sibling of *Socket connect*. + +DNS spans are reported for both lookups and reverse lookups. -Span name SHOULD be `DNS {dns.question.name}`. -Span kind SHOULD be `CLIENT` +Lookup (IP addresses from host name) span name SHOULD be `DNS lookup {dns.question.name}`. TODO? +Reverse lookup (host names from IP address) span name SHOULD be `DNS reverse lookup {dns.question.name}`. +Span kind SHOULD be `CLIENT`. Corresponding `Activity.OperationName` is `System.Net.NameResolution.DnsLookup`, `ActivitySource` name - `System.Net.NameResolution`. Added in .NET Core 9 @@ -331,31 +262,21 @@ Added in .NET Core 9 | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`dns.answer`](/docs/attributes-registry/dns.md) | string[] | The list of resolved IPv4 or IPv6 addresses. | `["10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`dns.question.name`](/docs/attributes-registry/dns.md) | string | The name being queried. [1] | `www.example.com`; `opentelemetry.io` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - -**[1]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. - -**[2]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. - -When `error.type` is set to a type (e.g., an exception type), its -canonical class name identifying the type within the artifact SHOULD be used. +| [`error.type`](/docs/attributes-registry/error.md) | string | Error code returned by the DNS resolver. [1] | `host_not_found`; `try_again` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`dns.answers`](/docs/attributes-registry/dns.md) | string[] | List of resolved IP addresses or a single element containing domain name. | `["10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`dns.question.name`](/docs/attributes-registry/dns.md) | string | The domain name or IP address being queried. [2] | `www.example.com`; `opentelemetry.io` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -Instrumentations SHOULD document the list of errors they report. +**[1]:** The following errors are reported: -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. +- `host_not_found` +- `try_again` +- `no_recovery` +- `address_family_not_supported` +- the full exception type name. -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. +See [SocketError](https://learn.microsoft.com/dotnet/api/system.net.sockets.socketerror) for more details. -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: - -* Use a domain-specific attribute -* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. +**[2]:** If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. @@ -372,15 +293,14 @@ it's RECOMMENDED to: -## TLS +## TLS handshake -The span describes TLS handshake. +The span describes TLS client or server handshake performed with [System.Net.Security.SslStream](https://learn.microsoft.com/dotnet/api/system.net.security.sslstream). -Span name SHOULD be `TLS {dns.question.name}`. // TODO - decide on TLS! -Span kind SHOULD be `CLIENT` +Span name SHOULD be `TLS client {server.address}` when authenticating on the client side and `TLS server` when authenticating the server. +Span kind SHOULD be `CLIENT` in both cases. -When *TLS* span is reported along with *HTTP connection setup* and *Socket connection setup* span, the *DNS* span becomes a child of *HTTP connection setup* -and a sibling of *Socket connection setup*. +When *TLS* span is reported for client-side authentication along with *HTTP connection setup* and *Socket connect* span, the *TLS* span becomes a child of *HTTP connection setup*. Corresponding `Activity.OperationName` is `System.Net.Security.TlsHandshake`, `ActivitySource` name - `System.Net.Security`. Added in .NET Core 9. @@ -394,30 +314,16 @@ Added in .NET Core 9. | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`tls.client.server_name`](/docs/attributes-registry/tls.md) | string | Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. | `opentelemetry.io` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `TODO` | `Conditionally Required` if and only if an error has occurred. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/attributes-registry/server.md) | string | The [server name indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) used in the 'Client Hello' message during TLS handshake. [2] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` when authenticating the client. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | [`tls.protocol.name`](/docs/attributes-registry/tls.md) | string | Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `ssl`; `tls` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`tls.protocol.version`](/docs/attributes-registry/tls.md) | string | Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html#RETURN-VALUES) | `1.2`; `3` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -**[1]:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. - -When `error.type` is set to a type (e.g., an exception type), its -canonical class name identifying the type within the artifact SHOULD be used. - -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. +**[1]:** The following errors codes are reported: -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. +TODO -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), -it's RECOMMENDED to: - -* Use a domain-specific attribute -* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. +**[2]:** 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. @@ -452,17 +358,6 @@ If connection is immediately available for the request, `HttpClient` creates one <------------------ GET / (CLIENT, trace=t1, span=s1) ---------------------------> ``` -### HTTP request that has to wait for existing connection to become available - -If connection was not immediately available for the request, `HttpClient` creates span for HTTP request and -*Wait for connection* span. In this example, the existing connection became available, so no additional spans -related to connection setup were reported. - -``` -<------------------ GET / (CLIENT, trace=t1, span=s1) ---------------------------> -<-- wait_for_connection host:port (INTERNAL, trace=t1, span=s2) --> -``` - ### HTTP request has to wait for connection setup If connection was not immediately available for the request, `HttpClient` creates span for HTTP request and @@ -476,7 +371,7 @@ connection was created. There was no cached DNS record for the host. <--------- HTTP connection_setup (trace=t2, span=s3) --------> <--- DNS ---> - <---- socket connection_setup ----> + <--------- socket connect --------> <--- TLS ---> ``` @@ -493,7 +388,7 @@ became available for this request, other requests were performed on it. <--- HTTP connection_setup - (trace=t2, span=s3) ---> <-- DNS --> - <-- socket connection_setup --> + <------ socket connect -------> <-- TLS --> ``` diff --git a/model/registry/dns.yaml b/model/registry/dns.yaml index 9b328d1075..05388463ee 100644 --- a/model/registry/dns.yaml +++ b/model/registry/dns.yaml @@ -16,7 +16,7 @@ groups: as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. - - id: answer + - id: answers type: string[] stability: experimental brief: The list of resolved IPv4 or IPv6 addresses. diff --git a/model/trace/dotnet/dotnet-connections.yaml b/model/trace/dotnet/dotnet-connections.yaml deleted file mode 100644 index 2baca88cca..0000000000 --- a/model/trace/dotnet/dotnet-connections.yaml +++ /dev/null @@ -1,92 +0,0 @@ -groups: - - id: dotnet.http.request.wait_for_connection - type: span - span_kind: internal - brief: 'The span is emitted by .NET runtime and describes the time it takes for HTTP request to obtain a connection to run on.' - note: | - The span is reported only if there are no connections that are readily available to perform the request. - The span ends when the connection is obtained - it could happen if an existing connection became available or - a new connection was established, so the time wait-for-connection span tracks is different than `dotnet.http.connection_setup`. - - The time it takes to get a connection from the pool is also reported by the - [`http.client.request.time_in_queue` metric](/docs/dotnet/dotnet-http-metrics.md#metric-httpclientrequesttime_in_queue). - - `Activity.OperationName`: `System.Net.Http.WaitForConnection` - `ActivitySource` name: `"System.Net.Http` # TODO - should it be different from HTTP requests so that users can opt-in independently? - Added in: .NET Core 9 - attributes: - - ref: http.request.method - - ref: network.protocol.version - - ref: server.address - - ref: server.port - - ref: url.scheme - - ref: error.type - examples: ["System.OperationCanceledException"] - - - id: dotnet.http.connection_setup - type: span - span_kind: client - brief: > - The span is emitted by .NET runtime and describes the establishment of the HTTP connection. It includes - the time it takes to resolve the DNS, establish the socket connection, and perform the TLS handshake. - - It's different from `dotnet.http.connection` span, which describes the lifetime of the HTTP connection. - note: | - `Activity.OperationName`: `System.Net.Http.Connections.ConnectionSetup` - `ActivitySource` name: `System.Net.Http.Connections` TODO - should be different than connection? - Added in: .NET Core 9 - attributes: - - ref: network.protocol.version - - ref: network.peer.address - - ref: server.address - - ref: server.port - - ref: error.type - - ref: url.scheme - - - id: dotnet.socket.connection_setup - type: span - span_kind: client - brief: > - The span is emitted by .NET runtime and describes the establishment of the socket connection. - note: | - `Activity.OperationName`: `System.Net.Sockets.ConnectionSetup` - `ActivitySource` name: `System.Net.Sockets` - Added in: .NET Core 9 - attributes: - - ref: network.protocol.version - - ref: network.peer.address - - ref: network.transport - - ref: network.type - - ref: error.type - - - id: dotnet.dns.lookup - type: span - span_kind: client - brief: > - The span is emitted by .NET runtime and describes DNS lookup. - note: | - DNS lookup duration is also reported by - [`dns.lookup.duration` metric](/docs/dotnet/dotnet-dns-metrics.md#metric-dnslookupduration). - - `Activity.OperationName`: `System.Net.NameResolution.DnsLookup` - `ActivitySource` name: `System.Net.NameResolution` - Added in: .NET Core 9 - attributes: - - ref: dns.question.name - - ref: dns.answer - - ref: error.type - - - id: dotnet.tls.handshake - type: span - span_kind: client - brief: > - The span is emitted by .NET runtime and describes TLS handshake. - note: | - `Activity.OperationName`: `System.Net.Security.TlsHandshake` - `ActivitySource` name: `System.Net.Security` - Added in: .NET Core 9 - attributes: - - ref: tls.protocol.name - - ref: tls.protocol.version - - ref: tls.client.server_name - - ref: error.type \ No newline at end of file diff --git a/model/trace/dotnet/dotnet-network.yaml b/model/trace/dotnet/dotnet-network.yaml new file mode 100644 index 0000000000..57983f0bd7 --- /dev/null +++ b/model/trace/dotnet/dotnet-network.yaml @@ -0,0 +1,116 @@ +groups: + - id: dotnet.http.request.wait_for_connection + type: span + span_kind: internal + brief: 'The span describes the time it takes for HTTP request to obtain a connection to run on.' + attributes: + - ref: error.type + requirement_level: + conditionally_required: if and only if an error has occurred. + brief: The full name of exception type. + note: "" + examples: ["System.OperationCanceledException"] + + - id: dotnet.http.connection_setup + type: span + span_kind: client + brief: > + The span describes the establishment of the HTTP connection. It includes + the time it takes to resolve the DNS, establish the socket connection, and perform the TLS handshake. + attributes: + - ref: network.protocol.version + - ref: network.peer.address + - ref: server.address + - ref: server.port + - ref: error.type + brief: The full name of exception type. + note: "" + requirement_level: + conditionally_required: if and only if an error has occurred. + examples: ["System.OperationCanceledException", "System.Net.Sockets.SocketException"] + - ref: url.scheme + + - id: dotnet.socket.connect + type: span + span_kind: client + brief: > + The span describes the establishment of the socket connection. + attributes: + - ref: network.peer.port + - ref: network.peer.address + - ref: network.transport + - ref: network.type + - ref: error.type + brief: "Socket error code." + requirement_level: + conditionally_required: if and only if an error has occurred. + note: | + The following errors codes are reported: + + - `network_down` + - `address_already_in_use` + - `interrupted` + - `in_progress` + - `already_in_progress` + - `address_not_available` + - `address_family_not_supported` + - `connection_refused` + - `fault` + - `invalid_argument` + - `is_connected` + - `network_unreachable` + - `host_unreachable` + - `no_buffer_space_available` + - `timed_out` + - `access_denied` + - `protocol_type` + + See socket errors on [Windows]( https://learn.microsoft.com/windows/win32/api/winsock2/nf-winsock2-connect#return-value) and [Linux](https://man7.org/linux/man-pages/man2/connect.2.html) for more details. + examples: ["connection_refused", "address_not_available"] + + - id: dotnet.dns.lookup + type: span + span_kind: client + brief: > + The span describes DNS lookup. + attributes: + - ref: dns.question.name + brief: The domain name or IP address being queried. + - ref: dns.answers + brief: List of resolved IP addresses or a single element containing domain name. + - ref: error.type + brief: Error code returned by the DNS resolver. + requirement_level: + conditionally_required: if and only if an error has occurred. + note: | + The following errors are reported: + + - `host_not_found` + - `try_again` + - `no_recovery` + - `address_family_not_supported` + - the full exception type name. + + See [SocketError](https://learn.microsoft.com/dotnet/api/system.net.sockets.socketerror) for more details. + examples: ["host_not_found", "try_again" ] + + - id: dotnet.tls.handshake + type: span + span_kind: client + brief: > + The span describes TLS handshake. + attributes: + - ref: tls.protocol.name + - ref: tls.protocol.version + - ref: server.address + brief: The [server name indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) used in the 'Client Hello' message during TLS handshake. + requirement_level: + recommended: when authenticating the client. + - ref: error.type + requirement_level: + conditionally_required: if and only if an error has occurred. + note: | + The following errors codes are reported: + + TODO + examples: ["TODO"] \ No newline at end of file