今天做地圖定位展示,展示的是ApacheWeb服務器的訪問日志文件中的來源IP。但是中間出現了報錯環節,說是索引不能匹配到geo_point類型,實在是不懂這是在說什么,后來在網站找了方法就解決了。主要報錯如下:
報錯信息:
No Compatible Fields: The "logstash_apachelogs" index pattern does not contain any of the following field types: geo_point”
覺得很是奇怪,再來看看我的配置文件
input {redis {host => "172.16.0.54"port => 6379db => 1password => "123456"data_type => "list"key => "apache_filter_index"codec => json {charset => "UTF-8"}add_field => {"[@metadata][myfulltotal]" => "apacheaccess_log"}} }filter {if [@metadata][myfulltotal] == "apacheaccess_log" {mutate {gsub => ["message","\\x","\\\x"]}if ( 'method":"HEAD' in [message] ) {drop{}}json {source => "message"add_field => {"[@metadata][direct_ip]" => "%{direct_ip}"}remove_field => "message"remove_field => "prospector"remove_field => "beat"remove_field => "host"remove_field => "input"remove_field => "source"remove_field => "offset"remove_field => "fields"remove_field => "@version"}date {match => ["timestamp","yyyy-MM-dd HH:mm:ss Z"]}mutate {split => ["client_ip",","]}mutate {replace => { "client_ip" => "%{client_ip[0]}"}}mutate {convert => ["body_bytes_sent","integer"]convert => ["total_bytes_sent","integer"]}if [client_ip] == "-" {if [@metadata][direct_ip] not in ["%{direct_ip}","-"]{mutate {replace => { "client_ip" => "%{direct_ip}" }}} else {drop {}}}geoip {source => "client_ip"target => ["geoip"]add_field => ["[geoip][coordinates]", "%{[geoip][longitude]}"]add_field => ["[geoip][coordinates]", "%{[geoip][latitude]}"]}mutate {convert => ["[geoip][coordinates]","float"]}mutate {remove_field => ["direct_ip"]remove_field => ["timestamp"]}} } output {if [@metadata][myfulltotal] == "apacheaccess_log" {elasticsearch {hosts => ["172.16.0.51:9200"]index => "logstash_apachelogs"}} }
看上去都是沒有問題的,只要是按照這個格式來寫,都沒有什么錯誤。只是在報錯信息中看出geo的location類型不是geo_point類型的,那我們通過GET命令查看一下mapping
[root@ELK-chaofeng07 httpd]# curl -XGET http://172.16.0.51:9200/logstash_apachelogs/_mapping/ {"logstash-apachelogs":{"mappings":{"_default_":{"dynamic_templates":,{"string_fields":{"match":"*","m,"@version":{"type":"keyword"},"geoip":{"dynamic":"true","properties":{"ip":{"type":"ip"},"latitude":{"type":"half_float"},"location":{"type":"geo_point"},"longitude":{"type":"half_float"}}}}},"doc":{"dynamic_templates":[{"message_field":{"path_match":"message","match_mapping_type":"string","mapping":{"norms":false,"type":"text"}}},{"string_fields":{"match":"*","match_mapping_type":"string","mapping":{"fields":{"keyword":{"ignore_above":256,"type":"keyword"}},"norms":false,"type":"text"}}}],"properties":{"@timestamp":{"type":"date"},"@version":{"type":"keyword"},"body_bytes_sent":{"type":"long"},"client_ip":{"type":"text","norms":false,"fields":{"keyword":{"type":"keyword",},"continent_code":{"type":"text","norms":false,"fields":{"keyword":{"type":"keyword","ignore_above":256}}},"coordinates":{"type":"float"},"country_code2":{"type":"text","norms":false,"fields":{"keyword":{"type":"keyword","ignore_above":256}}},"country_code3":{"type":"text","norms":false,"fields":{"keyword":{"type":"keyword","ignore_above":256}}},"country_name":{"type":"text","norms":false,"fields":{"keyword":{"type":"keyword","ignore_above":256}}},"ip":{"type":"ip"},"latitude":{"type":"half_float"},"location":{"type":"float"},"longitude":{"type":"half_float"},"region_code":}}}}}}}
看的出來我們此時的location是float類型的。所以如何將它變成geo_point類型是我們的解決目標方法
我們分析一下原因:
索引格式為logstash_apachelogs日志文件由logstash輸出到Elasticsearch;在 elasticsearch 中,所有的數據都有一個類型,什么樣的類型,就可以在其上做一些對應類型的特殊操作。geo信息中的location字段是經緯度,我們需要使用經緯度來定位地理位置;在 elasticsearch 中,對于經緯度來說,要想使用 elasticsearch 提供的地理位置查詢相關的功能,就需要構造一個結構,并且將其類型屬性設置為geo_point。
解決方法:
Elasticsearch支持給索引預定義設置和mapping,其實ES中已經有一個默認預定義的模板,我們只要使用預定的模板即可。我們要想使用預定義的模板,那么索引名必須匹配 logstash-* 的索引才會應用這個模板,由于我們在logstash中使用的是logstash_*的索引方式,因此并沒有匹配默認模板,所以只需要修改一下索引名即可。然后我們就可以看到map不再報這個錯誤了。
所以說這是個相當不起眼的錯誤,但是引發了這個大的問題,搞的讓人很懵比,所以接下來我們得好好研究一下mapping是什么,