elasticsearch Elasticsearch动态字段映射和JSON点表示法,elasticsearch,kubernetes,logstash,kubernetes-helm,fluent-bit,elasticsearch,Kubernetes,Logstash,Kubernetes Helm,Fluent Bit" /> elasticsearch Elasticsearch动态字段映射和JSON点表示法,elasticsearch,kubernetes,logstash,kubernetes-helm,fluent-bit,elasticsearch,Kubernetes,Logstash,Kubernetes Helm,Fluent Bit" />

elasticsearch Elasticsearch动态字段映射和JSON点表示法

elasticsearch Elasticsearch动态字段映射和JSON点表示法,elasticsearch,kubernetes,logstash,kubernetes-helm,fluent-bit,elasticsearch,Kubernetes,Logstash,Kubernetes Helm,Fluent Bit,我试图将日志从Kubernetes集群写入Elasticsearch索引。Fluent bit用于读取标准输出,它使用元数据(包括pod标签)丰富日志。下面是一个简化的日志对象示例 { "log": "This is a log message.", "kubernetes": { "labels": { "app": "application-1" } } } 问题在于,部署到集群的其他一些应用程序具有以下格式的标签: { "log": "This

我试图将日志从Kubernetes集群写入Elasticsearch索引。Fluent bit用于读取标准输出,它使用元数据(包括pod标签)丰富日志。下面是一个简化的日志对象示例

{
  "log": "This is a log message.",
  "kubernetes": {
    "labels": {
      "app": "application-1"
    }
  }
}
问题在于,部署到集群的其他一些应用程序具有以下格式的标签:

{
  "log": "This is another log message.",
  "kubernetes": {
    "labels": {
      "app.kubernetes.io/name": "application-2"
    }
  }
}
这些应用程序是通过Helm charts安装的,而较新的应用程序则遵循标签和选择器约定。标签和选择器的命名约定已于2018年12月更新,如图所示,并非所有图表都已更新以反映这一点

这样做的最终结果是,根据哪种类型的标签格式使其首先进入弹性索引,尝试发送另一种类型将引发映射异常。如果我创建一个新的空索引并首先发送带名称空间的标签,尝试记录简单的
app
标签将引发以下异常:

object mapping for [kubernetes.labels.app] tried to parse field [kubernetes.labels.app] as object, but found a concrete value
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].
相反的情况是,第二次发布带名称空间的标签会导致此异常:

object mapping for [kubernetes.labels.app] tried to parse field [kubernetes.labels.app] as object, but found a concrete value
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年,也有多年的时间讨论这个问题,但我找不到任何涉及最新版本的最新内容

我目前对前进的想法是标准化我们使用的舵图,使所有标签使用相同的约定。这似乎是一个创可贴的基础问题,虽然我觉得我缺少一些明显的配置在弹性搜索和动态字段映射。
这里的任何帮助都将不胜感激。

尽管我个人从未遇到过完全相同的问题,但当我为一些测试数据编制索引并随后更改本应编制索引的文档结构时,我遇到了类似的问题(尤其是在“取消平台”数据结构时)

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

{
  "log": "This is another log message.",
  "kubernetes": {
    "labels": {
      "app.kubernetes.io/name": "application-2"
    }
  }
}
{
  "log": "This is a log message.",
  "kubernetes": {
    "labels": {
      "app": "application-1"
    }
  }
}
由于动态映射,Elasticsearch将应用程序识别为对象/结构

然后尝试为文档编制索引时

{
  "log": "This is another log message.",
  "kubernetes": {
    "labels": {
      "app.kubernetes.io/name": "application-2"
    }
  }
}
{
  "log": "This is a log message.",
  "kubernetes": {
    "labels": {
      "app": "application-1"
    }
  }
}
先前动态创建的映射将字段app定义为具有子字段的对象,但elasticsearch遇到了一个具体值,即“application-1”

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


希望这能有所帮助。

我选择使用带有
重命名
选项的Logstash mutate过滤器,如下所述:

最终结果如下所示:

filter {
  mutate {
    '[kubernetes][labels][app]'   => '[kubernetes][labels][app.kubernetes.io/name]'
    '[kubernetes][labels][chart]' => '[kubernetes][labels][helm.sh/chart]'
  }
}

我认为Logstash管道将是使用变异过滤器的最直接的方法。我唯一关心的是复制/删除需要在显式定义的标签集上,而不是通用解决方案。我会尝试你的建议,并在这里更新结果。谢谢你可以用ruby过滤器来实现它。您将根据正则表达式解析每个字段。如果该字段包含点,您将提取该值,并基于点的位置,新创建的字段将是一个值或对象字段。当我回到家的时候,我会实现这一点。听起来很有趣;-)你能给我更多需要转换成目标结构的字段的例子吗?