Elasticsearch 查询日志:每个查询一行协调器级别日志,适用于 ES|QL、DSL、SQL 和 EQL

作者:来自 Elastic Najwa HarifValentin Crettaz

通过 Elasticsearch 查询日志,可以轻松理解查询对集群性能的影响。每个请求由一条协调器级别日志记录,覆盖 ES|QL、DSL、SQL 和 EQL,并提供完整的查询文本、追踪信息、可选用户上下文以及 CCS 提示。

测试 Elastic 的前沿开箱即用能力。深入 Elasticsearch Labs 仓库中的示例 notebooks,开始免费云试用,或立即在本地机器上体验 Elastic。


你的 dashboard 超时并且 CPU 飙升,但到底是哪条查询在执行?slow logs 每个 shard 只提供一行;Elasticsearch 查询日志则是每个请求一条 JSON 日志行,其端到端耗时与 API 中你已经信任的 took(在查询返回内容中的 took 字段) 相同。这一条日志还会捕获完整查询文本(适用于 ES|QL、DSL、SQL 和 EQL)、执行结果、追踪信息、可选用户上下文,以及在相关情况下的跨集群(CCS)提示。

这些日志遵循 ECS 规范,可以直接在 Discover 中使用,并且在开箱即用的 dashboard 中可直接可视化,只要你写入日志即可,无需自定义 schema 项目。下面内容将介绍我们为什么构建它、它与 slow logs 的区别、每一行包含的信息,以及如何启用它。

为什么我们要构建这个(你们问得很多!)

协调器级别的查询日志一直是一个非常高频的需求;我们倾听了这些反馈并最终交付了它!同样的问题不断出现:你希望在服务等级目标(SLO)和仪表盘中看到响应时长;你希望了解集群中查询执行的耗时;你还希望能够看到完整的查询内容。

在使用跨集群搜索(cross-cluster search)时,一个跨多个集群扩展的搜索在应用或 Kibana 视角下看起来像一次操作,但在运维层面,它实际上是一条工作链:协调、远程执行、合并、超时处理以及部分结果返回。当出现慢查询或不稳定情况时,团队不仅需要知道请求总耗时,还需要知道哪些集群参与了执行,以及最终结果是成功、部分成功还是完全失败。

你将获得的是 :一条日志流、每个查询一条记录!每条记录都包含协调器耗时(即与搜索 API 响应一致的 took 时间)、成功或失败状态以及完整查询文本。该日志符合 Elastic Common Schema(ECS),支持可选的延迟阈值与用户/审计字段,同时包含 X-Opaque-Id,可以将热点查询追溯到其来源的 saved object,并通过 trace ID 与 Kibana 或你自己的工具进行关联。

更重要的是:这些日志遵循稳定的 ECS 对齐 schema,这意味着你不需要设计自己的数据接入 pipeline 或字段映射。这种一致性使得开箱即用的 dashboard 和分析能力可以在日志写入后立即生效。

Slow logs vs. query logs:30 秒版本

slow logs 多年来一直是常用工具。它们可以告诉你哪个搜索操作变慢了,但它们是以 shard 为单位输出日志 ------ 每个 shard 只会产生一行 ,且每一行只反映该 shard 执行的一部分工作。这意味着,它们无法提供一个从客户端视角出发的、描述整个查询执行耗时的单一记录。query logs 则正好相反:每个查询只输出一行,并提供端到端(wall clock)耗时,这个时间与 search API 响应中的 took 时间一致。这使得它们更适合理解工作负载模式,以及快速定位问题查询。

slow logs 和 query logs 在触发时机与覆盖范围上也不同。slow logs 只有在 shard 执行超过阈值时才会写入,也就是说,它们主要用于"发现异常慢的 shard 工作"。query logs 可以记录所有查询(或仅记录超过你在集群级别配置的阈值的查询),因此你可以根据分析或排障需求调节日志量。slow logs 仅支持 DSL 查询,而 query logs 覆盖 ES|QLDSLSQLEQL,这更符合现代技术栈中 "这个集群到底执行了什么" 的分析方式。两者在 header 关联、trace 和审计信息方面提供相同能力(当你开启用户上下文时)。

