Skip to content

Commit 4e7c077

Browse files
author
Liudmila Molkova
authored
Add .NET network + HTTP connection spans (#1192)
1 parent bb3d1cc commit 4e7c077

File tree

7 files changed

+687
-6
lines changed

7 files changed

+687
-6
lines changed

.chloggen/1192.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
change_type: enhancement
2+
component: dotnet
3+
note: >
4+
Define .NET-specific network spans for DNS resolution, TLS handshake,
5+
and socket connections, along with HTTP-level spans to (optionally) record
6+
relationships between HTTP requests and connections.
7+
issues: [ 1192 ]

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
/model/container/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers
8989
/model/oci/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-container-approvers
9090

91-
# .NET semantic conventions
91+
# .NET semantic conventions approvers
9292
/docs/dotnet/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers
9393
/docs/runtime/dotnet-metrics.md @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver
9494
/model/aspnetcore/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-dotnet-approver @open-telemetry/semconv-http-approvers

docs/dotnet/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
linkTitle: .NET
33
--->
44

5-
# Semantic conventions for .NET metrics
5+
# Semantic conventions for .NET
66

7-
**Status**: [Stable][DocumentStatus]
7+
This article documents semantic conventions for metrics and traces emitted by the .NET runtime and individual components in the .NET ecosystem.
88

9-
This article documents semantic conventions for metrics emitted by the .NET runtime and individual components in the .NET ecosystem.
9+
The following span are currently supported:
10+
11+
- [HTTP client, DNS, and TLS](dotnet-network-traces.md): Semantic Conventions for HTTP client and connection-related *spans*.
1012

1113
The following metrics are currently supported:
1214

@@ -15,5 +17,4 @@ The following metrics are currently supported:
1517
* [HTTP](dotnet-http-metrics.md): Semantic Conventions for HTTP client and server *metrics*.
1618
* [Kestrel](dotnet-kestrel-metrics.md): Semantic Conventions for Kestrel web server *metrics*.
1719
* [SignalR](dotnet-signalr-metrics.md): Semantic Conventions for SignalR server *metrics*.
18-
19-
[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
20+
* [Runtime](/docs/runtime/dotnet-metrics.md): Semantic conventions for .NET Runtime *metrics*.

docs/dotnet/dotnet-network-traces.md

Lines changed: 462 additions & 0 deletions
Large diffs are not rendered by default.

docs/registry/attributes/dns.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This document defines the shared attributes used to report a DNS query.
99

1010
| Attribute | Type | Description | Examples | Stability |
1111
|---|---|---|---|---|
12+
| <a id="dns-answers" href="#dns-answers">`dns.answers`</a> | string[] | The list of IPv4 or IPv6 addresses resolved during DNS lookup. | `["10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]` | ![Development](https://img.shields.io/badge/-development-blue) |
1213
| <a id="dns-question-name" href="#dns-question-name">`dns.question.name`</a> | string | The name being queried. [1] | `www.example.com`; `opentelemetry.io` | ![Development](https://img.shields.io/badge/-development-blue) |
1314

1415
**[1] `dns.question.name`:** 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.

model/dns/registry.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@ groups:
1616
as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped.
1717
Tabs, carriage returns, and line feeds should be converted to \t, \r, and
1818
\n respectively.
19+
- id: dns.answers
20+
type: string[]
21+
stability: development
22+
brief: The list of IPv4 or IPv6 addresses resolved during DNS lookup.
23+
examples:
24+
- ["10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]

model/dotnet/network-spans.yaml

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
groups:
2+
- id: span.dotnet.http.request.wait_for_connection.internal
3+
type: span
4+
stability: development
5+
span_kind: internal
6+
brief: The span describes the time it takes for the HTTP request to obtain a connection from the connection pool.
7+
note: |
8+
The span is reported only if there was no connection readily available when request has started.
9+
It's reported as a child of *HTTP client request* span.
10+
11+
The span ends when the connection is obtained - it could happen when an existing connection becomes available or once
12+
a new connection is established, so the duration of *Wait For Connection* span is different from duration of the
13+
[*HTTP connection setup*](/docs/dotnet/dotnet-network-traces.md#http-connection-setup) span.
14+
15+
The time it takes to get a connection from the pool is also reported by the
16+
[`http.client.request.time_in_queue` metric](/docs/dotnet/dotnet-http-metrics.md#metric-httpclientrequesttime_in_queue).
17+
18+
Corresponding `Activity.OperationName` is `Experimental.System.Net.Http.Connections.WaitForConnection`, `ActivitySource` name - `Experimental.System.Net.Http`.
19+
Added in .NET 9.
20+
21+
**Span name** SHOULD be `HTTP wait_for_connection {server.address}:{server.port}`.
22+
attributes:
23+
- ref: error.type
24+
requirement_level:
25+
conditionally_required: if and only if an error has occurred.
26+
brief: >
27+
One of the [HTTP Request errors](https://learn.microsoft.com/dotnet/api/system.net.http.httprequesterror) in snake_case, or a full exception type.
28+
note: ""
29+
examples: ["version_negotiation_error", "System.OperationCanceledException"]
30+
31+
- id: span.dotnet.http.connection_setup.internal
32+
type: span
33+
stability: development
34+
span_kind: internal
35+
brief: >
36+
The span describes the establishment of the HTTP connection. It includes the time it takes
37+
to resolve the DNS, establish the socket connection, and perform the TLS handshake.
38+
note: |
39+
There is no parent-child relationship between the [*HTTP client request*](/docs/dotnet/dotnet-network-traces.md#http-client-request) and the
40+
[*HTTP connection setup*]/docs/dotnet/dotnet-network-traces.md(/docs/dotnet/dotnet-network-traces.md#http-connection-setup) spans;
41+
the latter will always be a root span, defining a separate trace.
42+
43+
However, if the connection attempt represented by the [*HTTP connection setup*](/docs/dotnet/dotnet-network-traces.md#http-connection-setup) span results in a
44+
successful HTTP connection, and that connection is picked up by a request to serve it, the instrumentation adds a link
45+
to the [*HTTP client request*](/docs/dotnet/dotnet-network-traces.md#http-client-request) span pointing to the *HTTP connection setup* span.
46+
I.e., each request is linked to the connection that served this request.
47+
48+
Corresponding `Activity.OperationName` is `Experimental.System.Net.Http.Connections.ConnectionSetup`, `ActivitySource` name - `Experimental.System.Net.Http.Connections`.
49+
Added in .NET 9.
50+
51+
**Span name** SHOULD be `HTTP connection_setup {server.address}:{server.port}`.
52+
attributes:
53+
- ref: network.peer.address
54+
brief: Peer IP address of the socket connection.
55+
note: >
56+
The `network.peer.address` attribute is available only if the connection was successfully established and only for IP sockets.
57+
- ref: server.address
58+
- ref: server.port
59+
- ref: error.type
60+
brief: >
61+
One of the [HTTP Request errors](https://learn.microsoft.com/dotnet/api/system.net.http.httprequesterror) in snake_case, or a full exception type.
62+
note: ""
63+
requirement_level:
64+
conditionally_required: if and only if an error has occurred.
65+
examples: ["name_resolution_error", "System.OperationCanceledException"]
66+
- ref: url.scheme
67+
68+
- id: span.dotnet.socket.connect.internal
69+
type: span
70+
stability: development
71+
span_kind: internal
72+
brief: >
73+
The span describes the establishment of the socket connection.
74+
note: |
75+
It's different from [*HTTP connection setup*](/docs/dotnet/dotnet-network-traces.md#http-connection-setup) span, which also covers the DNS lookup and TLS handshake.
76+
77+
When *socket connect* span is reported along with *HTTP connection setup* span, the socket span becomes a child of HTTP connection setup.
78+
79+
Corresponding `Activity.OperationName` is `Experimental.System.Net.Sockets.Connect`, `ActivitySource` name - `Experimental.System.Net.Sockets`.
80+
Added in .NET 9.
81+
82+
**Span name** SHOULD be `socket connect {network.peer.address}:{network.peer.port}` when socket address family has a
83+
notion of port and `socket connect {network.peer.address}`
84+
otherwise.
85+
attributes:
86+
- ref: network.peer.port
87+
requirement_level:
88+
recommended: If port is supported for the socket address family.
89+
- ref: network.peer.address
90+
- ref: network.type
91+
requirement_level:
92+
recommended: if `network.peer.address` is an IP address.
93+
- ref: network.transport
94+
examples: ['tcp', 'udp', 'unix']
95+
requirement_level:
96+
recommended: If value is not `tcp`. When missing, the value is assumed to be `tcp`.
97+
- ref: error.type
98+
brief: "Socket error code."
99+
requirement_level:
100+
conditionally_required: if and only if an error has occurred.
101+
note: |
102+
The following errors codes are reported:
103+
104+
- `network_down`
105+
- `address_already_in_use`
106+
- `interrupted`
107+
- `in_progress`
108+
- `already_in_progress`
109+
- `address_not_available`
110+
- `address_family_not_supported`
111+
- `connection_refused`
112+
- `fault`
113+
- `invalid_argument`
114+
- `is_connected`
115+
- `network_unreachable`
116+
- `host_unreachable`
117+
- `no_buffer_space_available`
118+
- `timed_out`
119+
- `access_denied`
120+
- `protocol_type`
121+
122+
See socket errors on [Windows](https://learn.microsoft.com/windows/win32/api/winsock2/nf-winsock2-connect#return-value) and
123+
[Linux](https://man7.org/linux/man-pages/man2/connect.2.html) for more details.
124+
examples: ["connection_refused", "address_not_available"]
125+
126+
- id: span.dotnet.dns.lookup.internal
127+
type: span
128+
stability: development
129+
span_kind: internal
130+
brief: >
131+
The span describes DNS lookup or reverse lookup performed with one of the methods
132+
on [System.Net.Dns](https://learn.microsoft.com/dotnet/api/system.net.dns) class.
133+
note: |
134+
DNS spans track logical operations rather than physical DNS calls and the actual behavior depends on the
135+
resolver implementation which could be changed in the future versions of .NET.
136+
.NET 9 uses OS DNS resolver which may do zero or more physical lookups for one API call.
137+
138+
When the *DNS lookup* span is reported along with *HTTP connection setup* and *socket connect* span,
139+
the *DNS lookup* span span becomes a child of *HTTP connection setup* and a sibling of *socket connect*.
140+
141+
DNS lookup duration is also reported by [`dns.lookup.duration` metric](/docs/dotnet/dotnet-dns-metrics.md#metric-dnslookupduration).
142+
143+
Corresponding `Activity.OperationName` is `Experimental.System.Net.NameResolution.DnsLookup`, `ActivitySource` name - `Experimental.System.Net.NameResolution`.
144+
Added in .NET 9.
145+
146+
**Span name** SHOULD be `DNS lookup {dns.question.name}` for DNS lookup (IP addresses from host name)
147+
and `DNS reverse lookup {dns.question.name}` for reverse lookup (host names from IP address).
148+
attributes:
149+
- ref: dns.question.name
150+
brief: The domain name or an IP address being queried.
151+
note: ""
152+
- ref: dns.answers
153+
brief: List of resolved IP addresses (for DNS lookup) or a single element containing domain name (for reverse lookup).
154+
requirement_level:
155+
recommended: if DNS lookup was successful.
156+
- ref: error.type
157+
brief: The error code or exception name returned by [System.Net.Dns](https://learn.microsoft.com/dotnet/api/system.net.dns).
158+
requirement_level:
159+
conditionally_required: if and only if an error has occurred.
160+
note: |
161+
The following errors are reported:
162+
163+
- `host_not_found`
164+
- `try_again`
165+
- `no_recovery`
166+
- `address_family_not_supported`
167+
- the full exception type name
168+
169+
See [SocketError](https://learn.microsoft.com/dotnet/api/system.net.sockets.socketerror) for more details.
170+
examples: ["host_not_found", "try_again" ]
171+
172+
- id: span.dotnet.tls.handshake.internal
173+
type: span
174+
span_kind: internal
175+
stability: development
176+
brief: >
177+
The span describes TLS client or server handshake performed with [System.Net.Security.SslStream](https://learn.microsoft.com/dotnet/api/system.net.security.sslstream).
178+
note: |
179+
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*.
180+
181+
Corresponding `Activity.OperationName` is `Experimental.System.Net.Security.TlsHandshake`, `ActivitySource` name - `Experimental.System.Net.Security`.
182+
Added in .NET 9.
183+
184+
**Span name** SHOULD be `TLS client handshake {server.address}` when authenticating on the client
185+
side and `TLS server handshake` when authenticating the server.
186+
187+
**Span kind** SHOULD be `INTERNAL` in both cases.
188+
attributes:
189+
- ref: tls.protocol.name
190+
requirement_level:
191+
recommended: when available
192+
- ref: tls.protocol.version
193+
requirement_level:
194+
recommended: when available
195+
- ref: server.address
196+
brief: The [server name indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) used in the 'Client Hello' message during TLS handshake.
197+
requirement_level:
198+
recommended: when authenticating the client.
199+
examples: ["opentelemetry.io", "example.com"]
200+
- ref: error.type
201+
requirement_level:
202+
conditionally_required: if and only if an error has occurred.
203+
note: ""
204+
examples: ["System.Net.Security.Authentication.AuthenticationException", "System.OperationCanceledException"]

0 commit comments

Comments
 (0)