带有千分尺 Elasticsearch 注册表的 Spring Boot 仅索引空文档

Posted

技术标签:

【中文标题】带有千分尺 Elasticsearch 注册表的 Spring Boot 仅索引空文档【英文标题】:Spring boot with micrometer Elasticsearch registry indexes only empty documents 【发布时间】:2019-12-17 01:02:36 【问题描述】:

我有一个简单的 spring boot 2.1.7.RELEASE 项目,使用 micrometer Elasticsearch 注册表(使用 Elasticsearch 7.2.0)。该项目在 github 上可用 here。它只有两个类,看起来像这样

pom.xml 有以下依赖:

<dependencies>
  <dependency>
    <artifactId>spring-boot-starter-web</artifactId>
    <groupId>org.springframework.boot</groupId>
  </dependency>

  <dependency>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <groupId>org.springframework.boot</groupId>
  </dependency>

  <dependency>
    <artifactId>micrometer-registry-elastic</artifactId>
    <groupId>io.micrometer</groupId>
  </dependency>
</dependencies>

还有两个类: MicrometerElasticApplication

@SpringBootApplication
public class MicrometerElasticApplication 
  public static void main(final String[] args) 
    SpringApplication.run(MicrometerElasticApplication.class, args);
  

TestController

@RestController
public class TestController 
  @ResponseStatus(HttpStatus.OK)
  @GetMapping("/test")
  public void sendMessage() 
    System.out.println("Received a test message");
  

启动应用后,我可以在日志中看到

i.m.elastic.ElasticMeterRegistry         : publishing metrics to elastic every 1m

这意味着发送了指标,但是当我检查 Elasticsearch 中的索引时,我只能看到这样的文档


    "_index": "metrics-2019-08",
    "_type": "_doc",
    "_id": "nWuMdWwBxBoi4XILEHVK",
    "_score": 1.0

所以没有字段,只有文档元数据。即使在达到/test 端点服务器次数后,metrics 索引也没有任何变化。

通过阅读官方文档here 和检查公共属性here 我的理解是,Spring 默认情况下会添加 JVM、CPU 的指标......甚至测量所有 MVC 请求的时间。现在,我没有得到任何这些,只是空文件。将属性 management.metrics.web.server.auto-time-requests 设置为 true 不会改变任何内容。

有人知道我在这里缺少什么吗?

更新

我在 ElasticMeterRegistry.publish 方法上设置了一个断点,发送到 Elaticsearch /_bulk API 的请求对我来说看起来不错

POST http://localhost:9200/metrics-2019-08/_bulk

 "index" :  
"@timestamp":"2019-08-09T10:49:18.826Z","name":"jvm_memory_max","type":"gauge","area":"heap","id":"PS Survivor Space","value":1.5204352E7
 "index" :  
"@timestamp":"2019-08-09T10:49:18.826Z","name":"jvm_threads_states","type":"gauge","state":"terminated","value":0.0
...

当我使用 Postman 发送此请求时,所有文档都保存为空文档,尽管 Elasticsearch 不报任何错误,回复中"errors": false


    "took": 8,
    "errors": false,
    "items": [
        ...
    ]

【问题讨论】:

【参考方案1】:

ElasticMeterRegistry 创建的索引metrics-2019-08 在其映射集_source 中设置为false

GET http://localhost:9200/metrics-2019-08/_mapping

回应是

"metrics-2019-08": 
    "mappings": 
        "_source": 
            "enabled": false
        
        ...
    

来自 Elasticserch 文档 here

_source 字段本身没有被索引(因此不可搜索),但它被存储以便在执行 fetch 请求时可以返回, 比如获取或搜索。

所以如果_source 为假,那么每个获取文档的请求都会返回空源。禁用此功能的原因是文档仅用于聚合(avg、min、max、sum ...),这些不需要_source,因此不存储_source 以节省磁盘空间。

要禁用此行为,请将 management.metrics.export.elastic.auto-create-index 设置为 false。如果你已经用 true 运行它,你需要用

删除现有的模板
DELETE http://localhost:9200/_template/metrics_template

之后,为指标索引创建模板,如下所示:

POST http://localhost:9200/_template/metrics_template

  "index_patterns": [
    "metrics*"
  ],
  "mappings": 
    "_source": 
      "enabled": true
    ,
    "properties": 
      "name": 
        "type": "keyword"
      ,
      "count": 
        "type": "double"
      ,
      "value": 
        "type": "double"
      ,
      "sum": 
        "type": "double"
      ,
      "mean": 
        "type": "double"
      ,
      "duration": 
        "type": "double"
      ,
      "max": 
        "type": "double"
      ,
      "total": 
        "type": "double"
      ,
      "unknown": 
        "type": "double"
      ,
      "active": 
        "type": "double"
      
    
  
 

除了_source设置为true之外,此模板与千分尺使用的模板相同。之后,文档将出现在 fetch 请求中,例如 get 或 search。

【讨论】:

我这样做了,它成功了,但是我的另一个应用程序(它也使用 Spring/Micrometer,工作并且我没有禁用 auto-create-inde)开始抛出:i.m.e.ElasticMeterRegistry : failed to send metrics to elastic: "took":581,"errors":true,"items":["index":"_index":"metrics-dispatcher-2020-06","_type":"doc","_id":"o5CmnXIB-_AiyWgfG-T4","status":400,"error":"type":"illegal_argument_exception","reason":"Can't merge because of conflicts: [Cannot update enabled setting for [_source]]" .只有在我删除模板后,这两个应用程序才能工作。知道为什么吗? 在您的情况下,_source 有两个具有不同值的应用程序,一个为 false,另一个为 true。在 Elasticsearch 中,您无法更新 _source 字段的映射值。这就是为什么第二个服务在启动时失败的原因,它正在更新映射并将 _source 设置为 false。 不必包含指标的来源以正确索引。它们在访问索引时可能不会出现,但它们在 Elasticsearch 中存在。您将需要使用 Kibana 之类的工具来可视化数据。这个 Github 问题解释了它:github.com/micrometer-metrics/micrometer/issues/1629 它对我有用,无需自己创建模板只需禁用自动创建索引并删除以前的索引,然后让千分尺重新创建索引即可修复它!

以上是关于带有千分尺 Elasticsearch 注册表的 Spring Boot 仅索引空文档的主要内容,如果未能解决你的问题,请参考以下文章

需要啥配置才能让带有 spring-boot 的千分尺输出 uvm_info 仪表?

为啥读数千分尺测量有时会返回 NaN?

在 Spring Boot 中,如何在每次测试之前重置指标注册表?

将金钱数变成带有千分位

如何使用 SLA 和标签注册 Micrometer Timer?

OTCBTC启动永久千分之二手续费活动