下面的表格总结了传统 slow logs 与新的 query logs 功能之间的主要差异。

Slow logs vs. Query logs

对比项 Slow logs Query logs
用途 用于定位 "热点 shard" 或慢索引操作,以及在单集群内进行传统性能调优 用于理解"执行了什么查询"、端到端耗时(协调器视角)、执行是否成功,更适合 SLO、分析与故障排查
粒度 按 shard(以及 phase)记录:一次用户查询可能在多个 shard / replica 上产生多条日志 按协调器级别查询记录:一个查询对应一条日志事件
覆盖范围 查询 + 索引 仅查询(索引日志未来才会支持)
可获得的信息 "这个 index 上的这个 shard 在 query/fetch 阶段超过 N ms" "这条查询(完整文本)、耗时、结果状态,以及(在相关情况下)跨集群/联邦查询汇总信息"
支持的查询类型 仅 DSL ES
阈值模型 通常是分层阈值(多个时间档位、按 index 配置) 集群级单一时间阈值(例如:≥ 500ms 记录日志)

每条日志里包含什么

每一条日志都是一个 JSON 对象(对应一个请求),存放在独立文件中(例如 Elasticsearch 日志目录下的 *_querylog.json)。下面是你可以从这些数据中获得的信息:

是否成功、耗时多少、哪里出错?

包含 执行结果(是否成功)耗时(took / took_millis,与 API 返回一致),以及发生错误或超时时的清晰失败信息。

这是用于告警、SLO 和仪表盘的核心信号:"系统是否正常?如果不正常,原因是什么?"

同时还会提供返回的行数或命中数(result_count),用于区分:

  • "慢但结果很少"

  • "慢且返回量很大"

实际执行了什么查询?

包含查询类型(esqldslsqleql)以及完整查询文本

这可以回答问题:

  • 哪个 dashboard 规则 / saved search / 客户端请求在持续压系统?

结合耗时和结果状态,可以快速定位最 "昂贵" 的查询进行优化或限流。

谁发起的请求?如何端到端追踪?

通过 X-Opaque-Idtrace ID,可以将日志关联回 Kibana 或自定义请求头。

task 和可选的 parent task ID 可以追踪异步或嵌套执行链路。

跨集群搜索(CCS):谁参与了?有没有异常?

在启用跨集群搜索时,日志可以包含:

  • 远程集群别名

  • 每个集群的耗时

  • 执行状态(成功 / 失败 / 部分成功 / 跳过)

你可以快速判断:

  • 慢是本地问题还是远端集群拖慢了整体响应

DSL 可以记录是否来自 remote alias

ES|QL 提供更丰富的 cluster map

EQL 在涉及远端时提供更轻量视图(例如涉及哪些 remote 以及数量)

安全信息(可选)

当开启 elasticsearch.querylog.include.user 时,可以获得:

  • 用户身份信息

  • realm 信息

  • run-as 情况下的 effective user

  • API key 元数据

结合查询文本和耗时,可以用于治理和容量分析(不仅看 IP,也看"谁在用")。

还有更多信息

此外还可能包含:

  • 更细粒度的执行细节

  • shard 级别结果

  • 可选 profiling 信息(取决于查询类型)

完整字段与配置请参考 Elasticsearch 官方 query logs 文档

日志存放位置(以及如何使用)

日志会以 *_querylog.json 的形式写入 Elasticsearch 的日志目录中(例如 mycluster_querylog.json),位于协调节点(coordinating node)上。

你可以通过 Filebeat Elasticsearch 模块中的 querylog fileset 来采集这些日志,然后在 Discover 中查看(通过 event.dataset: elasticsearch.querylog 过滤)。

