首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Elasticsearch动态场映射与JSON点符号

Elasticsearch动态场映射与JSON点符号
EN

Stack Overflow用户
提问于 2019-12-24 18:29:57
回答 2查看 5K关注 0票数 5

我试图从Kubernetes集群中将日志写入Elasticsearch索引。Fluent位被用来读取stdout,它用元数据(包括pod标签)丰富了日志。一个简化的示例日志对象是

代码语言:javascript
复制
{
  "log": "This is a log message.",
  "kubernetes": {
    "labels": {
      "app": "application-1"
    }
  }
}

问题是,部署到集群中的其他几个应用程序的标签格式如下:

代码语言:javascript
复制
{
  "log": "This is another log message.",
  "kubernetes": {
    "labels": {
      "app.kubernetes.io/name": "application-2"
    }
  }
}

这些应用程序是通过Helm图表安装的,较新的应用程序遵循按这里布局的标签和选择器约定。标签和选择器的命名约定在2018年12月更新,见这里,并不是所有的图表都被更新以反映这一点。

这样做的最终结果是,取决于标签格式的哪种类型,首先将其放入一个弹性索引中,尝试发送另一个类型会抛出一个映射异常。如果我创建一个新的空索引并首先发送名称空间标签,尝试记录简单的app标签将引发此异常:

代码语言:javascript
复制
object mapping for [kubernetes.labels.app] tried to parse field [kubernetes.labels.app] as object, but found a concrete value

相反的情况是,将命名空间标签放在第二位,则会导致此异常:

代码语言:javascript
复制
Could not dynamically add mapping for field [kubernetes.labels.app.kubernetes.io/name]. Existing mapping for [kubernetes.labels.app] must be of type object but found [text].

我怀疑发生的事情是Elasticsearch将字段名中的句点视为JSON点表示法,并试图将其充实为一个对象。我从2015年起就找到了这个公关,它明确禁止字段名中的句号,但在2016年这个公关中似乎出现了相反的情况。还有一个从2015-2017年开始的多年期线程在讨论这个问题,但我找不到最新版本的最新版本。

我目前对前进的想法是标准化的赫尔姆图表,我们正在使用的所有标签使用相同的约定。这似乎是基本问题上的一个创可贴,但我觉得在Elasticsearch和动态字段映射的配置中,我遗漏了一些明显的东西。

这里的任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-03 23:58:59

我选择使用带有rename选项的Logstash过滤器,如下所述:

https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-rename

最终结果如下所示:

代码语言:javascript
复制
filter {
  mutate {
    '[kubernetes][labels][app]'   => '[kubernetes][labels][app.kubernetes.io/name]'
    '[kubernetes][labels][chart]' => '[kubernetes][labels][helm.sh/chart]'
  }
}
票数 3
EN

Stack Overflow用户

发布于 2019-12-24 20:37:26

虽然我个人从未遇到过完全相同的问题,但当我索引一些测试数据时,以及后来更改了应该被索引的文档的结构时(特别是当“非扁平”数据结构时),我遇到了类似的问题。

您对错误信息的解释是正确的。当您第一次索引文档时

代码语言:javascript
复制
{
  "log": "This is another log message.",
  "kubernetes": {
    "labels": {
      "app.kubernetes.io/name": "application-2"
    }
  }
}

Elasticsearch将通过动态映射将应用程序识别为一个对象/结构。

然后尝试对文档进行索引时

代码语言:javascript
复制
{
  "log": "This is a log message.",
  "kubernetes": {
    "labels": {
      "app": "application-1"
    }
  }
}

以前,动态创建的映射将字段应用程序定义为一个具有子字段的对象,但是elasticsearch遇到了一个具体的值,即"application-1“。

我建议您设置一个索引模板来定义正确的映射。对于“过时的”日志版本,我建议通过elasticsearch管道或使用Logstash等方法对特定文档进行预处理,以获得正确的格式。

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59472323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档