openfalcon源码分析之Judge
openfalcon源码分析之Judge
本节内容
- Judge功能
- 源码分析
- 设计优缺点
1. Judge功能
在open-falcon中,Judge模块的功能是通过从HBS上同步告警的strategys(告警策略),及Expression,用来在接收transfer上报过来的数据时,对数据进行检测,每收到一条上报的数据,就去匹配对应的strategy和Expression是否满足条件,判断是否需要向redis发送告警。
告警策略
open-falcon中的策略有两类,strategys和Expression。strategys与主机进行管线,可以通过一个主机找到其对应的所有strategys。而Expression则不需要有任何关联,是对全局范围内进行的一个过滤和判断。
stratrgys查找策略
从transfer上接收过来的数据带有endpoint,通过主机可以找到其对应的主机组(主机和主机组是多对多的关系),通过主机组可以找到对应的模板组(模板和主机组是多对多的关系),模板之间又可能有继承关系,通过模板组可以找到对应的strategy(模板和strategy是一对多的关系)一个模板就是一组strategy的集合。这样就可以通过上报过来的数据的endpoint找到其对应的所有的strategys了。
expression查找策略
expression不和主机关联,其针对的是全局的配置,主要对应一些需要特殊定制的告警检查。
2. 源码分析
处理流程分析
接收数据方
- 通过RPC注册两个方法,一个是ping,返回一个nil的返回值,另一个是send,处理transfer发送过来的数据。
- 对于transfer发送过来的每个监控数据,都会生成一个pk(对数据的endpoint,metric,tags进行字符串拼接,之后再用md5进行hash,生成一个hash值)。通过pk的前两位hash值,去HistoryBigMap中找到对应的值,调用PushFrontAndMaintain。(HistoryBigMap的结构会在后面进行讲解)
- 调用PushFrontAndMaintain会去JudgeItemMap中找到pk对应的值(链表)
-
若该pk能找到值,则调用该链表的PushFrontAndMaintain方法,将新到来的监控数据和链表最大长度传递进去。链表的PushFrontAndMaintain方法将新监控数据插入到链表的头部,如果超过了最大长度,则把最老的数据删除。再调用Judge方法对新监控数据和历史数据进行判断。
- 若没找到值,则会新创建一个链表,把新监控数据放入链表中。再调用Judge方法对新监控数据和历史数据进行判断。
-
- Judge方法会调用CheckStrategy方法以及CheckExpression方法对新监控数据和历史数据进行处理。
- CheckStrategy方法先将监控数据中的endpoint和metric进行字符串拼接成key,通过key去strategys中寻找对应的strategys列表。对于一个监控数据如果找到了多个strategy,则会对每个strategy的tags进行匹配,若和监控数据不符合则被过滤掉。剩下的每个strategys将会调用judgeItemWithStrategy方法,该方法先将strategy的表达式进行拼接找到对应的函数,然后将历史数据传递到Compute中进行逻辑判断,如果判断匹配则返回的值isTriggered为true,否则返回false.在judgeItemWithStrategy中会创建event事件,调用sendEventIfNeed方法判断该event是否应该发送出去。
- sendEventIfNeed方法会去检查LastEvents中该event是否已经存在,并按照一定规则判断是否需要调用sendEvent将event发送到redis中。源码如下.
- CheckExpression方法先将监控数据中的endpoint、metric、tags进行字符串拼接成key,再用该key在ExpressionMap字典中检查是否有对应的expressions,如果找到则调用filterRelatedExpressions进行处理
- filterRelatedExpressions检查所有对应的expressions,筛选掉tags不匹配的expressions,剩下的就是所有符合条件的expressions,针对所有符合条件的expressions,调用judgeItemWithExpression构建告警event,后面的处理步骤和strategys一致。
- CheckStrategy方法先将监控数据中的endpoint和metric进行字符串拼接成key,通过key去strategys中寻找对应的strategys列表。对于一个监控数据如果找到了多个strategy,则会对每个strategy的tags进行匹配,若和监控数据不符合则被过滤掉。剩下的每个strategys将会调用judgeItemWithStrategy方法,该方法先将strategy的表达式进行拼接找到对应的函数,然后将历史数据传递到Compute中进行逻辑判断,如果判断匹配则返回的值isTriggered为true,否则返回false.在judgeItemWithStrategy中会创建event事件,调用sendEventIfNeed方法判断该event是否应该发送出去。
// sendEventIfNeed方法中判断event是否该发告警的逻辑
if isTriggered {
event.Status = "PROBLEM"
if !exists || lastEvent.Status[0] == 'O' {
// 本次触发了阈值,之前又没报过警,得产生一个报警Event
event.CurrentStep = 1
// 但是有些用户把最大报警次数配置成了0,相当于屏蔽了,要检查一下
if maxStep == 0 {
return
}
sendEvent(event)
return
}
// 逻辑走到这里,说明之前Event是PROBLEM状态
if lastEvent.CurrentStep >= maxStep {
// 报警次数已经足够多,到达了最多报警次数了,不再报警
return
}
if historyData[len(historyData)-1].Timestamp <= lastEvent.EventTime {
// 产生过报警的点,就不能再使用来判断了,否则容易出现一分钟报一次的情况
// 只需要拿最后一个historyData来做判断即可,因为它的时间最老
return
}
if now-lastEvent.EventTime < g.Config().Alarm.MinInterval {
// 报警不能太频繁,两次报警之间至少要间隔MinInterval秒,否则就不能报警
return
}
event.CurrentStep = lastEvent.CurrentStep + 1
sendEvent(event)
} else {
// 如果LastEvent是Problem,报OK,否则啥都不做
if exists && lastEvent.Status[0] == 'P' {
event.Status = "OK"
event.CurrentStep = 1
sendEvent(event)
}
}
同步strategy和expressions方
main函数中起了go-routine 专门用来从hbs同步strategy和expressions,同步完之后重新组装成StrategyMap和ExpressionMap两个字典。
几个数据结构分析
- HistoryBigMap
- HistoryBigMap是个大字典,key是pk的hash值的前两位,一共有16*16=256个键,value是NewJudgeItemMap,也是一个字典,该字典的key是pk,value对应历史数据组成的链表,链表最大长度可在配置文件中的remain配置,默认是11,也就是默认对每个数据,保留11个历史数据节点。
- StrategyMap
- StrategyMap是个字典,key是hostname和Metric拼接的字符串,value是一个array,因为同一个hostname和Metric可能对应多个Strategy(可能tags不同,当然可能没有tags时,父子模板中都有该Strategy)
- ExpressionMap
- ExpressionMap是个字典,key是metric和tags拼接的字符串,value是一个array,metric和tags无法唯一确定expression。
- LastEvents
- LastEvents是个字典,key是event.Id,该id是由strategy.id和pk的hash值拼接产生的,可以唯一确定一个数据,所以value就是event事件本身。
3. 设计优缺点
优点:
- 支持告警间隔以及最大告警次数,太多的告警并没有什么帮助,况且会将真正有用的告警淹没在无意义的告警中。
- 支持Expression,zabbix是将告警和主机绑定起来,某些并不和某个主机关联的告警无法做,有了Expression之后就可以关联那一类告警了。
缺点:
- 只支持按照次数告警,如果支持按照时间告警就好了,比如某台机器连续五分钟cpu负载过高告警。
posted on 2017-10-29 10:48 bigdata_devops 阅读(367) 评论(0) 编辑 收藏 举报