在 Elastic Cloud 上,你需要先为 deployment 启用 Logs,一旦开启,query logs 就会自动开始收集与传输。


两种使用方式

如果你只是想做一次性排查,例如:

  • 谁在 "打爆" 集群

  • 当前查询类型分布是什么

  • 做一次快速审计

可以直接开启日志,设置一个 duration 阈值(例如 ≥ 1 秒或 ≥ 5 分钟),只记录有意义的慢查询,用完后关闭即可。

如果你需要持续性的查询分析,只需:

  • 启用 logging

  • 用 Filebeat 采集日志

  • 在监控集群上打开 dashboard

非常简单的两步:启用 + 采集,就完成了。

每条请求一行,每条请求一个耗时,无需任何自定义 pipeline。


Dashboard 概览

下面的 dashboard 基于新的 query logs 开箱即用。

在顶部一行,你可以看到:

  • P95 / P99 查询延迟(以及可选的 "可接受延迟" 参考线)

  • 查询类型分布

  • 成功 / 失败比例

  • 用户查询 vs 系统查询比例

  • (针对 DSL)hits 与 aggregations 的比例

在下方,你可以看到:

  • 延迟随时间变化(avg、p50、p95、p99、max),并带有参考线用于识别回归

  • 查询量随时间变化(按类型分层)

  • Top indices、Top users、Top error types 表格

通过 cluster、user 或 index 过滤器,你可以精确聚焦到你关心的范围。

提醒一下:查询日志是异步的,因此不会阻塞查询执行。你可以使用 duration 阈值来控制日志量。

另外需要注意,在非常高的 QPS(每秒查询数)情况下,我们可能会丢弃部分日志记录,而不是让集群性能受到影响。对于分析用途,建议将日志发送到独立的监控集群,这样可以避免正在排障的集群承担额外负载。

一些配置与代码示例

查询日志默认是关闭的 。你可以在 elasticsearch.yml 中开启,或者通过 cluster settings API 开启。方法如下:

启用查询日志

elasticsearch.yml 中:

复制代码
elasticsearch.querylog.enabled: true

或者通过集群设置 API 动态开启:

复制代码
PUT _cluster/settings
{
  "persistent": {
    "elasticsearch.querylog.enabled": "true"
  }
}

仅记录超过持续时间阈值的查询

如果你不希望记录每一个健康检查或极小请求,只需设置一个阈值,让系统仅在查询执行时间达到或超过该阈值时才写入日志。duration 的单位是时间单位:

复制代码
PUT _cluster/settings
{
  "persistent": {
    "elasticsearch.querylog.enabled": "true",
    "elasticsearch.querylog.threshold": "1s"
  }
}

包含用户 / 审计信息

如果你使用 Security 插件,并且希望查看每条查询是由谁执行的:

复制代码
PUT _cluster/settings
{
  "persistent": {
    "elasticsearch.querylog.enabled": "true",
    "elasticsearch.querylog.include.user": "true"
  }
}

记录仅命中系统索引的 DSL 查询

默认情况下,只针对系统索引(system indices)的搜索不会被记录。

如果你希望将这些查询也纳入日志,需要启用 query logging,并设置:

复制代码
PUT _cluster/settings
{
  "persistent": {
    "elasticsearch.querylog.enabled": "true",
    "elasticsearch.querylog.include.system_indices": "true"
  }
}

示例日志条目

一行 = 一个 JSON 对象 = 一个请求,对 ES|QL、DSL、SQL、EQL 都具有相同结构。下面分别展示一个成功的 DSL 查询和一个失败的 EQL 查询,包括时间戳、耗时、查询类型和完整查询内容。成功时会包含结果数量和 shard 统计信息;失败时会包含错误信息块。当你启用相关配置后,还会包含用户信息和 X-Opaque-Id。

成功(DSL 查询):

