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

简介: 本文主要介绍一种免运维,高性能,支持灵活配置的方案,使用SLS接入日志和告警。

1.前言


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


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


2.前提:将日志接入SLS


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

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

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


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


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

image.png

NEW

出查询分析属性口

test-java-log

数据加工

另存为告警

另存为快速宣询

查询/分析

1分钟

中(整点时间)

java.Lang.NuliPointerException

1.2

47分27秒

47分54秒

47分45秒

47分36秒

47分18秒

47分09秒

47分00秒

日志总条数:1查询状态:结果精确

日志聚类

原始日志

统计图表

每页显示:

100

业向

目原始

围表格

快速分析

换行

时间

Q

搜索字段

日13.0.913.54

108-1317:47:11

8/home/www/togs/serverap/app88068

@13.0.913.54

app-1og

:203.119.111.111

tag

clienTIp

您还没有指定字段宣询,赶紧

ConTent:java.tanguPoicei

深加吧(查看帮助)

atsec.SecTest.testsendrrorlog(Secest.

atsun.reflect.Nativeethocceik)

atsun.rtect.tivehee

tsun.retect.ethcec

atjava.tang.eflect.Method.ih

torg.um.m.h

atorg.unit.nte

t0mgmt.rmes..

stgot.met..

tmet.hcotom.

atorgunt.m

atorg.junt.tnte.k

atorgjuntu

atorg.u.

atorg.um.

atorg.junt.ues.parenuntuea:2

atorg.junt.uns.ParetRunrs.chru

atorg.junt.unes.Parntunr.unchu

atorgjunit.runes.PaetRunrcceu

atorgunit.runnsauz

atorg.junit.urs.Parentuneru(aeuejaa300)

atorg.junit.runneJunitcore(untcj

tcomintet

tcomintt.

tcom.inteutt.

atcominteututu

收起

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

image.png

告警监控规则

规则名称:

发生NPE错误

7/64

固定间隔

检宜频率:

分钟

查询统计:

添加

java.Lang.nuliPointerException

1分钟(整点时间)

不分组

分组评估:

有数据

触发条件:

严重度:

当:

添加

添加标签:

?添加

S(aLerTnAme)告警触发

标颖(title)

添加标注:

S(CONTENT

描述(desc)

添加

自动添加标注:

恢复通知:

高级配置

普通模式

高级式

极简模式

告警策略:

行动组

钉钉-自定义

渠道

钉钉-自定义

请求地址

https://oapi.dingtalk.com/rob

提程方式

不提置

sLs内置内容模板

新增查看

内容棱板

任意

发送时段

自动分派?

添加通知渠道

重复等待:

分钟

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

image.png

告警测试

机器人

19:11

SLS告警

阿里云账号:1

告警规则名称:发生NPE错误

告警严重度:中级

告警标题:发生NPE错误告警触发

告警内容:java.lang.NuPointerExcetiont

sec.SecTest.testsendErrorlog(SecTestjaa:7)

sun.reflect.NativeMethodccessorimlioati

veMethod)at

sun.reflect.NativeMethodAccessoriml.inoke(ti

eMethodAccessorlmpl.java:62)at

sun.reflect.DelegatingMethodccesoimlie

DelegatingMethodAccessorlmpljava:43)at

java.lang.reflect.Method.inokMh.ja:

org.junit.runnersmodel.FramworMethode

lectivecall(FrameworkMethod.java:45)at

org.junit.internal.runrsmodeReflctiveCallabler

un(ReflectiveCallable.java:15)at

org.junitrunnersmodel.FrameworkMhodiEx

plosively(FrameworkMethod.java:42)at

mockit.integration.junit4.tl.JUitTu

Decorator.executeTestMethod(JUnit4TeRunDe

corator.java:138)at

mockit.integration.junit4.internal.JUnitTn

Decorator.inyokeExplosivelyJUnit4TetRunneDeco

ratorjava:79)at

org.junit.runnesmodel.FamworMthokeEx

plosively(FrameworkMethod.java)

org.junit.internal.runners.staement.okeMethod

