以前採用的是經過filebeat收集nginx的日誌,直接到elasticsearch。filebeat帶有nginx的module模塊,經過這個nginx模塊實現filebeat對nginx日誌中字段的處理。最近因爲一些實際的使用場景和需求,對nginx日誌的收集和處理方式作了一下調整:php
filebeat收集nginx原始日誌信息到kafka,而後logstash再從kafka讀取日誌,並進行字段處理後送到elasticsearch集羣。即相比原來的方式,添加了kafka層。nginx
logstash從kafka讀取過來的日誌爲json格式,字段的解析能夠藉助Grok Debugger工具來調,具體的解析方式這裏就不細說了。這裏主要說一下在logstash使用elasticsearch的template進行字段類型mapping的時候,須要注意的一點問題。json
logstash將日誌裏的字段解析出來併發送到elasticsearch後,發現es上字段的默認的類型都是text的。若是對一些關鍵字須要作統計報表的時候,就會出現提示報錯。如,我用grafana將elasticsearch作爲數據源進行數據展現時遇到以下報錯:
有報錯提示能夠看出,將nginx.access.remote_ip的字段換成keyword類型能夠解決。bash
因而,參考原先filebeat中使用的template,寫了一個供logstash用的template,起名爲nginx_req_log_wireless.json,部分片斷以下:markdown
"template": "nginx_req_log_wireless", "settings": { "index.refresh_interval": "5s" }, "mappings": { ...略 "nginx": { "properties": { "access": { "properties": { "referrer": { "ignore_above": 1024, "type": "keyword" }, "agent": { "norms": false, "type": "text" }, "response_code": { "type": "long" }, "geoip": { "properties": { "continent_name": { "ignore_above": 1024, "type": "keyword" }, "city_name": { "ignore_above": 1024, "type": "keyword" }, "country_name": { "ignore_above": 1024, "type": "keyword" }, "region_name": { "ignore_above": 1024, "type": "keyword" }, "location": { "type": "geo_point" } } }, "remote_ip": { "ignore_above": 1024, "type": "keyword" }, "method": { "ignore_above": 1024, "type": "keyword" }, "user_name": { "ignore_above": 1024, "type": "keyword" }, "http_version": { "ignore_above": 1024, "type": "keyword" }, "body_sent": { "properties": { "bytes": { "type": "long" } } }, "url": { "ignore_above": 1024, "type": "keyword" } ...略
以後,在logstash的output裏的elasticsearch配置部分對template模板進行指定:併發
index => "nginx_req_log_wireless-%{+YYYY.MM.dd}" manage_template => true template_name => "nginx_req_log_wireless" template_overwrite => true template => "/usr/local/logstash-5.4.3/template/nginx_req_log_wireless.json"
調試後發現,elasticsearch上建立的索引中字段的類型,並無按照指定的template去mapping。後來才注意到,是應爲建立的索引後面帶了日期部分:app
index => "nginx_req_log_wireless-%{+YYYY.MM.dd}"
這致使跟nginx_req_log_wireless.json模板文件中指定的template名並不匹配形成的:less
"template": "nginx_req_log_wireless"
解決辦法,就是將template名末尾加一個*號通配符便可:elasticsearch
"template": "nginx_req_log_wireless*"
總結一下:
index的名字必需要和指定的json文件中的templete名相匹配,定義的mapping纔會生效。logstash的output配置的template_name名能夠隨便。
工具