作者:来自 Elastic Naga Putta 及 Stephen Brown

五个 ES|QL 工具通过评估延迟、错误、吞吐量和依赖关系来定位根本原因,因此在发生 APM 事件时,你无需在多个仪表板之间来回切换。

询问 Elastic 新推出的 APM 服务健康监控器,你的服务是否健康。它会针对现有的 traces-* 数据分发执行五个 ES|QL 查询,并在一次响应中给出红色、黄色或绿色状态,同时附带根本原因,无需切换仪表板,也无需手动进行任何关联分析。它运行在 Elastic Agent Builder 上,已在 Elasticsearch 和 Kibana 9.3 中完成测试,并且一次部署即可覆盖你整个服务集群中的所有服务,无需针对每个服务进行单独配置。下面介绍它的构建方式。

我的服务健康吗?一个问题,一个 agent,一个答案

在一次故障事件中,每位工程师都害怕听到这样一个问题:“服务健康吗?”

听起来很简单。但实际上并非如此。要正确回答这个问题,需要在仪表板之间切换,执行多个查询,将延迟峰值与错误日志进行关联,并检查下游依赖是否正在导致问题,而这一切通常都需要在压力之下完成,甚至是在不方便的时间进行。

如果整个调查过程能够简化为一次对话,会怎样?

这正是我们希望构建的东西:一个像坐在你身边的资深 SRE 一样工作的 AI agent。它知道应该提出哪些问题,知道如何查询你的 APM 数据,并返回清晰的红色、黄色或绿色健康判断,同时提供上下文信息和建议。我们称它为 APM 服务健康监控器( APM Service Health Monitor ),它完全运行在 Elastic 之上。

为什么 APM 健康状态是一个派生信号,而不是单一指标

关于 APM 数据,有一点很重要:你已经拥有了所需的一切。延迟百分位数、错误率、吞吐量以及 span 级别的依赖追踪,都已经存在于你的 traces-* 索引中,并且已经完成索引,可以直接使用。

缺少的并不是数据,而是能够将这些信号连接起来形成完整判断的推理层。

单独来看,890 ms 的 p95 延迟几乎没有太大意义。但是,如果 890 ms 的 p95 延迟比 24 小时基线高出 38%,同时你的 postgres-primary 依赖存在 6% 的错误率,那么这就是一个完整的信息。这就是红色状态,它能够直接告诉工程师应该从哪里开始排查。

APM 服务健康监控器将这种推理能力(阈值逻辑、趋势比较以及依赖影响范围分析)编码到一个 Elastic AI agent 中,并能够按需运行,为任何服务、任何时间提供健康分析。

为什么 APM 健康状态是一个派生信号,而不是单一指标

关于 APM 数据,有一点很重要:你已经拥有了所需的一切。延迟百分位数、错误率、吞吐量以及 span 级别的依赖追踪,都已经存在于你的 traces-* 索引中,并且已经完成索引,可以直接使用。

缺少的并不是数据,而是能够将这些信号连接起来形成完整判断的推理层。

单独来看,890 ms 的 p95 延迟几乎没有太大意义。但是,如果 890 ms 的 p95 延迟比 24 小时基线高出 38%,同时你的 postgres-primary 依赖存在 6% 的错误率,那么这就是一个完整的信息。这就是红色状态,它能够告诉工程师应该从哪里开始排查。

APM 服务健康监控器将这种推理能力(阈值逻辑、趋势比较以及依赖影响范围分析)编码到一个 Elastic AI agent 中,并能够按需运行,为任何服务、任何时间提供分析。

以 APM 服务健康监控器 agent 为中心,向外分发到五个查询 traces-* 的 ES|QL 工具

APM 服务健康监控器架构如何工作?

该 agent 在 Elastic Agent Builder 中注册为一个聊天类型 agent,并连接到五个基于 ES|QL 的工具。每个工具都专注于完成一项明确的任务。该 agent 负责协调、比较,并基于这五个工具的结果进行推理。

