How to stop logstash from creating a default mapping in ElasticSearch

Prakash Shankor picture Prakash Shankor · Jul 24, 2014 · Viewed 26.5k times · Source

I am using logstash to feed logs into ElasticSearch. I am configuring logstash output as:

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

I notice that as soon as I start logstash it creates a mapping ( logs ) in ES as below.

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

How can I prevent logstash from creating this mapping ?

UPDATE:

I have now resolved this error too. "object mapping for [logs] tried to parse as object, but got EOF, has a concrete value been provided to it?"

As John Petrone has stated below, once you define a mapping, you have to ensure that your documents conform to the mapping. In my case, I had defined a mapping of "type: nested" but the output from logstash was a string. So I removed all codecs ( whether json or plain ) from my logstash config and that allowed the json document to pass through without changes.

Here is my new logstash config ( with some additional filters for multiline logs ).

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"
                }
}

Answer

John Petrone picture John Petrone · Jul 24, 2014

You will need a mapping to store data in Elasticsearch and to search on it - that's how ES knows how to index and search those content types. You can either let logstash create it dynamically or you can prevent it from doing so and instead create it manually.

Keep in mind you cannot change existing mappings (although you can add to them). So first off you will need to delete the existing index. You would then modify your settings to prevent dynamic mapping creation. At the same time you will want to create your own mapping.

For example, this will create the mappings for the logstash data but also restrict any dynamic mapping creation via "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"
                    }
        }
    }
}
'

Keep in mind that the index name "4glogs" and the type "logs" need to match what is coming from logstash.

For my production systems I generally prefer to turn off dynamic mapping as it avoids accidental mapping creation.

The following links should be useful if you want to make adjustments to your dynamic mappings:

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