一、 前奏
这段时间在完善kibana中实现预警机制,通过Sentinl实现。关于sentinl的使用就不做介绍了,这个插件功能还是很强大的,可以实现邮件预警及通过webhook接口的方式实现微信预警。sentinl中对预警数据的筛选是通过ES的DSL查询语句实现的。
二、问题场景
现在有这么个场景对zk的服务数进行预警,我们建了一个服务实施的通过zk注册中心正常的服务数,然后通过filebeat收集相关服务数日志,如果服务异常我们通过sentinl对日志进行筛查后实现预警。
相关的预警脚本如下:
{
"query": {
"bool": {
"must": [
{
"term": {
"tags": "nlp-log-monitor"
}
},
{
"range": {
"zootemAbnMsg": { "gte" : 1 }
}
},
{
"range": {
"@timestamp": {
"gte": "now-30s",
"lte": "now",
"format": "epoch_millis"
}
}
}
]
}
}
}
这段脚本的主要含义是查询当前时间30s内,服务nlp-log-monitor中异常服务数“zootemAbnMsg”大于1的日志,如果扫描到了,则通过sentinl预警。
term 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型)
最终的提示脚本:
dubbo服务数预警|{{payload.hits.total}}|ERROR dubbo服务数异常,宕机应用数:{{payload.hits.hits.0._source.zootemAbnMsg}},宕机应用:{{payload.hits.hits.0._source.zootemAbnMsgParam}}
但是上面的脚本是无法查询到数据的,“term”是需要not_analyzed ,ES里默认的分词器为standard。
我们通过命令分析下“nlp-log-monitor”是否被分词了。
POST http://10.XXX.XX.XXX:8200/logstash-2019.07.12/_analyze
{"text":"nlp-log-monitor"}
返回结果如下:
{
"tokens": [
{
"token": "nlp",
"start_offset": 0,
"end_offset": 3,
"type": "" ,
"position": 0
},
{
"token": "log",
"start_offset": 4,
"end_offset": 7,
"type": "" ,
"position": 1
},
{
"token": "monitor",
"start_offset": 8,
"end_offset": 15,
"type": "" ,
"position": 2
}
]
}
我们发下“nlp-log-monitor”被分词了,想要改变这个我们就需要引用其他的分词器。这里推荐使用ik分词器。关于ik分词器的安装网上有很多资料,主要需要注意安装的版本需要和es版本一致。分词器安装完成后,网上有很多方式说可以在es的config/elasticsearch.yml文件中配置,6.x版本后就不需要指定了。这里需要注意下。
三、logstash配置分词器
分词器的配置方式有很多种,比如在es中初始化时配置,由于我们使用的是logstash自动生成es索引的方式这里我们采用在logstash配置分词模板的方式:
1.在logstash的安装目录config下建立分词模板yrz-logstash.json
{
"index_patterns": ["yrz-logstash-*"],
"settings": {
"number_of_shards": 3
},
"mappings": {
"doc": {
"dynamic_templates": [{
"es": {
"match": "message",
"match_mapping_type": "string",
"mapping": {
"type": "text",
"analyzer": "ik_smart"
}
}
},
{
"en": {
"match": "tags",
"match_mapping_type": "string",
"mapping": {
"type": "keyword",
"analyzer": "ik_smart"
}
}
},
{
"ea": {
"match": "*",
"match_mapping_type": "string",
"mapping": {
"norms": false,
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}]
}
},
"aliases": {}
}
模板中参数的具体含义网上都可以找到, “match”: “tags”,这里就是我们指定了tags的分词方式为“ik_smart”。
es中初始导入可以通过命令PUT http://10.xxx.xx.xxx:8200/_template/yrz-logstash导入。
logstash启动conf文件中新增如下配置:
output {
if [type] == "filebeat"{
elasticsearch {
hosts => ["10.xxx.xx.xxx:8200"]
index => "yrz-logstash-%{+YYYY.MM.dd}"
action => "index"
template=>"/usr/local/nlp/logstash-6.0.1/config/yrz-logstash.json"
template_name=>"yrz-logstash"
#manage_template => true
template_overwrite => true
user => "elastic"
password => "xxxx"
}
}
........
}
配置完成后启动相关服务,后续的日志我们就可以按照新的分词规则往es中记录数据。
后面在kibana中发现了tags.keyword,我们在配置sentinl是可以改为如下一样可以精确匹配到我们的数据:
{
"term": {
"tags.keyword": "nlp-log-monitor"
}
},
keyword:存储数据时候,不会分词建立索引,text:存储数据时候,会自动分词