POST kbn:/api/agent_builder/agents
{
  "id": "apm_service_health_agent",
  "type": "chat",
  "name": "APM Service Health Monitor",
  ...
}

APM 服务健康监控器位于中心位置,向外分发到五个查询 traces-* 的 ES|QL 工具。

下面介绍工具层的组成方式。

工具 1:apm_metrics_overview_tool,24 小时基线

每次健康评估都从基线开始。该工具通过一个 ES|QL 查询,计算某个服务过去 24 小时内的整体情况(平均延迟、p95 和 p99 延迟、错误率以及吞吐量):

FROM traces-*
| WHERE service.name == ?service
| WHERE transaction.type == "request"
| WHERE @timestamp >= NOW() - 24 hours
| EVAL is_error = CASE(event.outcome == "failure", 1, 0)
| STATS
    avg_latency_ms  = AVG(transaction.duration.us / 1000),
    p95_latency_ms  = PERCENTILE(transaction.duration.us / 1000, 95),
    p99_latency_ms  = PERCENTILE(transaction.duration.us / 1000, 99),
    error_rate      = 100.0 * SUM(is_error) / COUNT(*),
    throughput_rps  = COUNT(*) / (24*3600)

这个快照成为基准点。后续每个趋势工具都会将最新读数与这些数值进行比较,因此 agent 始终拥有一个参考点,而不仅仅是一个原始数值。

工具 2:apm_latency_trend_tool,随时间变化的性能表现

平均值会隐藏关键变化点。延迟趋势工具会在过去 24 小时内,以 5 分钟为间隔对 p95、p75 和平均延迟进行分桶,为 agent 提供一个性能变化的时间序列视图:

| STATS
    avg_latency_ms = AVG(transaction.duration.us / 1000),
    p95_latency_ms = PERCENTILE(transaction.duration.us / 1000, 95),
    p75_latency_ms = PERCENTILE(transaction.duration.us / 1000, 75)
  BY time_bucket = DATE_TRUNC(5 minutes, @timestamp)
| SORT time_bucket ASC

Agent 会获取最近 5 分钟数据桶中的 p95_latency_ms,并将其与 apm_metrics_overview_tool 中的 p95_latency_ms(24 小时滚动平均值)进行比较。这个百分比差异就是用于计算绿色、黄色或红色状态的评分依据。

工具 3:apm_error_trend_tool,故障形态检测

错误率具有方向性。从 0.5% 缓慢上升到 1.2%,与突然升高到 8% 所代表的问题完全不同。错误趋势工具通过 5 分钟数据桶捕获这种变化形态:

| EVAL is_error = CASE(event.outcome == "failure", 1, 0)
| STATS
    total_requests = COUNT(*),
    error_count    = SUM(is_error),
    error_rate     = 100.0 * SUM(is_error) / COUNT(*)
  BY time_bucket = DATE_TRUNC(5 minutes, @timestamp)

Agent 会读取该趋势中最新数据桶的 error_rate,并根据固定阈值直接进行评分(低于 1% 为绿色,1% 到 5% 为黄色,高于 5% 为红色)。

工具 4:apm_throughput_trend_tool,作为健康信号的流量指标

吞吐量作为健康指标经常被低估。每秒请求量下降 40% 本身就是一次事件。它可能意味着部署回归、负载均衡器配置错误,或者上游服务发生了无声故障。

| STATS requests_count = COUNT(*)
  BY time_bucket = DATE_TRUNC(5 minutes, @timestamp)
| SORT time_bucket ASC

Agent 会将每个 5 分钟数据桶中的请求数量标准化为每秒请求速率,并与 apm_metrics_overview_tool 中的 throughput_rps 进行比较。相同的 10% 和 30% 偏差阈值仍然适用。一个异常安静的服务,与一个正在发生严重故障的服务一样,都会被快速标记出来。

工具 5:apm_dependency_health_tool,影响范围视图

apm_dependency_health_tool 往往能够发现其他工具无法直接暴露的问题。一个服务自身看起来可能很健康,但下游数据库或外部 API 可能正在悄悄累积失败。该工具通过 span.destination.service.resource 映射每个依赖关系,并根据 span 数据计算其错误率:

