加载中

跨度(Spans)

APM Server 与托管摄取服务 (managed intake service)

在 Elastic Cloud Hosted 中,APM Server 接收来自 Elastic APM Agent 的数据并将其转换为 Elasticsearch 文档。而在 Elastic Cloud Serverless 中,实际上并没有运行 APM Server,而是由托管摄取服务 (managed intake service) 接收并转换数据。

跨度 (Spans)包含有关特定代码路径执行的信息。它们测量从活动开始到结束的过程,并且可以与其他跨度具有父子关系。

代理(Agents)会自动对各种库进行插桩,以从您的应用程序内部捕获这些跨度,但您也可以使用代理 API 对特定的代码路径进行自定义插桩。

除其他外,跨度可以包含

  • 指向其父级 事务transaction.id 属性。
  • 指向其父级跨度或事务的 parent.id 属性。
  • 其开始时间和持续时间。
  • 一个 nametypesubtypeaction——有关按 APM 代理划分的跨度名称模式和示例,请参阅 跨度名称/类型对齐 表。此外,一些 APM 代理会针对公共 跨度类型/子类型规范 进行测试。
  • 可选的 stack trace。堆栈跟踪由堆栈帧组成,代表调用栈上的函数调用。它们包括函数名、文件名和路径、行号等属性。
提示

大多数代理将关键字字段(如 span.id)限制为 1024 个字符,将非关键字字段(如 span.start.us)限制为 10,000 个字符。

出于性能原因,APM 代理可以选择有目的地对跨度进行采样或省略。这有助于防止出现边缘情况(例如包含 100 多个跨度的长时间运行事务),否则这些情况会使代理和 APM Server 或托管摄取服务过载。发生这种情况时,应用程序 UI 将显示丢弃的跨度数量。

要配置每个事务记录的跨度数量,请参阅相关的代理文档

代理将跨度与事务分开流式传输到 APM Server 或托管摄取服务。因此,不可预见的错误可能会导致跨度丢失。代理知道一个事务应该有多少个跨度;如果预期跨度的数量不等于 APM Server 或托管摄取服务收到的跨度数量,应用程序 UI 将计算差值并显示一条消息。

跨度与事务一起存储在以下数据流中

  • 应用程序跟踪:traces-apm-<namespace>
  • RUM 和 iOS 代理应用程序跟踪:traces-apm.rum-<namespace>

请参阅数据流(Data streams)以了解更多信息。

此示例展示了跨度文档在 Elasticsearch 中索引时的外观。

在某些情况下,APM 代理可能会在一个事务中收集大量非常相似或相同的跨度。例如,如果在循环内部捕获跨度,或者在未优化的 SQL 查询中使用多个查询而不是连接来获取相关数据时,就会发生这种情况。

在这种情况下,每个事务的跨度上限(默认情况下为 500 个跨度)可能会很快达到,导致代理停止为给定事务捕获可能更相关的跨度。

捕获相似或相同的跨度通常没有帮助,特别是当它们的持续时间非常短时。它们还会使 UI 显得杂乱,并导致处理和存储开销。

为了解决这个问题,APM 代理可以将相似的跨度压缩为单个跨度。压缩后的跨度保留了大部分原始跨度信息,包括总体持续时间和它所代表的跨度数量。

无论采用哪种压缩策略,如果符合以下条件,则跨度有资格进行压缩

  • 它尚未传播其跟踪上下文。
  • 它是一个 exit 跨度(例如数据库查询跨度)。
  • 其结果不是 "failure"

APM 代理在两种策略之间进行选择,以决定是否可以压缩相邻的跨度。在这两种策略中,只需在内存中保留一个先前的跨度。这确保了代理不需要大量的内存即可启用跨度压缩。

如果两个相邻的跨度具有相同的以下内容,代理将使用 same-kind 策略

  • 跨度类型
  • 跨度子类型
  • destination.service.resource(例如数据库名称)

如果两个相邻的跨度具有相同的以下内容,代理将使用 exact-match 策略

  • 跨度名称
  • 跨度类型
  • 跨度子类型
  • destination.service.resource(例如数据库名称)

您可以在代理的配置设置中指定最大跨度持续时间。持续时间长于指定值的跨度将不会被压缩。

对于 "Same-Kind" 策略,默认的最大跨度持续时间为 0 毫秒,这意味着默认情况下禁用 "Same-Kind" 策略。对于 "Exact-Match" 策略,默认限制为 50 毫秒。

以下代理支持跨度压缩,并且可以使用下面列出的选项进行配置

OpenTelemetry 跨度映射到 Elastic APM 事务和跨度的方式如下

  • 根跨度(如入口点)映射到 APM 事务。
  • 子跨度(如内部操作和数据库查询)映射到 APM 跨度。

下表总结了 OpenTelemetry 跨度种类与 Elastic APM 实体之间的映射关系。

OpenTelemetry 跨度种类 映射到 APM 示例
SERVER 事务(Transaction) 传入的 HTTP 请求 (GET /users/{id})
CONSUMER 事务(Transaction) 消息队列消费者事件
CLIENT 跨度 传出的数据库查询 (SELECT * FROM users)
PRODUCER 跨度 向队列发送消息
INTERNAL 跨度 内部函数执行

以下示例显示了 OpenTelemetry 跨度

[
  {
    "traceId": "abcd1234",
    "spanId": "root5678",
    "parentId": null,
    "name": "GET /users/{id}",
    "kind": "SERVER"
  },
  {
    "traceId": "abcd1234",
    "spanId": "db1234",
    "parentId": "root5678",
    "name": "SELECT FROM users",
    "kind": "CLIENT"
  }
]
		

先前的 OTel 跨度由 Elastic APM 存储如下

Transaction: GET /users/{id}
 ├── Span: SELECT FROM users
		
© . This website operates independently and is not affiliated with or endorsed by Elasticsearch B.V. All brand names, logos, and trademarks are the property of their respective owners.