.NET 发出的网络 Span 的语义约定

状态: 混合

本文档定义了 .NET 发出的 HTTP 客户端、DNS 和 TLS Span 的语义约定。

.NET 的 HttpClient 根据 HTTP 语义约定报告 HTTP 客户端请求 Span。

除了稳定的 HTTP 客户端请求 Span 外,HTTP 客户端处理程序还报告描述 HTTP 连接建立及其阶段的实验性 Span。

连接的生命周期通常以分钟为单位,因此当应用程序处于负载下但连接池未过载时,连接相关 Span 的速率预计会远低于 HTTP 客户端请求 Span 的速率。

鼓励应用程序在生产环境中默认启用HTTP 客户端请求 Span。

连接级 Span 是实验性的——它们的语义在未来可能会以破坏性的方式更改。在生产环境中使用连接级仪表化应在适当验证后进行。

连接相关的 Span 仅由 HttpClientHandlerSocketsHttpHandler 报告,它们可能在某些平台上不受支持,或可能不被特定应用程序使用。

HTTP 客户端请求

状态: 稳定

.NET HttpClient 根据 HTTP 客户端语义约定报告客户端请求 Span,具体细节如下:

  • network.protocol.namenetwork.peer.porthttp.request.resend_count 属性未报告
  • url.full 默认情况下会被隐藏——查询参数值会被替换为*。可以通过将 AppContext 开关 System.Net.Http.DisableQueryRedaction 设置为 true 来禁用隐藏。
  • 当报告 error.type 属性时,它包含以下之一:snake_case 格式的 HTTP 请求错误、完整的异常类型名称,或收到的状态码的字符串表示。
  • 所有属性都在 Activity 启动后报告,创建时未提供任何属性。
  • 如果发生重定向,每个重定向的请求都会报告为一个单独的 Span。
  • SocketsHttpHandler 可能会在连接失败时重试请求。这些重试不会报告为单独的 Span。

相应的 Activity.OperationNameSystem.Net.Http.HttpRequestOutActivitySource 名称是 System.Net.Http。Span(带 HTTP 语义)已添加到 .NET 9。

HTTP 客户端请求:等待连接

状态: 开发中

此 Span 描述了 HTTP 请求从连接池获取连接所需的时间。

当请求开始时,如果没有现成的连接,则会报告此 Span。它会作为HTTP 客户端请求 Span 的子 Span 报告。

当获得连接时,此 Span 结束——这可能发生在现有连接可用时,或一旦建立新连接时。因此,等待连接 Span 的持续时间与 HTTP 连接设置 Span 的持续时间不同。

从池中获取连接所需的时间也由 http.client.request.time_in_queue 指标报告。

相应的 Activity.OperationNameExperimental.System.Net.Http.Connections.WaitForConnectionActivitySource 名称是 Experimental.System.Net.Http。添加于 .NET 9。

Span 名称应为 HTTP wait_for_connection {server.address}:{server.port}

Span 类型应为 INTERNAL

**Span 状态**应遵循 记录错误文档。

Attributes

Stability需求级别Value Type描述Example Values
error.typeStable如果发生错误,则为条件必需字符串snake_case 格式的 HTTP 请求错误之一,或完整的异常类型。version_negotiation_errorSystem.OperationCanceledException

error.type 具有以下已知值列表。如果其中一个适用,则必须使用相应的值;否则,可以使用自定义值。

描述Stability
_OTHER当检测不到自定义值时使用的回退错误值。Stable

HTTP 连接设置

状态: 开发中

此 Span 描述了 HTTP 连接的建立。它包括 DNS 解析、套接字连接建立和 TLS 握手所需的时间。

