作者:来自 Elastic Jack Shirazi

Telemetry Policy 表明你希望发生什么,并让每个组件自行决定如何实现。将 OpenTelemetry Java agent 的 trace 采样率更改为 1%,JVM 仍会继续提供流量服务。
Elastic 原生支持 OpenTelemetry。通过 OTLP 将 traces、logs 和 metrics 直接发送到 Elasticsearch,无需使用专有 agent。查看它如何协同工作,在云端免费试用,或者在本地运行。
无需重启 JVM,即可将正在运行的 Java 应用程序的 trace 采样率从 5% 更改为 1%。Telemetry Policy 规定你希望发生什么,并让每个 SDK、agent 或 collector 自行决定如何实现,因此平台团队只需定义一次,就可以在各处应用。下面的屏幕截图展示了在 Elastic APM UI 中将采样率设置为 0.1,以及 Java agent 记录其已接收并应用该值。本文的其余部分将介绍什么是策略以及它有哪些限制。在下一篇文章中,我将介绍 OpenTelemetry Java contrib 仓库中的首个实验性实现。
如何在运行时更改 OpenTelemetry Java agent 的采样率
到目前为止,除了一些专有方案之外,对此 类 遥测进行配置都必须在生成遥测数据的组件(例如 SDK、agent 或 OpenTelemetry Collector)启动时完成。Telemetry Policy 是一种正在形成的标准,它将允许你重新配置部分遥测设置,而无需重启生成遥测数据的组件。
例如,假设你希望:
-
在某些特殊的高峰时段(例如特殊促销日)将 trace 采样率更改为 1%,而在其他时间保持为 5%。
-
临时更改日志级别(例如更改为 debug 级别,或者恢复为 info)。
-
停止某些处于活动状态的 instrumentation。
这些都是很直接的需求。但直到现在,应用其中任何一项都意味着修改组件的配置并重启组件。对于 Java 应用程序(以及大多数语言中的应用程序)而言,这以前还意味着必须重启应用程序,因为没有办法在不重启 JVM 的情况下更改 agent 配置。
为什么集中式管理需要统一的策略格式
集中式管理带来了另一个挑战。一个控制系统请求进行诸如 "将日志级别提高到 debug" 这样的更改时,必须知道如何将该更改应用到它控制的每个组件。collector 的配置更改方式不会与 Java SDK 相同,即使两者应用的是同一个决策。
Telemetry Policy 通过将以下两者分离来解决这两个问题:
-
我们希望发生什么
-
特定 SDK、agent 或 collector 如何实现这一目标。

使用 Elastic APM UI 将 Java agent 的采样率设置为 0.1(10%)