evaluate(lnvo

告警首次触发时间:2021-08-1319:11:47

此次评估的触发时间:2021-08-1319:11:47

清体

触发告警的实例ID:34196cd86434f831-

5c96eead5f6d1-29ccaef

告磐规则所在project:demo-alert-chengdu

告警状态:触发

[详情][设置]

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

image.png

NEW

!查询分析属性,

数据加工

另存为快速查询

另存为告警

test-java-log

查询/分析

2021-081319:10:00~2021-08-1319:11:00

java.lang.NuliPointerExcetion

1.2

10分27秒

10分36秒

10分54秒

10分45秒

10分09秒

10分18秒

10分00秒

日志总条数:1询状态:结果精磷

统计图表

日志聚类

原始日志

业向

快速分析

围表格

换行

原始

时间

搜案字段

日13.0.913.54

a/home/www/logs/server-api/app.log

08-1319:10:47

1628853085

@13.0.913.54

app_Log

203.119.111.111

client_Ip

tag:

tag_:cllentip_

content:jav

T:javaLangNulPointerException

tag:hostname

sec.SecTest.testendErrorLog(scestj7

atSec.

atsun.refLect.NtiveethodccessopkMh)

tag

path

tsun.relect.tvehcece

atsun.rettect.gtinethccee

content

atjava.tang.lect.Mthk

toR.um.rme.

torg.unttnteaL

t0Rmmt.me.

atoo

boewt.tto

at

ot.mtretm

torumm

atorg.junit.intenat.ruI


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


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

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

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

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

image.png

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

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

image.png

告警监控规则

规则名称:

9/64

NPE发生次数过多

检宣频率:

固定间隔

分钟

15

查询统计:

添加

javaangcioc

不分组

分组评估:

15分钟(相对)

O

严重度:

cnt>5

触发条件:0当:

有数据匹配

添加

添加标签:?添加

sLalertname)告警能发

添加标注:

标题(title)

15分钟内共发生S(Cnt)次NPE错误

添加

描述(desc)

自动添加标注:

恢复通知:

高级配置

极简模式

音通模式

高级模式

告警算略:

行动组

钉钉-自定义?

渠道

钉钉-自定义

https://oapi.dingtalk.com/robi

请求地址

不提醒

提程方式

sLs内置内容模板

内容模板

C新增查看

任意

发送时段?

自动分派

+添加通知渠道

分钟

重复等待:

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

image.png

告警测试

机器人

19:36

SLS告警

阿里云账号:1.

050

告警规则名称:NPE发生次数过多

告警严重度:中级

告标题:NPE发生次数过多告警触发

告警内容:15分钟内共发生8次NPE错误

告警首次触发时间:2021-08-1319:35:49

此次评估的触发时间:2021-08-1319:35:49

触发告警的实例ID:44aao3da59769ebc-

596f40c969de-2624751

告警规则所在Project:#

SJle-log

告警状态:触发

[详情][设置]


5.方法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%;

image.png

NEW

出查询分析属性

数据加工口

error号

另存为告警

另存为快速查询

查询/分析

15分钟(相对)

java.Lang.NulPoiterExcetion

SOYs

44分45秒

54分42秒

42分15秒

47分15秒

49分45秒

52分15秒

39分57秒

扫重舒的置18自

统计图表

原始日志

日志聚类

123

一g88

下载日志

添加到仪表盘

收起配置

交互行为

属性配置

数据源

预览图表

行列变换

每页条数

today

yesterday

ratio

Q

20

40.0

21.21

33

隐藏所有保留字段

隐藏字段

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

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

标注中的描述为

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

image.png

通知结果如下,供参考。

image.png


6.方法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表示有异常。

image.png

image.png

数据预览

lower

anomaly-prob

unixtime

src

upper

predict

3.5999999512576834

1628843280.0

2.3073970593250445

5.064968050512865

0.0

4.0

1628843310.0

2.3073971179662156

0.0

2.0

5.064968109154037

3.6000000098988549

3.200000037243893

0.0

1.907397145311254

4.664968136499075

1628843340.0

4.0

1.9797168231435645

3.2723197150762037

1628843370.0

4.737287814331386

4.0

0.0

1.9176504472220646

3.2102533391547038

4.675221438409886

2.0

1628843400.0

0.0

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

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

image.png

通知结果如下:

image.png

告警测试

机器人

SLS告警

阿里云账号:

050

告警规则名称:NPE错误数异常

告警严重度:中级

告警标题:NPE错误数异常告警触发

告警内容:过去4小时内NPE错误数出现异常点超过

5个

告警首次触发时间:2021-08-1320:42:28

此次评估的触发时间:2021-08-1320:42:28

触发告的实例ID:c8161aef94boca2a

5c9702f2497a0-1acef2b

告警规则所在Project:

e-log

告警状态:触发

[详情][设置]


7.总结


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


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


8.参考


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


9.进一步参考



作者介绍
目录

相关产品

  • 日志服务