Graphite数据源下,如何对比当前1小时数据与上周同期均值并告警?
Graphite 基于历史时段基准的异常检测查询写法
核心逻辑
针对应用流量的日周期规律,通过对比当前1小时数据与过去1-2周同一时段的平均值,当差值超过3倍标准差时标记异常。以下是具体的查询语句及说明:
1. 正常请求(非4xx/5xx)的异常检测
全路由聚合检测
如果需要将所有路由的正常请求数合并后做整体异常检测,使用以下查询:
above( abs( subtract( sumSeries(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), averageSeries( timeShift(sumSeries(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-7d"), timeShift(sumSeries(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-14d") ) ) ), multiply( 3, stdevSeries( timeShift(sumSeries(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-7d"), timeShift(sumSeries(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-14d") ) ) )
单路由独立检测
如果需要对每个路由别名单独做异常检测,去掉sumSeries即可:
above( abs( subtract( exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}"), averageSeries( timeShift(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-7d"), timeShift(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-14d") ) ) ), multiply( 3, stdevSeries( timeShift(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-7d"), timeShift(exclude(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-14d") ) ) )
2. 错误请求(4xx/5xx)的异常检测
逻辑与正常请求一致,仅需将exclude替换为match来筛选错误响应码:
above( abs( subtract( sumSeries(match(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), averageSeries( timeShift(sumSeries(match(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-7d"), timeShift(sumSeries(match(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-14d") ) ) ), multiply( 3, stdevSeries( timeShift(sumSeries(match(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-7d"), timeShift(sumSeries(match(my_app.prod.count.api.*.*, ".*[45][0-9]{2}")), "-14d") ) ) )
关键函数说明
exclude(series, pattern):排除匹配指定正则的指标,这里用于过滤4xx/5xx错误请求match(series, pattern):筛选匹配指定正则的指标,用于定位错误请求sumSeries(series):将多个序列的数值求和,实现路由维度的聚合timeShift(series, offset):将序列的时间窗口偏移指定时长,获取过去同一时段的历史数据averageSeries(series1, series2):计算多个序列的平均值,作为历史基准值stdevSeries(series1, series2):计算多个序列的标准差,用于确定异常波动阈值subtract(a, b):计算当前数据与历史均值的差值abs(value):取差值的绝对值,忽略正负方向multiply(factor, value):计算3倍标准差的阈值above(value, threshold):判断数值是否超过阈值,返回1(异常)或0(正常)
内容的提问来源于stack exchange,提问作者Eduard Sukharev
相关产品推荐
相关产品推荐

