如何在嵌入式ElasticSearch中记录所有查询?

时间:2016-11-11 16:48:49

标签: elasticsearch elastic4s

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

问题是我无法看到生成的查询实际上是什么。我想在我的代码或elasticsearch中确定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的其他日志消息出现在那里,而不是实际的查询。

2 个答案:

答案 0 :(得分: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)。

答案 1 :(得分:1)

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

在某些情况下,

show会调用toString,因此使用普通的Elasticsearch API或其他基于JVM的包装器,您可以调用它来获取要记录的JSON字符串。

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