对于很多流量、访问量、延时等场景,很对同学在绘制大盘时想能在指标中,体现出来异常值的位置,这就是需要在SLS的图表中支持同时在一个图表中绘制曲线并标记点。接下来,我们一步步操作下,如何绘制异常点。
先绘制带点的时序图
接下来,我们根据访问日志中的每分钟延时指标进行时序和异常指标的绘制,通过如下的SQL语句我们可以得到一条时序曲线。同时我们在下图中,绘制了一条直线,试图想标记出超过这条红线的点,并用红色的点来表示。这也就是我们常说的,大于某个特定的阈值我们标记为异常。
*and domain:"www.abb.mock-domain.com"|select __time__ - __time__ %60astime, avg(request_time)/1000.0as request_time_avg from log groupbytimeorderbytimelimit10000
很自然,我们可以通过在子查询中通过给定的一个阈值(不如,下面的参数 10 )来进行判断,超过10这个大小的我们就进行标注。
*and domain:"www.abb.mock-domain.com"|selecttime, request_time_avg, request_time_avg >10as flag from(select __time__ - __time__ %60astime, avg(request_time)/1000.0as request_time_avg from log groupbytimeorderbytime)limit10000
但是在上面的query的结果中,我们在表格中会多拿到一列指标flag,此列的含义是 >10 就是True,<=10 就是False,但是上面的结果无法在单个Y轴下去描述,因为对应的Y轴的值域是不同的,那么我们自然就会考虑到,是否可以将上面的结果改成,超过了10就表示为原始值,没超过10的就表示为0.0。我们沿着这个思路就可以得到如下的Query,通过子查询中的case when来区分出对应的 flag 维度表示的含义,具体如下:
*and domain:"www.abb.mock-domain.com"|selecttime, request_time_avg, case when request_time_avg >10 then request_time_avg else 0.0 end as flag from(select __time__ - __time__ %60astime, avg(request_time)/1000.0as request_time_avg from log groupbytimeorderbytime)limit10000
通过上面的各种配置,我们得到了上述一个多曲线图,虽然距离我们的结果已经很近了,但是美中不足的是,我们发现红色的点好多,哪些 0.0 的点是否可以不用显示出来。
之所以可以绘制出等于 0.0 的点,是因为我们提供了在Y轴上的0.0的点,我们是否可以通过 null 来替代 0.0 不去显示它,因此我们稍作 case when的改造,再试一下。
*and domain:"www.abb.mock-domain.com"|selecttime, request_time_avg, case when request_time_avg >10 then request_time_avg else null end as flag from(select __time__ - __time__ %60astime, avg(request_time)/1000.0as request_time_avg from log groupbytimeorderbytime)limit10000
在上图中,已经非常接近我们要的结果了,Y轴等于 0.0 的红色的点已经不见了,但是每个红色点却链接在了一起,变成了红色曲线,那一定是我们曲线的配置问题,我们再次进入 【字段配置】部分,重新修改下对应的【图形配置】,这就得到了下面这张图,就满足我们的需求了。
在仪表盘中提供自定义的阈值
经过上面的各种操作,我们终于拿到了一张可以绘制曲线+特定点的时序图了,接下来,我们如何来修改可以改变红点数量的阈值呢?那就要介绍到SLS仪表盘中的过滤器。
我们添加一个名字为【延时阈值】的变量替换,并且对应的Key值为:latency_threshold,同时我们在静态列表项中,我们在添加一些内置的参数值大小。
这时,我们修改下仪表盘中的时序图的Query语句,这里要前调一点,对应的变量替换的变量表示为如下
${{latency_threshold|10}}latency_threshold 为变量名称,10表示的是默认的取值
*and domain:"www.abb.mock-domain.com"|selecttime, request_time_avg, case when request_time_avg > ${{latency_threshold|10}} then request_time_avg else null end as flag from(select __time__ - __time__ %60astime, avg(request_time)/1000.0as request_time_avg from log groupbytimeorderbytime)limit10000
保存后,我们就在仪表盘中,得到了异常的内容,可以通过修改【延时阈值】来实现不同过滤器条件下的结果。
几种产生不同异常点的方法
在SLS平台中,产生异点的方式大致分为2种,一种是通过【SLS中的机器学习函数】,另外一种是通过【智能异常分析APP】来实现,
- 机器学习语法与函数 https://help.aliyun.com/document_detail/93023.html
- 智能异常分析 https://help.aliyun.com/document_detail/356466.html
上述两种方式的基本差异
- 机器学习函数:目前是无状态的,仅仅对于输入的数据进行处理,处理的精度等一般,且每个函数有较多参数需要学习
- 智能异常分析:底层是一个有状态的常驻Job,可以通过实时输入的数据进行建模,同时完成模型巡检和模型推断,配置相对简单直接
使用ts_predicate_arma产生不同的异常点
1. 直接使用算法产生异常点
*and domain:"www.abb.mock-domain.com"|select unixtime, src, predict, upper_val, lower_val, case when prob =0.0 then null else src end as prob from(select t1 [1]as unixtime, t1 [2]as src, t1 [3]as predict, t1 [4]as upper_val, t1 [5]as lower_val, t1 [6]as prob from(select ts_predicate_arma(time, request_time_avg,10,1,1)as res from(selecttime, request_time_avg from(select __time__ - __time__ %60astime, avg(request_time)/1000.0as request_time_avg from log groupbytimeorderbytime))), unnest(res)as t(t1))limit100000
2. 依托算法产生自定义的异常点
- 产生向上超出阈值的异常点
*and domain:"www.abb.mock-domain.com"|select unixtime, src, predict, upper_val, lower_val, case when prob >0.0and src > upper_val then src else null end as prob from(select t1 [1]as unixtime, t1 [2]as src, t1 [3]as predict, t1 [4]as upper_val, t1 [5]as lower_val, t1 [6]as prob from(select ts_predicate_arma(time, request_time_avg,10,1,1)as res from(selecttime, request_time_avg from(select __time__ - __time__ %60astime, avg(request_time)/1000.0as request_time_avg from log groupbytimeorderbytime))), unnest(res)as t(t1))limit100000
- 产生向下超出阈值的异常点
(*and domain:"www.abb.mock-domain.com")|select unixtime, src, predict, upper_val, lower_val, case when prob >0.0and src < lower_val then src else null end as prob from(select t1 [1]as unixtime, t1 [2]as src, t1 [3]as predict, t1 [4]as upper_val, t1 [5]as lower_val, t1 [6]as prob from(select ts_predicate_arma(time, request_time_avg,10,1,1)as res from(selecttime, request_time_avg from(select __time__ - __time__ %60astime, avg(request_time)/1000.0as request_time_avg from log groupbytimeorderbytime))), unnest(res)as t(t1))limit100000
使用智能巡检产生不同的异常点
- AIOps:自适应机器学习异常检测 https://developer.aliyun.com/article/784991
- 一分钟完成访问数据的智能巡检告警 https://developer.aliyun.com/article/785427
- 一分钟完成ECS机器数据的智能巡检告警 https://developer.aliyun.com/article/785745
- 智能巡检云监控指标的最佳实践 https://developer.aliyun.com/article/836132
- 智能巡检告警配置最佳实践 https://developer.aliyun.com/article/851142