1

我正在尝试调试 ElasticSearch 查询。我已经为有问题的查询启用了解释,这表明查询正在做一个中间分数的乘积,它应该做一个总和。(我正在使用 elastic4s 创建查询请求。)

问题是我看不到生成的查询实际上是什么。我想确定 bug 是在 elastic4s 中(错误地生成查询请求)、在我的代码中还是在 elasticsearch 中。因此,我使用以下代码为测试中使用的嵌入式弹性搜索实例启用了日志记录:

ESLoggerFactory.setDefaultFactory(new Slf4jESLoggerFactory())
val settings = Settings.settingsBuilder
  .put("path.data", dataDirPath)
  .put("path.home", "/var/elastic/")
  .put("cluster.name", clusterName)
  .put("http.enabled", httpEnabled)
  .put("index.number_of_shards", 1)
  .put("index.number_of_replicas", 0)
  .put("discovery.zen.ping.multicast.enabled", false)
  .put("index.refresh_interval", "10ms")
  .put("script.engine.groovy.inline.search", true)
  .put("script.engine.groovy.inline.update", true)
  .put("script.engine.groovy.inline.mapping", true)
  .put("index.search.slowlog.threshold.query.debug", "0s")
  .put("index.search.slowlog.threshold.fetch.debug", "0s")
  .build

但我在 logback.xml 中配置的日志文件中找不到任何查询。来自 elasticsearch 的其他日志消息出现在那里,而不是实际的查询。

4

2 回答 2

1

你不能,至少不能直接,至少不能在当前可用的 ES 版本中。这是一些已经讨论过的东西(例如https://github.com/elastic/elasticsearch/issues/9172https://github.com/elastic/elasticsearch/issues/12187)似乎这可能很快就会改变, 重写了任务 API。同时,您可以使用 ES Restlog ( https://github.com/etsy/es-restlog ) 和/或将 nginx 放在 ES 前面并在 nginx 日志中捕获查询。您也可以使用 tcpdump(例如tcpdump -vvv -x -X -i any port 9200) 并在服务器上运行时捕获查询。最后一个选项是修改您的应用程序并回显查询而不是执行它(和/或在执行之前将查询插入 ES 本身,因为查询本身是 JSON)。

于 2016-11-11T21:06:26.217 回答
1

在 elastic4s 的特定情况下,它提供了调用 elastic4s 查询对象的能力,以生成如果使用 JSON-over-HTTP 协议发送请求时请求.show的 JSON 正文部分将是什么,对于大多数类型的请求。然后可以在代码中方便的位置记录这一点,例如,如果您有一种方法可以生成所有 ES 搜索查询。当然,Elasticsearch 中生成假 JSON 的代码仍然可能存在错误,因此不应完全信任它。但是,值得尝试.show通过 HTTP 对真实 Elasticsearch 集群使用 Sense 的输出来重现该问题 - 如果可以,您 (a) 知道这不是 elastic4s 错误,并且 (b) 可以轻松操纵 JSON 以尝试找出导致问题的原因。

show在某些情况下调用toString,因此使用普通的 Elasticsearch API 或其他基于 JVM 的包装器,您可以调用它来获取 JSON 字符串进行记录。

使用嵌入式 Elasticsearch,这与您将在日志记录方面获得的一样好 - 没有在构建器调用上设置断点并观察创建的实际 Java Elasticsearch 请求对象(这是最准确的方法)。

于 2016-11-11T21:31:09.853 回答