bosun使用elasticsearch作为数据源进行预警

前言

bosun可以使用elasticsearch作为数据源,还提供了许多操作elasticsearch的函数,可以非常方便地设置预警。相比之前需要自己写个elasticsearch的python接口,然后写脚本进行各种预警,bosun真是平台化了elasticsearch预警。

设置

bosun设置elasticsearch数据源非常简单,只要配置文件里配置elasticHosts参数然后重启即可:

elasticHosts = http://your_es_ip:9200  

your_es_ip:9200为你的elasticsearch的ip及端口,多节点用逗号分隔。需要注意的是,下面说的bosun所提供的操作elasticsearch的函数,需要elasticsearch的版本在2.0及以上才能支持。

一个实际例子

我们的nginx access log接入了elasticsearch。现在有个具体的需求,找出1小时内访问我们网站的请求数大于1000的ip,这些ip通常认为是在做不符合真实用户的操作,需要进行封禁。

假设经过elasticsearch索引后的日志,client_ip字段为访问者的ip,server_name是访问的域名。我们使用bosun提供的escount函数来获取数据:

escount(esls("logstash"), "client_ip,server_name",esquery("message","+server_name:s*.your-domain.com"), "1h", "1h", "")  
  1. 第一个参数,esls函数用来指定logstash-YYYY.MM.DD类型的index;
  2. 第二个参数是你所需要获取的fieldcvs格式(即逗号分隔),这些field从bosun获取回来后可以作为tag使用;
  3. 第三个参数,esquery函数是elasticsearch的全文搜索语句(不知道翻译得对不对,给出的文档在这里),它的第一个参数是字段,我们用了message这个整条日志的field;
  4. 第四个参数bucketDuration不懂怎么翻译,看文档好像是说统计间隔,1h表示每1小时统计;
  5. 最后两个参数分别是开始时间和结束时间。

alert:我们使用t聚合函数,当出现1个或以上的符合条件的series则进行预警,如下:

template client_ip {  
    subject = 【BOSUN】XXX网站请求数告警
    body = `<b>XXX网站请求数请求数告警</b>
    <table>
        <th>client_ip</th>
        <th>server_name</th>
        <th>次数(1小时内)</th>
        {{ range $f := .EvalAll .Alert.Vars.avg }}
            {{if gt $f.Value 1000.0}}
            <tr>
                <td style="color: green;">{{ $f.Group.client_ip }}</td>
                <td>{{ $f.Group.server_name }}</td>
                <td style="color: red;">{{ $f.Value | printf "%.0f" }}</td>
            </tr>
            {{ end }}
        {{ end }}
    </table>
    {{.Graph .Alert.Vars.metric}}
    `
}

alert client_ip {  
    runEvery = 60
    log = true
    maxLogFrequency = 60m
    ignoreUnknown = true
    template = client_ip
    $notes = 1小时内访问次数过多
    $metric = escount(esls("logstash"), "client_ip,server_name",esquery("message","+server_name:s*.your-domain.com"), "1h", "1h", "")
    $avg = avg($metric)
    $group = t($avg > 1000, "")
    $q = sum($group)
    crit = $q > 0
    critNotification = yw_email
}

收到的预警邮件如下: