很久很久以前,大家都在问 Tdengine 支不支持事件报警,后来,估计是被否定的答案伤透了心,就渐渐没人问了:(。但实际上,报警用途真的非常广泛,比如:一家运输公司要监测车辆的速度,希望车辆最近五分钟的平均速度超过100km/h时,能及时提醒驾驶员。那么,这家公司可能会在 TDengine 中用下面的语句创建表结构:

    1. create database if not exists test;
    2. use test;
    3. create table cars (ts timestamp, speed float) tags(id int);
    4. create table car0 using cars tags(0);
    5. create table car1 using cars tags(1);
    6. create table car2 using cars tags(2);
    7. ...

然后,自己开发应用程序并使用下面的 sql 语句检测超速的车辆,再一一通知相关人员:

    1. select avg(speed) as avgSpeed from test.cars where ts > now - 5m group by id;

这样做确实可以满足需求,但为这么简单的一个场景开发应用程序,未免有点“杀鸡有牛刀”;而且,如果规则很多,每一条都定制开发,成本也不低。

而事件报警就是为应对这类场景而生的,所以,这个功能刚刚开发完毕,我迫不及待的写出了这篇博客和大家分享。

安装

在 TDengine 的技术架构中,事件报警以单独模块的形式提供,这个模块和TDengine结合在一起,共同实现了报警功能。另外,考虑到Prometheus的AlertManager在报警管理方面很成熟,拥有庞大的用户群,报警模块目前将生成的报警信息都直接推送给了AlertManager,后续的管理工作,由用户在AlertManager上完成。

安装报警模块有两种方式:下载预编译的安装包或者从源码编译安装。

使用编译好的二进制文件

您可以从 涛思数据 官网下载最新的安装包。下载完成后,使用下面的命令解压即可:

    1. $ tar -xzf tdengine-alert-$version-$OS-$ARCH.tar.gz

如果您之前没有安装过 TDengine 的客户端或服务端,您还需要执行下面的命令安装一下 TDengine 的动态库:

    1. $ ./install_driver.sh

从源码安装

从源码安装需要在您用于编译的计算机上提前安装好 TDEngine 的服务端或客户端,如果您还没有安装,可以参考 TDEngine 的文档。报警模块使用 Go语言 开发,所以,编译之前,您还需要安装最新版的 Go 语言编译环境(目前是 v1.14)。这两项都准备好后,就可以用下面的命令编译了:

    1. $ mkdir taosdata
    2. $ cd taosdata
    3. $ git clone https://github.com/taosdata/tdengine.git
    4. $ cd tdengine/alert/cmd/alert
    5. $ go build

由于墙的原因,最后一步可能会因为部分依赖包无法下载而失败,这时,您可以根据 goproxy.io 上的说明配置好 GOPROXY 再重新执行 go build

配置

为了让产品更好用,涛思数据一直都以“开箱即用”为目标,但具体到报警模块,因为需要 TDengineAlertManager 的连接信息(这两项需分别单独安装),所以在运行它之前,需要您手工进行一些配置。

在安装后的文件夹中,有一个名为 alert.cfg 的文件,它采用的是标准 json 格式,以下是其默认内容:

    1. {
    2. "port": 8100,
    3. "database": "file:alert.db",
    4. "tdengine": "root:taosdata@/tcp(127.0.0.1:0)/",
    5. "log": {
    6. "level": "production",
    7. "path": "alert.log"
    8. },
    9. "receivers": {
    10. "alertManager": "http://127.0.0.1:9093/api/v1/alerts"
    11. }
    12. }

您可以用喜欢的文本编辑器打开它并修改其中的选项,这些选项的含义如下:

  • port:报警模块支持使用 restful API 对规则进行管理,这个参数用于配置 http 服务的侦听端口。
  • database:报警模块将规则保存到了一个 sqlite 数据库中,这个参数用于指定数据库文件的路径(不需要提前创建这个文件,如果它不存在,程序会自动创建它)。
  • tdengineTDEngine 的连接信息,一般来说,数据库信息应该在报警规则中指定,所以这里 应包含这一部分信息。
  • log > level:日志的记录级别,可选 productiondebug
  • log > path:日志文件的路径。
  • receivers > alertManager:报警模块会将报警推送到 AlertManager,在这里指定 AlertManager 的接收地址。

准备好配置文件后,可使用下面的命令启动报警模块:

    1. $ ./alert -cfg alert.cfg

编写报警规则

报警模块安装配置好后,就可以给它添加报警规则了。不过,开始前,为了便于大家更好的理解一条报警规则中要包含那些东西,我们要先来看看报警是什么:

从技术的角度,报警是指从最近一段时间的数据中筛选出符合一定条件的数据,并基于这些数据根据定义好的计算方法得出一个结果,当结果符合某个条件且持续一定时间后,触发警告并以某种形式通知用户。

仍以本文开头的监测车辆速度的场景为例,下面就是其对应的报警规则(json格式):

    1. {
    2. "name": "CarTooFast",
    3. "sql": "select avg(speed) as avgSpeed from test.cars where ts > now - 5m group by id",
    4. "expr": "avgSpeed > 100",
    5. "period": "10s",
    6. "for": "0s",
    7. "labels": {
    8. "ruleName": "CarTooFast"
    9. },
    10. "annotations": {
    11. "summary": "car {{$values.id}} is too fast, its average speed is {{$values.avgSpeed}}km/h"
    12. }
    13. }

其中字段含义如下:

  • name:用于为规则指定一个唯一的名字。
  • sql:从 TDEngine 中查询数据时使用的 sql 语句,查询结果中的列将被后续计算使用,所以,如果使用了聚合函数,请为这一列指定一个别名。您可能已经注意到,本例中,这条语句和本文开头的那条完全相同。
  • expr:一个计算结果为布尔型的表达式,支持算数运算、逻辑运算,并且内置了部分函数,也可以引用查询结果中的列。 当表达式计算结果为 true 时,进入报警状态。
  • period:规则的检查周期,默认1分钟,而在我们的例子中,是每10秒检查一次有没有车辆超速。
  • for: 一个时间长度,当布尔表达式的计算结果为 true 的持续时间超过这个选项时,才会触发报警。默认为0,表示只要计算结果为 true,就触发报警。
  • labels:人为指定的标签列表,标签可以在生成报警信息时引用。特别的,如果 sql 中包含 group by 子句,则所有用于分组的字段会被自动加入这个标签列表中,在本例中,车辆的 id 会被自动加入标签列表。
  • annotations:用于定义报警信息,使用 go template 语法,其中,可以通过 $labels.<label name> 引用标签,也可以通过 $values.<column name> 引用查询结果中的列。

我们将上面的规则保存在文件 rule.json 中,然后,可以用下面的命令将规则加入报警模块:

    1. $ curl -d '@rule.json' http://localhost:8100/api/update-rule

现在,我们尝试在TDengine中增加几条0号车的数据:

    1. insert into car0 values(now - 4m, 90) (now - 3m, 110) (now - 2m, 120) (now - 1m, 120) (now, 100);

稍等片刻,如果一切正常,您就可以从AlertManager中看到相应报警信息了。您可以再添加一些其他车辆的数据并观察报警信息的变化。

报警监测(Alarm monitoring/) - 图1

其他

上面简单的介绍了报警模块的使用方法,更详细的信息您可以参考这个模块的文档

另外,客观的说,报警模块目前提供的功能还不是很多,所以使用时需要结合AlertManager。但不必担心,报警管理、路由、邮件推送、微信推送、钉钉推送等功能都已经在我们的计划列表里了,如果您有任何意见和建议,也欢迎向我们反馈。