统一告警平台
一、概要
由于监控业务发展的较快,各种告警很多,并且告警记录不能查询,则需要一个平台来解决告警展示、查询等问题,「统一告警平台」应运而生。以下简称AMC(Alert Messages Center)。
AMC提供接口调用和前台配置,支持Rtx、短信、微信、邮件四种告警通道,支持模块信息自动补全、告警收敛、历史记录查询/展示等功能,告警接收人和告警机器可关联CMDB获取相关信息,也可独立配置,同时支持临时屏蔽功能。
二、接入说明
1、登记项目
若某项目需要发送告警,则可以考虑接入AMC。
该项目的开发同学,先在AMC前端页面登记项目信息,然后在自己项目代码里调用告警接口,发送告警即可。
登记项目信息需提供:
- 项目名称,必须字段:包含 a)全局唯一的英文字段,b)拉风的中文名称
- 项目申请人,只是登记一下,不做其他用途
- 选择一个三级业务信息,必须字段
- 告警开关,基于本项目的告警开关,可在故障时控制本项目的告警消息是否发送出来
- 告警接收人,支持发送业务树负责人/机器负责人/自定义/接口指定
- 告警收敛周期,默认为 60 秒,在一个周期内,重复告警则以第一条为准,其他会被过滤,可在接口设置不收敛/过滤。
- 告警收敛规则
- 告警方式:rtx,sms,wechat,e-mail,至少选一种
登记后会获得一个全局唯一的项目key,appKey,作为告警接口的一个必需参数
2、告警类型
一个项目中一般会有多种不算类型的告警(不同的异常情况),本模块采用「首次告警登记」的方式,即不用特意先登记有哪几种异常。
在某个项目的开发过程中,当遇到一种的异常情况,为这种异常指定一个(本项目内)唯一的字符串,称为「告警类型」,因此有全局唯一的字段:appKey + 告警类型。
但,一个项目逻辑很简单(比如一个脚本),不需区分异常类型,或是项目刚刚启动,暂时只有一种异常,则发送告警时不需指定「告警类型」,本模块使用 default 作为默认值。
以下简称「告警类型」,一种告警类型中默认包含有「项目」key,即全局唯一的「告警类型」。
比如「基础监控」中的 cpu、内存,都是该系统下的一种告警类型。
3、机器维度
每条告警消息,也应有一个的机器信息,基于机器信息,我们可以做:
- 该机器在 CMDB 中是否打开了告警。这是一个总开关,优先级最高
- 使用该机器在 CMDB 的业务信息,可以确定该机器是线上机器、或是非线上机器,不同的机器角色,有不同的收敛规则
三、告警接口设计
1、redis 队列
包含两种队列:
- 待处理队列,暂定8个队列, in_list_{01} ... in_list_{08},由「告警接口」按 「告警类型 」做一致性 hash 写入,再由后端进程进行处理
- 已处理队列,暂定一个队列,his_msg_list,后端进程处理后写入该队列,再由 logstash 每分钟取出,写入 elasticsearch
2、任务数据
「告警接口」写入的数据,为「任务数据」。
任务数据需要序列化:使用 msgpack api 把任务信息序列化成二进制,再把二进制写入redis。
序列化的各字段顺序(php、伪代码):
msgpack_pack( array( 'appKey' => $app_key, // 字符串 'content' => $content, // 字符串 'alarmType' => $alarm_type, // 字符串 'isFadeOut' => $is_fadeout, // 数值 1、0 'timestamp' => $timestamp, // 时间戳 'alarmIp' => $uip, //无符号整形ip,告警的机器 ip 'remoteIp' => $remoteIp, // 无符号整形ip,调用接口的对端 ip 'otherUser' => $other_users, // 用户id列表,多个id使用英文分号分隔 ) );
3、消息数据
后端程序处理一个任务,生产一个「消息数据」
格式为 json,为了让 logstash 直接写入 elasticsearch
一条数据包含如下字段,各字段含义请见以下 mysql create table 语句中的注释:
app_id,数值,项目 id app_key,字符串,项目key app_name, 字符串,项目标识(英文名) alarm_id,数值,告警类型 id alarm_type,字符串,告警类型 ip(点分表示法),字符串,ip content,字符串,告警内容 occur_time,字符串,YYYY-MM-DD hh:mm:ss,故障时间戳 result_code,数值,处理结果状态码 result,字符串,处理结果说明 send_time,字符串,YYYY-MM-DD hh:mm:ss, 消息发送的时间戳 send_by,字符串,消息发送的渠道 send_to,字符串,消息发送给了谁
四、告警后台设计
1、生产者
根据 redis 队列配置线程数量,每个线程操作一个 redis 队列加上「告警类型」的一致性 hash 可保证内存中的二级以下数据不用加锁,极大优化程序处理速度。
定时从 CMDB 获取最新 ip/业务树/机房等信息,定时从 AMC 数据库中 load 配置信息,降低数据库压力并且通过队列传递减少阻塞。
根据内存数据来解析判断是否需要告警,需要则推送给「消费者」
定时恢复告警记录的「异常/正常」状态
2、消费者
多线程操作,实时从「生产者」获取告警消息推送给用户,并写进数据库和 redis,提供 logstash 调用
五、临时屏蔽设计
1、增加临时屏蔽
根据不同需求提供一定时间的屏蔽告警功能,屏蔽时间开始即生效关闭告警,屏蔽时间结束则继续开启告警。每次屏蔽均会生成一条屏蔽记录,每条屏蔽记录均记录下操作人和屏蔽原因,方便审计 NOTE: 临时屏蔽功能上线期间会同时将永久关闭告警功能,对某条记录的屏蔽最长是10天,因为amc的告警一般是rtx/mail持续7天,其他的持续1天,则屏蔽10天足够。对CMDB的告警开关是否去掉需要调查一番。
WARNING: 屏蔽开始时间必须大于等于当前时间的下一分钟,结束时间至少在开始时间1分钟后,不能大于开始时间10天
IMPORTANT: 由于AMC对开关的获取是每分钟才获取一次,并不是实时获取开关,则屏蔽开始/结束时间是会提前1分钟将开关关闭/开启,这样能尽量保证开关在AMC中是接近准确值的
2、屏蔽类型
- amc有三级指标,项目->类型->ip,则提供 按项目屏蔽
- 按项目下的类型屏蔽
- 按项目下的类型下的ip屏蔽
- amc是结合机器进行告警的,则提供
- 按机器IP屏蔽,则屏蔽该ip,不会对应ip1-ip5
- 按业务树屏蔽该业务下所有的机器(可区分线上机/测试机,使用中/非使用中),包括ip1~ip5
- 按机房屏蔽该机房下所有的机器(可区分线上机/测试机,使用中/非使用中),包括ip1~ip5
3、取消屏蔽「恢复告警」
由于关闭永久开关,则需要提供接口取消屏蔽,重新开启开关。
- 提供根据屏蔽记录来取消的接口
- 提供更细维度的取消接口
- 由于取消永久开关并且实时更新业务树/机房下的ip,所以遇到这四种屏蔽则只能根据原记录mask id取消
- 如果是批量ip/appId/alarmId/statusId的取消则可以修改mask表中的生效的value,剔除需要取消的值即可