轉自:https://blog.csdn.net/felix_yujing/article/details/78930389
之前采用的是通過filebeat收集nginx的日志,直接到elasticsearch。filebeat帶有nginx的module模塊,通過這個nginx模塊實現filebeat對nginx日志中字段的處理。最近由於一些實際的使用場景和需求,對nginx日志的收集和處理方式做了一下調整:
filebeat收集nginx原始日志信息到kafka,然后logstash再從kafka讀取日志,並進行字段處理后送到elasticsearch集群。即相比原來的方式,添加了kafka層。
logstash從kafka讀取過來的日志為json格式,字段的解析可以借助Grok Debugger工具來調,具體的解析方式這里就不細說了。這里主要說一下在logstash使用elasticsearch的template進行字段類型mapping的時候,需要注意的一點問題。
logstash將日志里的字段解析出來並發送到elasticsearch后,發現es上字段的默認的類型都是text的。如果對一些關鍵字需要做統計報表的時候,就會出現提示報錯。如,我用grafana將elasticsearch做為數據源進行數據展示時遇到如下報錯:
有報錯提示可以看出,將nginx.access.remote_ip的字段換成keyword類型可以解決。
於是,參考原先filebeat中使用的template,寫了一個供logstash用的template,起名為nginx_req_log_wireless.json,部分片段如下:
"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" } ...略
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
之后,在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"
- 1
- 2
- 3
- 4
- 5
調試后發現,elasticsearch上創建的索引中字段的類型,並沒有按照指定的template去mapping。后來才注意到,是應為創建的索引后面帶了日期部分:
index => "nginx_req_log_wireless-%{+YYYY.MM.dd}"
- 1
這導致跟nginx_req_log_wireless.json模板文件中指定的template名並不匹配造成的:
"template": "nginx_req_log_wireless"
- 1
解決辦法,就是將template名末尾加一個*號通配符即可:
"template": "nginx_req_log_wireless*"
- 1
總結一下:
index的名字必須要和指定的json文件中的templete名相匹配,定義的mapping才會生效。logstash的output配置的template_name名可以隨便。