Elastic APM Java agent 日志语句确认已接收并应用 0.1 的采样率值
OpenTelemetry 中的 Telemetry Policy 是什么?
Telemetry Policy 是一种独立的规则,用于描述用户希望实现的行为。
例如:
go
`Sample traces at 5%`AI写代码
在 5% 的比例下对 traces 进行采样
一个规定以 5% 的比例对 traces 进行采样的策略,并不会说明应该安装哪个 sampler、在哪里添加 processor,或者遥测管道应该如何布局。这些都是特定组件的实现细节。策略只说明预期结果。
该草案规范将策略定义为一个类型化的独立对象。每个策略都有一个 ID、一个名称,以及一个目标信号,例如 traces、logs 或 metrics。目标决定了可以使用哪些匹配字段和操作。
下面是这个 5% 采样策略的示例:
markdown
`
1. {
2. "id": "sample-spans-5-percent",
3. "name": "Sample traces at 5%",
4. "trace": {
5. "match": [
6. {
7. "exists": true
8. }
9. ],
10. "keep": {
11. "percentage": 5.0
12. }
13. }
14. }
`AI写代码
该策略规定匹配每个 trace,并使用 ID 为 sample-spans-5-percent 的策略应用 5% 的采样。每个理解该 ID 的遥测组件都能够应用该策略。任何不理解该策略的遥测组件都会直接忽略它。
Telemetry Policy 可以在运行时更改哪些设置?
我们并不期望策略覆盖每一种配置,甚至不期望覆盖每个组件的_许多_配置。Telemetry Policy 并不是一种通用的"重新配置任何内容"工具。策略针对的是用户最希望在无需重启的情况下进行更改的内容。对于应用程序 agent,根据我们在 Elastic 的经验,大多数客户需要能够在不重启应用程序的情况下于运行时更改的重要策略类型只有十几种左右,包括:
-
更改 trace 采样百分比。
-
开启和关闭单独的 instrumentation 或所有 instrumentation。
-
开启和关闭单独的 signal exporter(traces、metrics、logs、profiles)。
-
更改日志级别。
-
更改少数特定 instrumentation 的配置。
-
例如,更改创建 traces 时需要忽略的 HTTP 路由(例如忽略
/heartbeat)。 -
或者更改需要进行 instrumentation 的方法。
-
Telemetry Policy 如何到达 SDK、agent 或 collector
整体的遥测策略管道包含特定的组件,至少涵盖以下顺序:
rust
`Message -> Provider -> Policy -> Policy aggregator -> Implementer`AI写代码
一个具体的例子是使用 Open Agent Management Protocol (OpAMP),通过集中式管理更改 trace 采样 百分比 ,这有助于理解这一流程:
| 阶段 | 它的作用 | 5% 采样示例中的情况 |
|---|---|---|
| Message | 将请求的更改传入组件 | 一条指定 trace 采样百分比为 5% 的 OpAMP 消息,例如上面的 JSON |
| Provider | 从输入流中读取策略 | OpAMP provider 从 OpAMP 数据流中读取消息 |
| Policy | 对更改的内部表示 | 一个目标值为 5% 的 trace-sampling-percentage-policy,这就是该组件如何实现 ID sample-spans-5-percent* |
| Policy aggregator | 将该策略与已经应用或正在等待应用的其他策略进行组合,并处理来源优先级和合并 | 直接传递,因为这里只有一个 provider |
| Implementer | 将更改应用到正在运行的组件 | 安装一个设置为 5% 的新 sampler |
当两个来源产生冲突时,来源优先级决定采用哪个策略。来自 OpAMP 来源的消息优先级高于来自 HTTP 来源的消息。
Implementer 会安装一个新的 sampler,除非当前运行的 sampler 可以在运行时更改其采样百分比;在这种情况下,它会更新当前的 sampler。
请注意,未来策略类型可能会成为消息中的必需部分。目前还没有将策略 ID 映射到策略类型的标准方法,因此必须将类型包含在消息中,或者通过外部映射提供类型。
通过 OpAMP、HTTP 或本地文件传递策略
Telemetry Policy 不定义新的传输机制或协议。策略可以通过现有的传输方式进行传递:
-
OpAMP。
-
HTTP。
-
本地文件。
-
自定义来源。
在测试时,可以从本地文件读取相同的 trace 采样策略,也可以通过 HTTP 提供策略,或者使用 OpAMP 从集中式管理系统发送策略。OpAMP 并不是 Telemetry Policy 的要求,而是一种受支持的提供方式,并且很可能会成为集中管理系统中的常见传输方式。
Telemetry Policy 在 OpenTelemetry 中的状态
Telemetry Policy 目前是一项已接受的开发中项目。在成为已接受的 OpenTelemetry 标准之前,其架构、策略类型和实现细节仍在持续开发中。
首个实验性 Java SDK 实现
首个实验性 Java SDK 实现首先从动态更改 trace 采样概率开始。这一范围经过刻意缩小,为测试完整的策略流程提供了一种简单实用的方式。
Telemetry Policy 将可观测性决策与应用这些决策的组件的内部配置分离开来。这使平台团队能够定义一次策略,并在 SDK、agent 和 collector 中一致地应用该策略。
在下一篇博客中,我将介绍 OpenTelemetry Java contrib 仓库中的首个实验性实现,包括它如何通过 OpAMP 接收策略,以及如何在运行中的 Java 应用程序中更改 trace 采样,而无需重启。
原文:OpenTelemetry Java agent: change sampling without restart | Elastic Observability Labs