用SLS配置日志关键字告警的N种方法

前言

在业务日志中,经常会有些warning,error的日志打出来,出现比较严重的问题时在日志中也会发现异常,比如在Go中的panic错误,Java的java.lang.*Error日志等等;或者是在程序运行到某种状态时,业务会自动在日志中打印某个关键词,比如“支付失败”等,根据关键词来判断业务运行的情况。


日志关键词的检索和监控告警是一个比较常见的需求,也有很多方法来实现关键词告警,对于简单的告警,一般方案也比较简单,比如从最原始的写shell脚本来判断日志中的关键词然后发送邮件,或者使用zabbix传统监控工具等,或者使用ELK等方案。这些监控工具虽然可以实现需求,但是在面对分布式部署的业务,海量日志的情况下存在运维问题,配置复杂,性能低下等问题;这里介绍一种免运维,高性能,支持灵活配置的方案,使用SLS接入日志和告警。


前提:将日志接入SLS

首先需要将业务日志接入SLS,可以根据自身的业务来选择不同的接入方式,SLS也提供支持非常便捷的接入方式,限于篇幅,本文不在赘述接入方法。具体接入方法可以参考【链接】。

在日志接入后,我们就可以在SLS控制台查询关键词,并且配置告警。

以下来介绍在SLS中配置关键词告警的几种常见方法。

方法1:出现关键词就告警

这里以Java日志为例,在日志中,我们注意到有NPE发生,这时候可以在SLS控制台搜索java.lang.NullPointerException,然后点击查询/分析,这时候可以看到日志中有NPE发生。

用SLS配置日志关键字告警的N种方法

查询出错误后,我们可以对这个错误进行告警配置,点击右上角的“另存为告警”按钮,在弹出框里编辑告警,将描述修改为${content},表示满足触发条件的第一条数据,然后配置钉钉通知渠道,选择默认SLS内置内容模板,点击确定。

用SLS配置日志关键字告警的N种方法

如果日志中有java.lang.NullPointerException出现,则会在钉钉中发出告警,内容如下。显示是使用的SLS内置内容模板的格式,其中告警标题引用了${annotations.title}告警内容引用${annotations.desc},内容模板的详细配置可以参考【链接】。

用SLS配置日志关键字告警的N种方法

在通知中,可以点击详情,查看告警发生时的日志,进行追溯。详情点击后页面如下

用SLS配置日志关键字告警的N种方法

方法2:根据关键词出现次数告警

有时候出现错误关键词时,我们并不一定要发出告警,在一定时间内,出现到了特定次数,才发出告警;比如5分钟出现了1次错误我们并不是很关心,但是出现了100次错误,就需要引起我们的注意。使用关键词出现次数判断一定程度上起到了降噪的效果。

接下来我们我们对关键词的出现次数进行一次告警配置。

仍然以java.lang.NullPointerException关键词为例,通过查询可以看出15分钟内,出现了关键词次数为10,语句使用了SLS的 查询 | 分析 语法,其中分析语句为标准的SQL 92语法,这里可以省略FROM子句,也可以加上 FROM log,表示从当前logstore查询。其中查询分析结果中的cnt表示关键词出现的次数总和。

java.lang.NullPointerException | SELECT COUNT(*) as cnt

用SLS配置日志关键字告警的N种方法

接下来可以对关键词出现的次数总和进行告警判断,如果15分钟内出现5次以上NPE错误,就发出告警。

注意,这里触发条件选择有数据匹配,内容填写cnt > 5

用SLS配置日志关键字告警的N种方法

通知效果参考如下:我们仍然可以通过点击详情查看告警发生时的情况。

用SLS配置日志关键字告警的N种方法

方法3:关键词出现次数环比昨日告警

仅仅用关键词的出现次数来告警,在某些场景下可能还不是很准确,可能有的人说,我每天的错误数跟用户访问PV成正比,白天用户访问PV高,错误关键词出现次数就高,晚上用户访问PV降下来,错误关键词次数就降下来了,这种情况下使用关键词出现次数的绝对值来判断可能就不准确了。

也就是说关键词的出现有一定的周期性,并且这个周期是以天为单位。在一天中的同一时刻可能变化不大,在同一天的不同时刻变化比较大。这种情况可以使用SLS告警吗?答案是肯定的。

SLS提供了同环比函数,可以用来计算不同时间周期内的结果对比,比如可以计算当前15分钟与昨天同时刻15分钟的对比。

compare(x,n)

对比当前时间周期内的计算结果与n秒之前时间周期内的计算结果。返回值为:

JSON数组。格式为[当前计算结果,N秒前的计算结果,当前计算结果与N秒前计算结果的比值,N秒前的UNIX时间戳]。


接下来通过一个简单的例子来理解下这个函数。

查询语句如下,其中最内层查询先查出了当前的错误次数cnt,然后在使用compare函数,参数86400表示一天的秒数,compare函数的结果是一个数组,使用diff[1],diff[2], diff[3]分别获取每个元素的值,注意第一个元素下标是1。

