elasticsearch Logstash&x2B;ElasticSearch:初始类型映射导致缺少日志行,elasticsearch,logstash,kibana,elasticsearch,Logstash,Kibana" /> elasticsearch Logstash&x2B;ElasticSearch:初始类型映射导致缺少日志行,elasticsearch,logstash,kibana,elasticsearch,Logstash,Kibana" />

elasticsearch Logstash&x2B;ElasticSearch:初始类型映射导致缺少日志行

elasticsearch Logstash&x2B;ElasticSearch:初始类型映射导致缺少日志行,elasticsearch,logstash,kibana,elasticsearch,Logstash,Kibana,我们有一个用于日志聚合的经典logstash+elasticsearch+kibana设置。我们使用它来聚合所有服务器和应用程序中的日志,我们偶然发现了以下问题:ES第一次收到日志行(在我们的例子中是JSON文档)时,它会为该文档创建一个映射(请参阅)。大多数情况下,属性映射为字符串,但在某些情况下,属性映射为日期或数字。在后一种情况下,如果另一个日志行(来自不同的应用程序)具有相同的字段,但具有字符串值,ES将无法对其进行索引(向其日志抛出异常,并照常继续)。作为一种解决方法,我们已将ES配置

我们有一个用于日志聚合的经典logstash+elasticsearch+kibana设置。我们使用它来聚合所有服务器和应用程序中的日志,我们偶然发现了以下问题:ES第一次收到日志行(在我们的例子中是JSON文档)时,它会为该文档创建一个映射(请参阅)。大多数情况下,属性映射为字符串,但在某些情况下,属性映射为日期或数字。在后一种情况下,如果另一个日志行(来自不同的应用程序)具有相同的字段,但具有字符串值,ES将无法对其进行索引(向其日志抛出异常,并照常继续)。作为一种解决方法,我们已将ES配置为忽略格式错误的文档(index.mapping.ignore\u malformed:true),但它更像是一种黑客行为


有什么好办法可以优雅地解决这个问题吗?

听起来你们不在乎日期类型或任何类型。 我认为最好的解决方案是定义一个动态模板,将所有类型定义为字符串:

{
    "_default_" : {
        "dynamic_templates" : [
            {
                "long_to_string" : {
                    "match" : "*",
                    "match_mapping_type": "long",
                    "mapping" : {
                        "type" : "string",
                        "index" : "analyzed"
                    }
                }
            },
            {
                "double_to_string" : {
                    "match" : "*",
                    "match_mapping_type": "double",
                    "mapping" : {
                        "type" : "string",
                        "index" : "analyzed"
                    }
                }
            },
            {
                "float_to_string" : {
                    "match" : "*",
                    "match_mapping_type": "float",
                    "mapping" : {
                        "type" : "string",
                        "index" : "analyzed"
                    }
                }
            },
            {
                "integer_to_string" : {
                    "match" : "*",
                    "match_mapping_type": "integer",
                    "mapping" : {
                        "type" : "string",
                        "index" : "analyzed"
                    }
                }
            },
            {
                "date_to_string" : {
                    "match" : "*",
                    "match_mapping_type": "date",
                    "mapping" : {
                        "type" : "string",
                        "index" : "analyzed"
                    }
                }
            },
            {
                "boolean_to_string" : {
                    "match" : "*",
                    "match_mapping_type": "boolean",
                    "mapping" : {
                        "type" : "string",
                        "index" : "analyzed"
                    }
                }
            }
        ]
    }
}

从。

经过大量研究,我可以遗憾地宣布,目前还不存在解决这一问题的优雅解决方案。虽然可以声明不应分析字段,但不能告诉它动态更改其类型,也不能自动忽略类型

这实际上意味着您首先发送的任何类型都将是唯一可以索引到该字段的类型。 如果您使用类型预先声明了字段,那么您将无法索引除该类型之外的任何内容。 在这两种情况下,所有不匹配的类型都将删除。 另外,请注意,这通常会淹没elasticsearch的日志文件,您应该设置日志旋转或将elasticsearch配置为不在其日志yaml中记录这些错误

您的解决方案确实是一个潜在的黑客(除非您确定未索引的数据是无关的)。这很像一个try:something,除了:传入python

作为一般规则(从经验来看),我建议不要将不同类型的数据(而不是不同的elasticsearch类型)索引到具有相同名称的字段中,因为当尝试使用基于数字/字符串的查询时,在Kibana中进行分析会变得非常困难(您将无法在该特定字段上排序或显示直方图或饼图。)
显然,仅仅更改代码(或其他应用程序的代码)使其不索引到同一字段并不总是容易的,在这种情况下,我将识别原始应用程序并使用logstash的grok(除非您已经发送了json)和变异过滤器来替换字段的名称。

想知道为什么忽略格式错误被认为是一种黑客行为吗?我想,他们加入该功能的原因完全相同——有时字段的计算结果可能与声明的数据类型不符。它真的会破坏任何东西吗

编辑/更新:
对于日志摄取/处理/索引,我的经验是,直接将日志摄取到像ES这样的存储中是一个坏主意,原因有很多(如果您好奇,请随时询问这些是什么)

简而言之,在将数据推入任何数据存储库(如ElasticSearch或HDFS)之前,我总是使用摄取/解析引擎。您可以使用logStash或flume等代理使用grok处理/解析数据。或者,在将数据馈送给ES之前,编写自定义Spark应用程序来摄取、验证和构造数据

通常,我会像这样构建日志管道: 制作人(syslog等)->Kafka/Kinesis(主题1)->Spark流媒体应用程序(应用解析/结构化规则)->Kafka/Kinesis(主题2)->多个代理(每个数据存储库一个代理组)例如,我将部署一组flume代理,订阅topic-2并写入HDFS。同时,部署一组logStash代理并写入ES


可能看起来有点牵扯,但更干净/一致的数据的好处是多方面的。从临时的数据探索者到数据科学家,每个人都会感谢你:)

上次我检查它时,它只是从文档中省略了字段,如果你不想丢失数据,这是不可接受的。这是黑客行为,因为该设置是全局的,并且适用于所有索引。