HTTP 客户端请求 Span 和 [HTTP 连接设置](/docs/dotnet/dotnet-network-traces.md#http-connection-setup) Span 之间没有父子关系;后者始终是一个根 Span,定义一个单独的跟踪。

但是,如果HTTP 连接设置 Span 所代表的连接尝试成功建立了一个 HTTP 连接,并且该连接被一个请求使用,则仪表化会在HTTP 客户端请求 Span 中添加一个指向HTTP 连接设置 Span 的链接。也就是说,每个请求都链接到为该请求服务的连接。

相应的 Activity.OperationNameExperimental.System.Net.Http.Connections.ConnectionSetupActivitySource 名称是 Experimental.System.Net.Http.Connections。添加于 .NET 9。

Span 名称应为 HTTP connection_setup {server.address}:{server.port}

Span 类型应为 INTERNAL

**Span 状态**应遵循 记录错误文档。

Attributes

Stability需求级别Value Type描述Example Values
error.typeStable如果发生错误,则为条件必需字符串snake_case 格式的 HTTP 请求错误之一,或完整的异常类型。name_resolution_errorSystem.OperationCanceledException
network.peer.addressStable推荐字符串套接字连接的对等 IP 地址。[1]10.1.2.80/tmp/my.sock
server.addressStable推荐字符串服务器域名(如果无需反向 DNS 查询即可获得);否则,为 IP 地址或 Unix 套接字名称。[2]example.com10.1.2.80/tmp/my.sock
server.portStable推荐int服务器端口号。[3]80; 8080; 443
url.schemeStable推荐字符串The URI 方案组件,用于标识所使用的协议。httpsftptelnet

[1] network.peer.address network.peer.address 属性仅在连接成功建立且仅适用于 IP 套接字时可用。

[2] server.address 当从客户端观察时,并且通过中间人通信时,server.address 应代表任何中间人(例如代理)之后的服务器地址,如果可用的话。

[3] server.port: 从客户端观察时,并且在通过中介进行通信时,server.port 应代表任何中介(例如代理)之后的服务器端口,如果可用。


error.type 具有以下已知值列表。如果其中一个适用,则必须使用相应的值;否则,可以使用自定义值。

描述Stability
_OTHER当检测不到自定义值时使用的回退错误值。Stable

DNS 查询

状态: 开发中

此 Span 描述了使用 System.Net.Dns 类上的方法之一执行的 DNS 查询或反向查询。

DNS Span 跟踪逻辑操作而不是物理 DNS 调用,实际行为取决于解析器实现,这在 .NET 的未来版本中可能会发生更改。.NET 9 使用操作系统 DNS 解析器,它可能对一个 API 调用执行零次或多次物理查询。

DNS 查询 Span 与HTTP 连接设置套接字连接 Span 一起报告时,DNS 查询 Span 将成为HTTP 连接设置的子 Span,并与套接字连接成为同级 Span。

DNS 查询的持续时间也由 dns.lookup.duration 指标报告。

相应的 Activity.OperationNameExperimental.System.Net.NameResolution.DnsLookupActivitySource 名称是 Experimental.System.Net.NameResolution。添加于 .NET 9。

Span 名称对于 DNS 查询(从主机名到 IP 地址)应为 DNS lookup {dns.question.name},对于反向查询(从 IP 地址到主机名)应为 DNS reverse lookup {dns.question.name}

Span 类型应为 INTERNAL

**Span 状态**应遵循 记录错误文档。

Attributes

Stability需求级别Value Type描述Example Values
error.typeStable如果发生错误,则为条件必需字符串System.Net.Dns 返回的错误代码或异常名称。[1]host_not_foundtry_again
dns.answersDevelopment如果 DNS 查询成功,则Recommendedstring[]解析的 IP 地址列表(用于 DNS 查询)或包含域名的单个元素(用于反向查询)。["10.0.0.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]
dns.question.nameDevelopment推荐字符串正在查询的域名或 IP 地址。www.example.comopentelemetry.io

[1] error.type 报告以下错误

  • host_not_found
  • try_again
  • no_recovery
  • address_family_not_supported
  • 完整的异常类型名称

有关更多详细信息,请参阅 SocketError


error.type 具有以下已知值列表。如果其中一个适用,则必须使用相应的值;否则,可以使用自定义值。

描述Stability
_OTHER当检测不到自定义值时使用的回退错误值。Stable

Socket 连接

状态: 开发中

此 Span 描述了套接字连接的建立。

它与 HTTP 连接设置 Span 不同,后者还涵盖了 DNS 查询和 TLS 握手。

套接字连接 Span 与HTTP 连接设置 Span 一起报告时,套接字 Span 将成为 HTTP 连接设置的子 Span。

相应的 Activity.OperationNameExperimental.System.Net.Sockets.ConnectActivitySource 名称是 Experimental.System.Net.Sockets。添加于 .NET 9。

Span 名称应为 socket connect {network.peer.address}:{network.peer.port}(当套接字地址族具有端口概念时)和 socket connect {network.peer.address}(否则)。

Span 类型应为 INTERNAL

**Span 状态**应遵循 记录错误文档。

Attributes

Stability需求级别Value Type描述Example Values
error.typeStable如果发生错误,则为条件必需字符串套接字错误代码。[1]connection_refusedaddress_not_available
network.peer.addressStable推荐字符串网络连接的对端地址 - IP 地址或 Unix 域套接字名称。10.1.2.80/tmp/my.sock
network.peer.portStable推荐 [2]int网络连接的对等端口号。65123
network.transportStable推荐 [3]字符串OSI 传输层进程间通信方法。[4]tcpudpunix
network.typeStable如果 network.peer.address 是 IP 地址,则Recommended字符串OSI 网络层或非 OSI 等效。 [5]ipv4; ipv6

[1] error.type 报告以下错误代码

  • 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

有关更多详细信息,请参阅 WindowsLinux 上的套接字错误。

[2] network.peer.port 如果端口支持套接字地址族。

[3] network.transport 如果值为 tcp 以外的值。如果缺失,则假定值为 tcp

[4] network.transport 值应规范化为小写。

在设置端口号时,应始终考虑设置传输协议,因为没有传输协议的端口号是模糊的。例如,不同的进程可能正在监听 TCP 端口 12345 和 UDP 端口 12345。

[5] network.type: 值应标准化为小写。


error.type 具有以下已知值列表。如果其中一个适用,则必须使用相应的值;否则,可以使用自定义值。

描述Stability
_OTHER当检测不到自定义值时使用的回退错误值。Stable

network.transport 具有以下已知值列表。如果其中一个适用,则必须使用相应的_值_;否则,可以_使用_自定义值。

描述Stability
pipe命名或匿名管道。Stable
quicQUICStable
tcpTCPStable
udpUDPStable
unixUnix 域套接字Stable

network.type 具有以下预定义值列表。如果其中一个适用,则必须使用相应的值;否则,可以使用自定义值。

描述Stability
ipv4IPv4Stable
ipv6IPv6Stable

TLS 握手

当在客户端进行身份验证时,Span 名称应为 TLS client handshake {server.address};当服务器进行身份验证时,Span 名称应为 TLS server handshake。两种情况下,Span 类型都应为 INTERNAL

状态: 开发中

此 Span 描述了使用 System.Net.Security.SslStream 执行的 TLS 客户端或服务器握手。

当为客户端身份验证报告TLS Span,并与HTTP 连接设置套接字连接 Span 一起报告时,TLS Span 将成为HTTP 连接设置的子 Span。

相应的 Activity.OperationNameExperimental.System.Net.Security.TlsHandshakeActivitySource 名称是 Experimental.System.Net.Security。添加于 .NET 9。

Span 名称当在客户端进行身份验证时应为 TLS client handshake {server.address},当服务器进行身份验证时应为 TLS server handshake

Span 类型在两种情况下都应为 INTERNAL

**Span 状态**应遵循 记录错误文档。

Attributes

Stability需求级别Value Type描述Example Values
error.typeStable如果发生错误,则为条件必需字符串描述操作结束的错误类别。System.Net.Security.Authentication.AuthenticationExceptionSystem.OperationCanceledException
server.addressStable在客户端身份验证时Recommended字符串TLS 握手期间“Client Hello”消息中使用的 服务器名称指示 (SNI)。[1]opentelemetry.ioexample.com
tls.protocol.nameDevelopment可用时Recommended字符串从协商的 SSL/TLS 协议版本的原始字符串解析出的标准化小写协议名称。ssltls
tls.protocol.versionDevelopment可用时Recommended字符串从协商的SSL/TLS 协议版本的原始字符串解析出的版本数值部分。1.2; 3

[1] server.address 从客户端观察时,并且当通过中间设备通信时,server.address 应代表任何中间设备(例如代理)后面的服务器地址,如果可用。


error.type 具有以下已知值列表。如果其中一个适用,则必须使用相应的值;否则,可以使用自定义值。

描述Stability
_OTHER当检测不到自定义值时使用的回退错误值。Stable

tls.protocol.name 具有以下一组知名值。如果适用其中一个,则必须使用相应的;否则,可以改用自定义值。

描述Stability
sslsslDevelopment
tlstlsDevelopment

示例

HTTP 请求在即时可用的连接上执行

如果连接对请求即时可用,HttpClient 会为 HTTP 请求创建一个 Span,并将其链接到与该连接关联的HTTP connection_setup Span。

此时HTTP connection_setup Span 已结束。

<- HTTP connection_setup - (trace=t1, span=s1) ->
<--- DNS --->
             <--- socket connect --->
                                     <--- TLS -->
                                                  <--- GET / (INTERNAL, trace=t2, span=s2, link_to=t1,s1) --->

HTTP 请求需要等待连接设置

如果连接对请求不可用,HTTP 客户端和处理程序会创建 HTTP 请求和等待连接 Span。在此示例中,创建了一个新连接,并在连接建立后立即在该连接上执行了请求。仪表化将一个链接添加到了 HTTP 请求 GET Span 到HTTP 连接设置 Span。

<--------- HTTP connection_setup (trace=t1, span=s1) -------->
<--- DNS --->
             <--------- socket connect -------->
                                                <--- TLS --->


<----------------------- GET / (trace=t2, span=s2, link_to=t1,s1) -------------------------------->
<--------- HTTP wait_for_connection (trace=t2, span=s3) ------>

HTTP 请求需要等待连接设置以及该连接上的其他请求完成

如果连接对请求不可用,HTTP 客户端和处理程序会创建 HTTP 请求和等待连接 Span。在此示例中,请求在现有连接上执行,但该连接在对上述 GET 请求可用之前,在队列中服务了其他请求。

<- HTTP connection_setup - (t1,s1) ->
                                        <--------------------- GET / (trace=t2, span=s2) ----------------------------------------->
                                        <---- HTTP wait_for_connection (trace=t2, span=s2, link_to=t1,s1) ---->

HTTP 连接设置 Span 在此请求之前已启动,相应的连接在变为对上述 GET 请求可用之前,一直服务于其他请求。

此处的长等待连接 Span 表明存在请求队列以及连接池的高需求。

HTTP 请求因无法建立连接而失败

如果 HTTP 请求在连接建立之前失败

  • 所有建立连接的尝试都记录为HTTP connection_setup Span
  • HTTP 请求 GET Span 会随相应的错误类型一起记录,并附带等待连接 Span。
  • HTTP 请求 GET Span **不**链接到任何HTTP 连接设置 Span,因为这些连接从未与相应的请求关联。
<- HTTP connection_setup - (trace=t1, span=s1) - ERROR ->
<------------------- DNS - timeout ---------------->

<---------- GET / (trace=t2, span=s2) - ERROR ---------->
<- HTTP wait_for_connection (trace=t2, span=s3) - ERROR ->