告警中的持续时长无效

Viewed 63

我配置了一个告警规则,执行频率是60s,持续时长是600s,我这边收到的告警显示有持续时长0s,也有11,12,13,14m 不知道为啥未生效,看描述这个持续时长意思是连续查询10次才会告警,为啥持续时长为0就告警了

1 Answers

结论是虽然你设置的持续时长是600s,不过还有个重要的配置-‘重复通知间隔(分钟)’,这里描述的问题我认为是和它有关。
再详细解释一下:
‘告警显示有持续时长0s’,这一部分描述中我和碰到的情况不太一样,你可以给出更多描述或者证据。
‘也有11,12,13,14m 不知道为啥未生效,看描述这个持续时长意思是连续查询10次才会告警’,这一部分我目前的判断是因为‘重复通知间隔’配置的问题,不过在不调整配置的情况下,告警恢复再次触发的两次告警会满足你的预期。

本来以为挺了解告警这部分内容,看到这个问题,细想了下,不是很理解具体怎么处理的,又看了下表结构和源码,也记录一下重要的部分。
下面是process.go中handleEvent函数的片段,这是判断是否要生成告警事件的必要判断步骤之一,用到了执行频率(PromEvalInterval)和持续时长(PromForDuration)两个配置,这里可以看到生成告警事件需要满足上面连续告警的要求,不是通过判断n次满足发送告警,再重置计数器达到n再发送的方式。

...
                var preTriggerTime int64//首次触发事件
		preEvent, has := p.pendings.Get(event.Hash)//活跃告警map(AlertCurEventMap)中查到上次事件记录,其中hash是‘规则id+异常点标签+数据源id+异常等级’ 的md5值,process.go  Hash
		if has {
			p.pendings.UpdateLastEvalTime(event.Hash, event.LastEvalTime)//更新活跃告警map的‘最近一次计算时间’为这次事件的计算时间
			preTriggerTime = preEvent.TriggerTime//设置首次触发时间为活跃告警map对象中事件的首次触发时间
		} else {
			p.pendings.Set(event.Hash, event)
			preTriggerTime = event.TriggerTime//设置首次触发时间为本次事件的触发时间
		}
//***当前触发异常点的时间(同上次触发时间) - 首次异常点触发时间 + 执行频率 >= 持续时长 ***
		if event.LastEvalTime-preTriggerTime+int64(event.PromEvalInterval) >= int64(p.rule.PromForDuration) {
			fireEvents = append(fireEvents, event)
			if severity > event.Severity {
				severity = event.Severity
			}
			continue
		}
....

其次在看下fireEvent函数,经过上面函数判断后,这里用到重复通知间隔的配置(NotifyRepeatStep),告警事件是否继续发送的判断是这样:本次触发时间〉上次发送告警时间+通知间隔 ,所以我总结下来应该是符合这样的规律

间隔(分钟) 频率(分钟) 触发(分钟)
2 0.5 2.5
2 1 3
2 2 4
2 3 3
...
               if cachedRule.NotifyRepeatStep == 0 {
			logger.Debugf("rule_eval:%s event:%+v repeat is zero nothing to do", p.Key(), event)
			// 说明不想重复通知,那就直接返回了,nothing to do
			// do not need to send alert again
			return
		}

		// 之前发送过告警了,这次是否要继续发送,要看是否过了通道静默时间
		if event.LastEvalTime > fired.LastSentTime+int64(cachedRule.NotifyRepeatStep)*60 {
			if cachedRule.NotifyMaxNumber == 0 {
...