FROM traces-*
| WHERE processor.event == "span"
  AND span.destination.service.resource IS NOT NULL
| EVAL is_error = CASE(event.outcome == "failure", 1, 0)
| STATS
    total_calls  = COUNT(*),
    failed_calls = SUM(is_error),
    error_rate   = 100.0 * SUM(is_error) / COUNT(*)
  BY dependency_name = span.destination.service.resource
| SORT error_rate DESC

与其他四个工具不同,依赖健康状态会独立进行评分。每个依赖的 error_rate 会直接与固定阈值进行比较(低于或等于 1% 为绿色,高于 1% 为黄色,高于 5% 为红色),无需进行基线比较。

健康评分如何工作

当五个工具全部返回数据后,agent 会在一次推理步骤中为每个指标计算健康状态。没有轮询循环,也没有中间存储。下面是具体的比较方式:

**指标提供数值的工具比较对象评分方式**
延迟(p95)apm_latency_trend_toolapm_metrics_overview_tool 提供的 24 小时 p95< 10% 绿色 · 10–30% 黄色 · > 30% 红色
错误率apm_error_trend_tool固定阈值 + 概览中的 24 小时 error_rate< 1% 绿色 · 1–5% 黄色 · > 5% 红色
吞吐量apm_throughput_trend_toolapm_metrics_overview_tool 提供的 24 小时 throughput_rps< 10% 绿色 · 10–30% 黄色 · > 30% 红色
每个依赖apm_dependency_health_tool仅固定阈值(无基线)全部 ≤1% 绿色 · 任意 >1% 黄色 · 任意 >5% 红色

整体判断遵循一个简单规则:最差的单个指标决定最终结果。

任意指标为红色                → 总体状态 = 🔴 红色
任意指标为黄色(没有红色)   → 总体状态 = 🟡 黄色
所有指标均为绿色              → 总体状态 = 🟢 绿色

红/黄/绿色评分逻辑存放在 agent 的自然语言指令中。它易于阅读、审计和调整,无需修改代码,也无需重新部署基础设施。

四个指标列(延迟、错误率、吞吐量、依赖关系)汇聚到红/黄/绿色结果状态

在 Agent Builder 中部署 APM 服务健康监控器

注册流程遵循 Elastic 标准的 Agent Builder API 模式,已在 Elasticsearch 9.3 和 Kibana 9.3 中完成测试。首先注册这些工具,然后将 agent 连接到全部五个工具 ID:

# Step 1: Register the five ES|QL tools
POST kbn:/api/agent_builder/tools   # apm_metrics_overview_tool
POST kbn:/api/agent_builder/tools   # apm_latency_trend_tool
POST kbn:/api/agent_builder/tools   # apm_error_trend_tool
POST kbn:/api/agent_builder/tools   # apm_throughput_trend_tool
POST kbn:/api/agent_builder/tools   # apm_dependency_health_tool
 
# Step 2: Register the agent with tools wired in
POST kbn:/api/agent_builder/agents  # apm_service_health_agent
 
# Step 3: Verify the agent is live
GET kbn:/api/agent_builder/agents/apm_service_health_agent

每个工具都通过服务绑定进行参数化,因此同一个 agent 可以服务你整个服务集群中的所有服务,无需针对每个服务进行单独配置。这些查询目标为 traces-*,并支持跨集群通配符,因此一次部署即可开箱即用地覆盖多集群环境。

试试看:向 agent 询问你的服务状态

部署完成后,在 Kibana 中打开该 agent,并输入:

过去 24 小时内我的 checkout-service 的健康状态如何?

Agent 会向所有五个工具分发请求,计算各项指标状态,一次性应用健康判断逻辑,并返回一份结构化报告。

Kibana 聊天卡片:checkout-service · 最近 24 小时 · 包含红/黄/绿色状态标签的各指标表格 · 总体状态:🔴 红色

