Logstash做爲一個數據處理管道,提供了豐富的插件,可以從不一樣數據源獲取用戶數據,進行處理後發送給各類各樣的後臺。這中間,最關鍵的就是要對數據的類型就行定義或映射。html
本文討論的 ELK 版本爲 5.5.1。mysql
Elastisearch不只是一個強大的全文檢索引擎,它還可以對一些數據類型進行實時的統計運算,相關的結果能夠經過Kibana的圖表展示出來。若是數據類型沒有正確的定義,那麼Elasticsearch就沒法進行運算了,所以,雖然數據類型的定義須要花一點時間,但你會收到意想不到的效果。linux
全部送往Elasticsearch的數據都要求是JSON格式,Logstash所作的就是如何將你的數據轉換爲JSON格式。ElasticSearch會幫咱們自動的判斷傳入的數據類型,這麼作固然極大的方便了用戶,但也帶來了一些問題。git
Elastic中的一些數據類型: text、keyword、date、long、double、boolean、ip、object、nested、geo_point等。不一樣的類型有不一樣的用途,若是你須要全文檢索,那應該使用text類型,若是你須要統計彙總那應該選擇數據或者keyword類型。感謝動態映射 Dynamic Mapping 的存在,在向ES送數的時候咱們不須要事先定義映射關係,ES會對新增的字段自動進行映射。可是你比Elasticsearch更加熟悉你的數據,所以可能須要本身進行顯示定義 Explicit Mapping 映射關係。例如IP字段,默認是解析成字符串,若是映射爲IP類型,咱們就能夠在後續的查詢中按照IP段進行查詢,對工做是頗有幫助的。咱們能夠在建立索引時定義,也能夠在索引建立後定義映射關係。github
對於已經存在的數據,沒法更新映射關係。更新映射關係意味着咱們必須重建索引。web
先來看下面這個JSON文檔。sql
{ "@timestamp": "2017-08-11T20:11:45.000Z", "@version": "1", "count": 2048, "average": 1523.33, "host": "elasticsearch.com" }
這裏有五個字段:@timestamp
,@version
,count
,average
,host
。其中 @timestamp 和 host 是字符串,count、average 是數字,@version比較特殊,它的值是數字,可是由於放在雙引號中,因此做爲字符串來對待。apache
嘗試把數據送入到 Elasticsearch 中,首先建立一個測試的索引:json
將數據存入索引ruby
查看數據映射的狀況
根據結果可知,在沒有明肯定義數據類型的狀況下,Elasticsearch會自動判斷數據的類型,所以 @timestamp、@version、host都被映射爲 text ,average、count 被映射爲數字。
Logstash提供了 grok 和 mutate 兩個插件來進行數值數據的轉換。
grok 目前是解析非結構化的日誌數據最好的插件。特別適合處理syslog、apache或其餘web服務器、mysql等爲了閱讀而輸出的信息類日誌。
grok 的基本用法以下:%{SYNTAX:SEMANTIC}
,SYNTAX是grok提供的樣式Pattern的名稱,grok提供了120多種Pattern,SEMANTIC是你給匹配內容的名稱(標誌符)。由於grok其實是正則匹配,所以任何輸出都默認轉換爲字符類型,若是你須要數據類型的轉換,則使用下面這種格式
%{NUMBER:SEMANTIC:int}
目前,類型轉換僅支持 int 和 float 兩種類型。
若是將帶小數的數字轉換爲 int 類型,會將小數後的數字丟棄。
mutate 爲用戶提供了處理Logstash event數據的多種手段。容許咱們移除字段、重命名字段、替換字段、修改字段等操做。
filter { mutate { convert => { "num" => "integer" } } }
Elasticsearch中經過模板來存放索引字段的映射關係,logstash能夠在配置文件中指定模板文件來實現自定義映射關係。
查詢 Elasticsearch 中的模板,系統自帶了 logstash-* 的模板。
咱們用實際的例子來看一下映射和模板是如何起做用的。
一、首先建立一個 logstash 配置文件,經過 filebeat 讀取 combined 格式的 apache 訪問日誌。
配置文件名爲 filebeat.conf 位於 logstash 文件夾內。filebeat的配置比較簡單,能夠參考個人上一篇文章 Filebeat+Logstash+ElasticSearch+Kibana搭建Apache訪問日誌解析平臺
input { beats { port => "5043" } } filter { grok { match => { "message" => "%{COMBINEDAPACHELOG}" } } date { match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ] target => ["datetime"] } geoip { source => "clientip" } } output { elasticsearch { hosts => "localhost:9200" index => "my_index" #template => "/data1/cloud/logstash-5.5.1/filebeat-template.json" #template_name => "my_index" #template_overwrite => true } stdout { codec => rubydebug } }
第一次數據導入的時候,咱們先不使用模板,看看 es 如何默認映射數據,啓動elk環境,進行數據導入。
[maserati@iZ627x15h6pZ logstash-5.5.1]$ ../elasticsearch-5.5.1/bin/elasticsearch [maserati@iZ627x15h6pZ logstash-5.5.1]$ ./bin/logstash -f filebeat.conf [maserati@iZ627x15h6pZ filebeat-5.5.1-linux-x86_64]$ sudo ./filebeat -e -c filebeat.yml -d "publish"
數據導入完成後,看一下索引的狀況
由於從log導入的數據,因此mapping中給映射規則起名爲log,對應的是 document_type,能夠看到clientip和 geoip.location 分別解析成了文本和數值。其餘大部份內容都映射爲 text 。這種不須要咱們定義映射規則的處理方式很是方便,但有時候咱們更須要精確的映射。
看一下ES映射模板,只有logstash命名的模板,由於名稱不匹配,因此沒有應用這裏的映射規則。
這裏能夠注意到模板文件和索引中的映射關係稍有不一樣,不要緊,咱們把 my_index 的映射關係拷貝下來,存爲 filebeat-template.json ,這裏貼一下一個刪減版的 模板文件。
{ "template": "my_index", "order": 1, "settings": { "index.refresh_interval" : "5s" }, "mappings": { "_default_": { "properties": { "clientip" : { "type":"ip" }, "geoip": { "properties": { "location": { "type":"geo_point" } } } } } } }
咱們能夠經過命令行收工把模板上傳到 elasticsearch ,也能夠經過 logstash 配置文件指定。
curl -XPUT http://localhost:9200/_template/my_index_template?pretty -d @filebeat-template.json
個人例子中,咱們只須要把 filebeat.conf 中的註釋打開便可。而後刪除索引,咱們對索引重建一下。
看一下索引,能夠看到模板中定義的規則已經在裏面了。
看一下索引字段,看到 clientip 已經定義成 ip 類型了。
一樣,geoip.location映射成 geo_point 類型。
這樣咱們就能夠作訪客地圖了。
這時,再看一下 template 的狀況。
能夠看到,除了默認的模板,新增了一個咱們定義的 my_index 模板。後續還能夠對模板進行修改,可是注意只能增長或者刪除,沒法對已經映射的字段進行更新。
參考資料:
一、Using Logstash to help create an Elasticsearch mapping template
二、Using grok and mutate to type your data
三、Elasticsearch Mapping
四、Grok Filter Plugin
五、Mutate Filter Plugin
六、用logstash導入ES且自定義mapping時踩的坑