Logstash整合Kafka( 二 )


这里使用dynamic_templates是因为我们这里有嵌套结构logs , 即使我们在内嵌的logs结构中定义了字段是not_analyzed , 但是新创建出来的索引数据仍然是analyzed的(不知道是为什么) 。 如果字段都是analyzed就无法在Kibana中进行统计 , 这里使用dynamic_templates , 给所有动态字段都加一个raw字段 , 这个字段名就是原字段(比如:logs.name)后面加上一个.raw(变成logs.name.raw) , 专门用来解决analyzed无法做统计的 , 所有的.raw字段都是not_analyzed , 这样就可以使用.raw字段(logs.name.raw)进行统计分析了 , 而全文搜索可以继续使用原字段(logs.name) 。
这里还需要注意的就是 , 需要精确匹配的字段要设置成not_analyzed(例如:某些ID字段 , 或者可枚举的字段等等) , 需要全文搜索的字段要设置成analyzed(例如:日志详情 , 或者具体错误信息等等) , 否则在Kibana全文搜索的时候搜索结果是正确的 , 但是没有高亮 , 就是因为全文搜索默认搜索的是_all字段 , 高亮结果返回却是在_source字段中 。 还有Kibana的全文搜索默认是搜索的_all字段 , 需要在ES创建mapping的时候设置_all开启状态 。
Highlight高亮不能应用在非String类型的字段上 , 必须把integer , long等非String类型的字段转化成String类型来创建索引 , 这样这些字段才能够被高亮搜索 。
还有就是记得每次修改完ES Mapping文件要刷新Kibana中的索引
最终修改后的ES Mapping如下:
{"mappings": {"_default_": {"_all": {"enabled": true},"dynamic_templates": [{"my_template": {"match_mapping_type": "string","mapping": {"type": "string","fields": {"raw": {"type": "string","index": "not_analyzed"}}}}}]},"api": {"properties": {"timestamp": {"format": "strict_date_optional_time||epoch_millis","type": "date"},"message": {"type": "string","index": "not_analyzed"},"level": {"type": "string","index": "not_analyzed"},"host": {"type": "string","index": "not_analyzed"},"logs": {"properties": {"uid": {"type": "string","index": "not_analyzed"},"status": {"type": "string","index": "not_analyzed"},"did": {"type": "long","fields": {"as_string": {"type": "string","index": "not_analyzed"}}},"device-id": {"type": "string","index": "not_analyzed"},"device_id": {"type": "string","index": "not_analyzed"},"errorMsg": {"type": "string","fields": {"raw": {"type": "string","index": "not_analyzed"}}},"rpid": {"type": "string","index": "not_analyzed"},"url": {"type": "string","fields": {"raw": {"type": "string","index": "not_analyzed"}}},"errorStatus": {"type": "long","fields": {"as_string": {"type": "string","index": "not_analyzed"}}},"ip": {"type": "string","index": "not_analyzed"},"timestamp": {"type": "string","index": "not_analyzed"},"hb_uid": {"type": "long","fields": {"as_string": {"type": "string","index": "not_analyzed"}}},"duid": {"type": "string","index": "not_analyzed"},"request": {"type": "string","fields": {"raw": {"type": "string","index": "not_analyzed"}}},"name": {"type": "string","fields": {"raw": {"type": "string","index": "not_analyzed"}}},"errorCode": {"type": "string","index": "not_analyzed"},"ua": {"type": "string","fields": {"raw": {"type": "string","index": "not_analyzed"}}},"server_timestamp": {"type": "long"},"bid": {"type": "long","fields": {"as_string": {"type": "string","index": "not_analyzed"}}}}},"path": {"type": "string","fields": {"raw": {"type": "string","index": "not_analyzed"}}},"type": {"type": "string","index": "not_analyzed"},"@timestamp": {"format": "strict_date_optional_time||epoch_millis","type": "date"},"@version": {"type": "string","index": "not_analyzed"}}}}}name , request , path , ua , url , errorMsg虽然设置了analyzed , 但是同时也需要做统计 , 所以在这几个字段单独加上了.raw字段 , 用来统计使用 。
这里有个小技巧就是我们没有直接把long类型的字段直接转换成String类型 , 我们是在这个long类型的字段下创建了一个as_string字段 , as_string这个字段是String类型的 , 并且是not_analyzed , 这样Kibana在全文搜索的时候就会高亮出来long类型的字段了 , 实际上是高亮的long类型字段下的String字段 。 举例:下面是搜索一个logs.bid字段 , logs.bid这个字段是long类型的 , 但是我们在这个字段下创建了一个logs.bid.as_string字段 , 实际上highlight高亮的字段也是logs.bid.as_string这个字段 。
参考:

..."highlight": {"logs.duid": ["@kibana-highlighted-field@wasl6@/kibana-highlighted-field@"],\"logs.bid.as_string": ["@kibana-highlighted-field@79789714801950720@/kibana-highlighted-field@"],"type": ["@kibana-highlighted-field@api@/kibana-highlighted-field@"],"logs.request": ["GET /@kibana-highlighted-field@api@/kibana-highlighted-field@/hongbao/realname/info"]}...Kibana查询Request{"size": 500,"highlight": {"pre_tags": ["@kibana-highlighted-field@"],"post_tags": ["@/kibana-highlighted-field@"],"fields": {"*": {}},"require_field_match": false,"fragment_size": 2147483647},"query": {"filtered": {"query": {"query_string": {"query": "keyword","analyze_wildcard": true}}}},"fields": ["*","_source"]}