Agent 无需任何手动关联分析,就识别出了根本原因:postgres-primary 的调用失败率达到 6.1%,并且这一问题正在直接导致 p95 延迟峰值。无需切换仪表板,无需手动编写 ES|QL。一个提示词,即可获得完整的态势感知。

你可以在同一个会话中继续提出后续问题:

  • 哪些其他服务依赖 postgres-primary?

  • 这与昨天的健康状态相比如何?

  • 只显示过去 6 小时的错误趋势。

Agent 会针对每个后续问题调用相应的工具,同时保留原始健康评估的完整上下文。

为什么 Agent Builder 和 ES|QL 是实现这一方案的正确技术栈

一些经过深思熟虑的设计选择,让这个方案能够简洁地运行。

ES|QL 作为查询层

ES|QL 基于管道的语法使每个工具查询都易于阅读、测试和独立验证。用于趋势分析的 DATE_TRUNC 分桶、用于延迟分析的 PERCENTILE 聚合,以及用于依赖关系分析的 span.destination.service.resource 分组,都是精确且可审计的查询。你可以直接在 Kibana Dev Tools 中运行任意查询,并查看 agent 所看到的完整结果。

窄范围、无状态工具

每个工具只负责完成一件事情,并返回结构化数据。agent 负责编排和推理。添加新的指标维度只需要注册一个新的工具,并更新 agent 指令即可。其他内容无需改变。

将指令作为运行手册

agent 的健康判断逻辑通过自然语言表达,并存放在其配置中。团队中的任何人都可以阅读这些逻辑,无需代码部署即可进行调整,并且可以通过 Kibana 中的 Agent Builder 界面完整审计这些逻辑。

APM 服务健康监控器的下一步发展方向

APM 服务健康监控器是一个基础能力,而不是终点。自然的扩展方向包括:

  • 由告警触发的健康检查:将 agent 连接到异常检测规则,使其能够在规则触发时自动运行,并将健康摘要直接附加到告警通知中。

  • 部署关联分析:集成变更事件数据,使 agent 能够判断红色状态是否在某次特定部署之后开始出现。

  • 基于 SLO 的阈值:使用每个服务的错误预算消耗替代固定百分比阈值,使红色、黄色和绿色状态能够根据定义好的 SLO 反映真实业务影响。

  • 跨服务遍历:扩展依赖工具,使其能够递归评估上游和下游服务,通过一次查询构建完整的拓扑视图。

要求和部署

要求:

完整的 agent 和工具定义可以在[此代码仓库]中找到。一旦你的 traces 完成索引,全部五个 ES|QL 工具无需修改即可作用于你的数据,在查询时通过服务名称进行参数化,并通过一次部署覆盖整个服务集群。

下一次有人问“服务健康吗?”时,你将在事件频道中的问题结束回响之前,获得一个精确、有数据支持的答案。

有问题、扩展想法或反馈?欢迎加入 Elastic 社区论坛 讨论。

完整部署参考

以下是部署 APM 服务健康监控器所需的全部内容,按照执行顺序排列。先运行五个工具注册,然后运行 agent。

工具 1:依赖健康状态

POST kbn:/api/agent_builder/tools
{
  "id": "apm_dependency_health_tool",
  "type": "esql",
  "description": "评估外部依赖(数据库、API、缓存等)的健康状态...",
  "configuration": {
    "query": "FROM traces-*\n| WHERE service.name == ?service\n| WHERE processor.event == \"span\"\n  AND span.destination.service.resource IS NOT NULL\n| WHERE @timestamp >= NOW() - 24 hours\n| EVAL is_error = CASE(event.outcome == \"failure\", 1, 0)\n| STATS\n    total_calls = COUNT(*),\n    failed_calls = SUM(is_error),\n    error_rate = 100.0 * SUM(is_error)/COUNT(*)\n  BY dependency_name = span.destination.service.resource\n| SORT error_rate DESC | LIMIT 100"
  }
}

工具 2:错误趋势