第一个元素是当前15分钟(假设为18:00:00~18:15:00)的错误次数;

第二个元素是昨天(也就是86400秒前)的15分钟(18:00:00~18:15:00)的错误次数;

第三个元素是当前15分钟错误次数与昨天15分钟错误次数的比值,这里使用diff[3]-1可以表示增长率,可能为负数,表示负增长率。

java.lang.NullPointerException |
SELECT
  diff [1] as today,
  diff [2] as yesterday,
  round((diff [3]-1) * 100, 2) as ratio
FROM  (
    SELECT
      compare(cnt, 86400) as diff
    FROM      (
        SELECT
          COUNT(*) as cnt
        FROM          log
      )
  )

查询结果如下:可以看到最近15分钟错误数40个,昨天同期为33个,增长了21.21%;

用SLS配置日志关键字告警的N种方法

基于以上的查询,我们可以对增长率进行一个告警监控,比如增长超过10%就触发告警。配置告警如下。

注意这里的ratio已经是百分比后的值,条件写ratio > 10,表示超过10%;如果需要对负增长率进行判断,可以使用ratio < (-10),这里负号需要用括号括起来。

标注中的描述为

15分钟内错误数为:${today}, 昨日同期为:${yesterday}, 陡增${ratio}%

用SLS配置日志关键字告警的N种方法

通知结果如下,供参考。

用SLS配置日志关键字告警的N种方法

方法4:使用机器学习算法进行异常点检测告警

通过昨日环比的告警,我们已经很大程度上可以对关键词告警进行更全方位的监控告警了,但是还有一些情况,比如某个关键词错误数在全天可能都比较平滑,上升和下降都比较平滑,没有陡增陡降的情况,但是如果出现了陡增陡降需要得到通知。

也就是说,我们可以把错误数当成一条曲线,如果出现陡增陡降就要告警,这种情况下,我们可以借助SLS强大的机器学习算法,SLS内置了功能丰富的机器学习算法,并且以函数的形式暴露,可以直接在SLS分析语法中使用;

这里我们选取一个预测与异常点检测函数:ts_predicate_simple,来对关键词错误数进行监控。函数定义如下,具体可以参考【链接】。

select ts_predicate_simple(x, y, nPred, isSmooth) 

这里我们将这个算法函数用在查询分析语句中,查询分析语句如下:

java.lang.NullPointerException |
select
  ts_predicate_simple(stamp, value, 6)
FROM  (
    select
      __time__-__time__ % 30 as stamp,
      count(1) as value
    FROM      log
    GROUP BY
      stamp
    order by
      stamp
  )

查询区间选择了4小时,统计图表选择时序图展示,点击查询分析,结果展示如下,在结果的图中,红色小圆圈表示异常点,这里点表示的30秒内java.lang.NullPointerException的次数;

函数返回值包括src, predict, upper, lower, anomaly_prob等;其中anomaly_prob表示异常点的概率,这里我们认为大于0表示有异常。

用SLS配置日志关键字告警的N种方法

用SLS配置日志关键字告警的N种方法

因此,我们可以对anomaly_prob的在一段时间内出现的次数进行监控,比如4小时内出现超过5个异常点,我们就会发出告警。这时另存为告警。告警配置如下:

这里我们触发条件选择有特定条数据匹配,并且选择 > 5条,条件是anomaly_prob > 0,因为上述查询分析语句中返回结果也有anomaly_prob = 0的行,这里我们要筛选的是anomaly_prob > 0的行数要超过5行才报警。

用SLS配置日志关键字告警的N种方法

通知结果如下:

用SLS配置日志关键字告警的N种方法


总结

本文由日志关键词告警出发,介绍了使用SLS进行关键词监控告警配置,并且介绍了几种常见的配置方法,可以覆盖关键词监控的大部分场景,其中前两种告警配置比较常见,使用场景也更加广泛,日环比和异常点检测的告警适合更加精细的监控告警需求。


本文虽然以关键词监控告警来介绍SLS告警,其实关键词只是使用SLS全文索引进行查询分析的一种场景。在SLS中还可以创建字段索引,比如对Nginx访问日志可以创建字段索引,如果需要查询5xx错误的次数或者同环比或者异常点,只需要将文中java.lang.NullPointerException换成status >= 500即可。对于OSS访问日志,SLB访问日志同理。


参考

  • 什么是日志服务【链接
  • 日志服务数据采集概述【链接
  • 查询和分析日志【链接
  • 什么是日志服务告警【链接
  • SLS告警-学习路径【链接
  • SLS同环比函数【链接
  • SLS机器学习语法与函数【链接
  • 通知内容定制【链接

进一步参考

用SLS配置日志关键字告警的N种方法


上一篇:Day04-使用PolarDB和ECS搭建门户网站


下一篇:阿里云ECS上搭建个人Leanote云笔记本