【问题标题】:How to stop logstash from creating a default mapping in ElasticSearch如何阻止 logstash 在 ElasticSearch 中创建默认映射
【发布时间】:2014-07-24 02:41:07
【问题描述】:

我正在使用 logstash 将日志提供给 ElasticSearch。 我将logstash输出配置为:

input {
file {
            path => "/tmp/foo.log"
            codec =>
                    plain {
                    format => "%{message}"
            }
    }
}
output {
        elasticsearch {
                        #host => localhost 
                        codec => json {}
                        manage_template => false
                        index => "4glogs"
                }
}

我注意到,一旦我启动 logstash,它就会在 ES 中创建一个映射 (logs),如下所示。

{
    "4glogs": {
        "mappings": {
            "logs": {
                "properties": {
                    "@timestamp": {
                        "type": "date",
                        "format": "dateOptionalTime"
                    },
                    "@version": {
                        "type": "string"
                    },
                    "message": {
                        "type": "string"
                    }
                }
            }
        }
    }
}

如何防止 logstash 创建此映射?

更新:

我现在也解决了这个错误。 “[logs] 的对象映射尝试解析为对象,但得到了 EOF,是否为其提供了具体值?”

正如 John Petrone 下面所说,一旦定义了映射,您必须确保您的文档符合映射。在我的例子中,我定义了一个“type:nested”的映射,但是logstash的输出是一个字符串。 因此,我从我的 logstash 配置中删除了所有编解码器(无论是 json 还是 plain),这使得 json 文档可以通过而无需更改。

这是我的新 logstash 配置(带有一些额外的多行日志过滤器)。

input {
    kafka {
        zk_connect => "localhost:2181"
        group_id => "logstash_group"
        topic_id => "platform-logger"
        reset_beginning => false
        consumer_threads => 1
        queue_size => 2000
        consumer_id => "logstash-1"
        fetch_message_max_bytes => 1048576
        }
        file {
                path => "/tmp/foo.log"
        }
}
filter {
  multiline {
    pattern => "^\s"
    what => "previous"
  }
  multiline {
    pattern => "[0-9]+$"
    what => "previous"
  }
  multiline {
    pattern => "^$"
    what => "previous"
  }
        mutate{
                remove_field => ["kafka"]
                remove_field => ["@version"]
                remove_field => ["@timestamp"]
                remove_tag => ["multiline"]
        }
 }
output {
        elasticsearch {
                        manage_template => false
                        index => "4glogs"
                }
}

【问题讨论】:

  • 是在第一条消息到达时创建还是在日志存储开始时创建?
  • 仔细观察,似乎是第一条消息到达的时候。
  • 好吧,你不能改变它,这就是elasticsearch所做的。它需要一个映射,如果它不可用,它会自动创建一个。你想完成什么?
  • Jettro,感谢您的回复。我不希望在第一条消息上发生动态映射。因此,似乎定义我自己的映射(严格)是一种方式。但是我自己的映射仍然存在问题。请参阅下面的“对象映射错误”。

标签: elasticsearch logstash


【解决方案1】:

您将需要一个映射来在 Elasticsearch 中存储数据并对其进行搜索——这就是 ES 知道如何索引和搜索这些内容类型的方式。您可以让 logstash 动态创建它,也可以阻止它这样做,而是手动创建它。

请记住,您无法更改现有映射(尽管您可以添加它们)。所以首先你需要删除现有的索引。然后,您将修改您的设置以防止创建动态映射。同时你会想要创建你自己的映射。

例如,这将为 logstash 数据创建映射,但也会通过“strict”限制任何动态映射的创建:

$ curl -XPUT 'http://localhost:9200/4glogs/logs/_mapping' -d '
{
    "logs" : {
        "dynamic": "strict",
        "properties" : {
            "@timestamp": {
                "type": "date",
                "format": "dateOptionalTime"
                    },
            "@version": {
                "type": "string"
                    },
             "message": {
                "type": "string"
                    }
        }
    }
}
'

请记住,索引名称“4glogs”和类型“logs”需要与来自 logstash 的内容相匹配。

对于我的生产系统,我通常更喜欢关闭动态映射,因为它可以避免意外创建映射。

如果您想调整动态映射,以下链接应该很有用:

https://www.elastic.co/guide/en/elasticsearch/guide/current/dynamic-mapping.html

http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/custom-dynamic-mapping.html

http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/dynamic-mapping.html

【讨论】:

  • 我可以使用 "dynamic":"strict" 并拥有自己的映射。但是现在我遇到了一个不同的错误:“[logs] 的对象映射尝试解析为对象,但得到了 EOF,是否提供了具体值?”
  • 为了更清楚,我已经为类型“logs”和索引“4glogs”定义了我自己的映射。我不能在这里粘贴我的映射,因为它太大了。我的映射在“消息”字段下使用 "type": "nested"。使用此映射,对文档进行索引的任何尝试都会导致错误:“[logs] 的对象映射尝试解析为对象,但获得了 EOF,是否已为其提供了具体值?”
  • 当您将映射更改为包含 "type": "nested" 时,您是在告诉 ES 期待一些对象、未知字段并让它动态映射它们——但您关闭了动态映射。还要记住,即使打开了动态映射,第一个嵌套文档也会为其定义映射,因此如果后面的任何数据不匹配(例如,字段名称相同但数据类型不同),您将收到错误消息。
  • 约翰,感谢您的帮助。你是说我不能使用“嵌套”并定义我自己的映射?我的嵌套映射明确定义了子字段及其类型。
  • (请原谅格式)我的映射示例是:{ "mappings": { "logs": { "properties": { "message": { "type": "nested", "properties": { "level": { "type": "string", "store": "no" }, "logger": { "type": "string", "store": "yes" }, "timestamp": { "type": "string", "store": "no" } } } } } } }
【解决方案2】:

logs 在这种情况下是index_type。如果您不想将其创建为 logs,请在您的 elasticsearch 元素上指定其他一些 index_type。 elasticsearch 中的每条记录都需要有一个索引和一个类型。如果您没有指定,Logstash 默认为 logs

当您将记录插入 Elasticsearch 时,总会创建一个隐式映射,因此您无法阻止它被创建。您可以在插入任何内容之前自己创建映射(通过模板映射)。

false 的设置manage_template 只是阻止它为您指定的index 创建模板映射。如果已经使用curl -XDELETE http://localhost:9200/_template/logstash?pretty 之类的东西创建了现有模板,您可以删除它

【讨论】:

    【解决方案3】:

    索引模板可以帮助您。请参阅此jira 了解更多详情。您可以创建支持通配符的索引模板以匹配索引名称并放置您的默认映射。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    相关资源
    最近更新 更多