POST kbn:/api/agent_builder/tools
{
  "id": "apm_error_trend_tool",
  "type": "esql",
  "description": "跟踪服务过去 24 小时内按 5 分钟分桶的错误率...",
  "configuration": {
    "query": "FROM traces-*\n| WHERE service.name == ?service\n| WHERE transaction.type == \"request\"\n| WHERE @timestamp >= NOW() - 24 hours\n| EVAL is_error = CASE(event.outcome == \"failure\", 1, 0)\n| STATS\n    total_requests = COUNT(*),\n    error_count = SUM(is_error),\n    error_rate = 100.0 * SUM(is_error)/COUNT(*)\n  BY time_bucket = DATE_TRUNC(5 minutes, @timestamp)\n| SORT time_bucket ASC | LIMIT 1000"
  }
}

工具 3:延迟趋势

POST kbn:/api/agent_builder/tools
{
  "id": "apm_latency_trend_tool",
  "type": "esql",
  "description": "提供过去 24 小时按 5 分钟分桶的延迟趋势(平均值、p95、p75)...",
  "configuration": {
    "query": "FROM traces-*\n| WHERE service.name == ?service\n| WHERE transaction.type == \"request\"\n| WHERE @timestamp >= NOW() - 24 hours\n| STATS\n    avg_latency_ms = AVG(transaction.duration.us / 1000),\n    p95_latency_ms = PERCENTILE(transaction.duration.us / 1000, 95),\n    p75_latency_ms = PERCENTILE(transaction.duration.us / 1000, 75)\n  BY time_bucket = DATE_TRUNC(5 minutes, @timestamp)\n| SORT time_bucket ASC | LIMIT 1000"
  }
}

工具 4:指标概览

POST kbn:/api/agent_builder/tools
{
  "id": "apm_metrics_overview_tool",
  "type": "esql",
  "description": "聚合过去 24 小时的关键服务指标:平均延迟、p95/p99、错误率、吞吐量...",
  "configuration": {
    "query": "FROM traces-*\n| WHERE service.name == ?service\n| WHERE transaction.type == \"request\"\n| WHERE @timestamp >= NOW() - 24 hours\n| EVAL is_error = CASE(event.outcome == \"failure\", 1, 0)\n| STATS\n    avg_latency_ms = AVG(transaction.duration.us / 1000),\n    p95_latency_ms = PERCENTILE(transaction.duration.us / 1000, 95),\n    p99_latency_ms = PERCENTILE(transaction.duration.us / 1000, 99),\n    error_rate = 100.0 * SUM(is_error) / COUNT(*),\n    throughput_rps = COUNT(*) / (24*3600)"
  }
}

工具 5:吞吐量趋势

POST kbn:/api/agent_builder/tools
{
  "id": "apm_throughput_trend_tool",
  "type": "esql",
  "description": "提供过去 24 小时按 5 分钟间隔的服务吞吐量趋势...",
  "configuration": {
    "query": "FROM traces-*\n| WHERE service.name == ?service\n| WHERE transaction.type == \"request\"\n| WHERE @timestamp >= NOW() - 24 hours\n| STATS requests_count = COUNT(*)\n  BY time_bucket = DATE_TRUNC(5 minutes, @timestamp)\n| SORT time_bucket ASC | LIMIT 1000"
  }
}

Agent:APM 服务健康监控器

POST kbn:/api/agent_builder/agents
{
  "id": "apm_service_health_agent",
  "type": "chat",
  "name": "APM 服务健康监控器",
  "description": "提供过去 24 小时服务的红/黄/绿色健康状态和趋势。",
  "labels": ["apm", "health", "service", "monitoring"],
  "avatar_color": "#4CAF50",
  "configuration": {
    "instructions": "你是服务健康 Agent...",
    "tools": [{
      "tool_ids": [
        "apm_dependency_health_tool",
        "apm_error_trend_tool",
        "apm_latency_trend_tool",
        "apm_metrics_overview_tool",
        "apm_throughput_trend_tool"
      ]
    }]
  }
}

原文:From five dashboards to one prompt: Elastic Agent Builder's Red/Yellow/Green APM verdict — Elastic Observability Labs

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