复制代码
{
  "@timestamp": "2026-03-04T19:40:34.736Z",
  "log": {
    "level": "INFO",
    "logger": "elasticsearch.querylog"
  },
  "event": {
    "duration": 1000000,
    "outcome": "success"
  },
  "elasticsearch": {
    "querylog": {
      "type": "dsl",
      "query": "{\"size\":10,\"query\":{\"match_all\":{\"boost\":1.0}}}",
      "indices": ["query_log_test_index"],
      "result_count": 3,
      "search": { "total_count": 3 },
      "shards": { "successful": 1 },
      "took": 1000000,
      "took_millis": 1
    },
    "node": { "name": "node-1" },
    "cluster": { "name": "my-es-cluster" }
  },
  "http": {
    "request": {
      "headers": { "x_opaque_id": "opaque-1772653234" }
    }
  },
  "user": {
    "name": "elastic",
    "realm": "reserved"
  }
}

失败(EQL 查询):

复制代码
{
  "@timestamp": "2026-03-04T19:40:35.271Z",
  "log": {
    "level": "INFO",
    "logger": "elasticsearch.querylog"
  },
  "event": {
    "duration": 1326334,
    "outcome": "failure"
  },
  "elasticsearch": {
    "querylog": {
      "type": "eql",
      "query": "any where true",
      "indices": ["nonexistent_index_xyz"],
      "result_count": 0,
      "took_millis": 1
    },
    "node": { "name": "node-1" },
    "cluster": { "name": "my-es-cluster" }
  },
  "error": {
    "type": "org.elasticsearch.index.IndexNotFoundException",
    "message": "no such index [Unknown index [nonexistent_index_xyz]]"
  }
}

总结

Elasticsearch 查询日志为每个查询提供一条协调器级别日志(覆盖 ES|QL、DSL、SQL、EQL)。每个请求一行,包含协调器耗时、完整查询内容,以及可选的用户信息和 X-Opaque-Id。启用后,你可以设置持续时间阈值以及用户信息采集(如需要),即可完成配置。

日志存储在日志目录中(*_querylog.json),通过 Filebeat 采集后,可以在 Discover 中通过 elasticsearch.querylog 数据集查看。

完整配置项和字段说明请参考 Elasticsearch 查询日志官方文档。慢查询或异常查询也可以在 AutoOps 中查看,它利用 X-Opaque-Id 将长耗时搜索追溯到其来源,例如 dashboard、saved search 或告警规则。

最后需要注意的是,这个新的查询日志是 9.2 版本中仅支持 ES|QL 的查询日志的演进版本。我们建议使用新的查询日志,因为它不仅支持 ES|QL,还支持所有其他查询类型。

现在,可以去看看你的集群里到底在运行什么查询了。

原文:https://www.elastic.co/search-labs/blog/elasticsearch-query-logs

相关推荐
爱码小白1 小时前
MySQL易忘知识点梳理
数据库·mysql
战南诚1 小时前
mysql - 行列数据转换技巧
数据库·mysql
m0_596749091 小时前
SQL统计分组内的所有数据唯一值_使用DISTINCT汇总
jvm·数据库·python
m0_609160491 小时前
Golang项目目录结构如何组织_Golang项目结构教程【核心】
jvm·数据库·python
Cloud云卷云舒1 小时前
【由云向算】AI原生数据库-海山数据库技术沙龙
数据库·ai-native·移动云·智算·智能云
m0_463672201 小时前
如何优雅处理SQL存储过程异常_使用TRY-CATCH块机制
jvm·数据库·python
NagatoYukee1 小时前
Spring/SpringMVC/SprongBoot知识复习
java·数据库·spring
ㄟ留恋さ寂寞1 小时前
HTML5中SharedWorker生命周期与浏览器进程关闭的关系
jvm·数据库·python
彳亍1011 小时前
MongoDB备节点无法读取数据怎么解决_rs.slaveOk()与Secondary读取权限
jvm·数据库·python