夜莺-Nightingale
夜莺V6
项目介绍 架构介绍
快速开始
黄埔营
安装部署
升级
采集器
使用手册
API
数据库表结构
FAQ
开源生态
Prometheus
版权声明
第1章:天降奇兵
第2章:探索PromQL
第3章:Prometheus告警处理
第4章:Exporter详解
第5章:数据与可视化
第6章:集群与高可用
第7章:Prometheus服务发现
第8章:监控Kubernetes
第9章:Prometheus Operator
参考资料

夜莺和自定义告警通知方式?

首先,夜莺已经内置了多种常见的告警通知方式,包括不限于以下:

  • dingtalk
  • wecom
  • feishu
  • feishucard
  • telegram
  • email

如果上述这些通知方式还不能满足你的需求,那么可以添加自定义的告警通知媒介,首先需要在页面菜单:系统设置-通知设置-通知媒介中添加自定义的通知媒介,例如添加短信,其标识设置为sms,状态为不隐藏。添加配置后再去告警规则配置页面就能够看到新增的媒介了。

其次,自定义通知媒介是通过执行自定义脚本来实现的,这个脚本需要在系统配置-通知设置-通知脚本里设置。设置通知脚本状态为启用,设置合理超时时间,最重要的就是设置脚本的内容,有两种方式:

  1. 直接填写脚本内容:粘贴Python脚本内容即可
  2. 指定路径路径:填写脚本存放的路径

不过推荐填写脚本内容的方式,直接在页面上粘贴脚本内容,因为存放路径方式在集群部署时相对麻烦一些,需要在每个n9e/n9e-alert所在机器上放置脚本文件。

脚本文件可以参考etc/script/notify.py来改写。上例中,新增的告警媒介标识是sms,所以脚本文件里我们要自定义一个send_sms方法来发送对应的告警通知。


class Sender(object):
    ...
    @classmethod
    def send_sms(cls, payload):# 自定义短信通知媒介方法
        users = payload.get('event').get("notify_users_obj") # 获取所有接收通知的用户
        phones = {}
        for u in users:# 遍历用户获取手机号
            if u.get("phone"):
                phones[u.get("phone")] = 1
        if phones:
            # 核心是改写这个逻辑,调用自己公司的短信发送接口
            print("send_sms not implemented, phones: {}".format(phones.keys()))


def main():
    # 获取标准输入的json数据
    # 脚本要能发送告警消息,得先拿到告警事件详情,夜莺会把告警事件 encoding 成 json 字符串,通过 stdin 的方式传给脚本
    payload = json.load(sys.stdin) 

    # 为了方便调试,可以把告警事件的内容写到文件里,这样我们就知道夜莺通过 stdin 传过来的 json 是什么样的
    with open(".payload", 'w') as f:
        f.write(json.dumps(payload, indent=4))

    # json 包含两个属性,其中 tpls 属性就是通知内容,可以在通知模版(系统设置-通知模板)中自行修改
    # event 属性包含了这条告警的完整信息,可以从 notify_channels 看到要发送的通知媒介,notify_users_obj 看到接收告警的所有用户信息等等
    for ch in payload.get('event').get('notify_channels'): # 遍历告警设置的通知媒介名称
        send_func_name = "send_{}".format(ch.strip()) # 拼接通知媒介在脚本中方法名
        if not hasattr(Sender, send_func_name): # 查看 Sender 中是否存在对应方法
            print("function: {} not found", send_func_name) # 没有方法名继续下一个
            continue
        send_func = getattr(Sender, send_func_name) # 存在匹配方法名称
        send_func(payload) # 调用对应方法,发送告警通知,比如 send_sms send_dingtalk send_wechat 等等

if __name__ == "__main__":
    if len(sys.argv) == 1:
        main()
    elif sys.argv[1] == "hello":
        hello()
    else:
        print("I am confused")

夜莺内置了邮件、企微机器人、钉钉机器人、飞书机器人等通知方式,如果用户在告警规则配置中设置了这些通知方式,夜莺内置就会调用对应的通知方式完成消息推送,如果用户设置了自定义的通知方式,夜莺没有内置对应的通知方法,就会在日志中打印 ’no sender channel: xxx’,这个时候就需要用户在脚本里实现通知方法了。

夜莺的 etc/script/notify.py 脚本中,也有 send_email send_dingtalk send_wechat send_feishu 等方法,但都是空实现,写了 pass,这是因为这些通知逻辑在夜莺的 go 代码中已经内置了,脚本中就不需要重复发送了。

夜莺调用通知脚本的时候,会把告警事件详情序列化为 json 传给脚本,通过 stdin 的方式。脚本从告警事件中可以拿到告警接收人的手机号、邮箱等联系方式,进而调用自己公司的通道接口来发送即可。发送的时候,具体要发送什么内容?理应是从告警事件中获取一些字段来拼接,比如告警标题、告警备注、告警级别等等,但有的时候我们希望发送的内容格式比较多样,此时就需要引入模板机制了,通过模板定义发送消息的内容格式会更为方便。

夜莺支持自定义通知模板,在 etc/template 下内置了一些模板文件,我们可以在这个目录下创建自己的模板文件,之后就可以在页面上(系统设置-通知模板)来做二次修改。模板文件的格式是 go template,具体语法可以参考 go template 的文档。

自定义通知脚本,涉及到二次开发,如果您不想自己开发,也可以使用夜莺专业版,我们可以帮您完成通知媒介的对接,当然,专业版还有更多功能,您可以查阅这个链接了解详情:夜莺专业版

本文介绍的内容,也提供了视频演示,可以扫码观看:

Q:夜莺调用自定义通知脚本的时候,具体传递了哪些内容和字段?

A:传递的字段,具体可以参考 AlertCurEvent 结构,这个结构的各个字段都可以在模版中引用,引用的方式遵从 go template 语法。比如,告警事件中一般会有多个标签,模板文件中这个写法 {{.TagsJSON}} 可以按照数组的方式展示所有的标签。

Q: 夜莺调用自定义通知脚本的时候,如何自定义展示标签?

A: 比如,对于Kubernetes体系的监控数据,有的时候标签会非常非常多,看起来很费劲,有些朋友就会想,我是否可以只展示部分标签呢?

答案当然是可以的。TagsJSON 是所有标签的数组形式,TagsMap是所有标签的map形式,我们可以使用TagsMap来方便的获取特定的标签值,比如我这里修改企微的模板文件,不展示所有的标签:

**级别状态**: {{if .IsRecovered}}<font color="info">S{{.Severity}} Recovered</font>{{else}}<font color="warning">S{{.Severity}} Triggered</font>{{end}}
**规则标题**: {{.RuleName}}{{if .RuleNote}}
**规则备注**: {{.RuleNote}}{{end}}
**监控指标**: {{$metric := index .TagsMap "__name__"}}{{if eq "disk_used_percent" $metric}}机器:{{index .TagsMap "ident"}} 分区:{{index .TagsMap "path"}}{{else}}{{.TagsJSON}}{{end}}
{{if .IsRecovered}}**恢复时间**:{{timeformat .LastEvalTime}}{{else}}**触发时间**: {{timeformat .TriggerTime}}
**触发时值**: {{.TriggerValue}}{{end}}
**发送时间**: {{timestamp}}

注意上面监控指标那一行,先从TagsMap中拿到 __name__ 对应的标签值,就是 $metric,然后判断 $metric 是否是磁盘利用率,如果是就只展示ident标签的内容和path标签的内容,如果不是,就还是按照老样子,把TagsJSON全部展示出来。

Q:如果要把告警发送到私有化部署的飞书,支持吗,该如何配置?

A: 夜莺也支持私有化部署的飞书。配置方式和飞书类似,具体的步骤如下:

  • 第一步:访问菜单 系统设置-》通知设置-》通知媒介,在该设置页面中,找到feishu这一行,将其设置为不隐藏
  • 第二步:访问右上角菜单,打开个人信息设置页,在该页面中,选择添加联系方式,在联系方式下拉列表中选择feishu_robot_token,将其值设置为如下类似的地址:https://open.xxx.com/open-apis/bot/v2/hook/71cea89b-xxxx-yyyy-zzzz-ddddd , 其中 open.xxx.com 为私有化部署的飞书域名;
  • 第三步:设置完个人信息后,将自己添加到某个团队中,比如该团队为ops-team
  • 第四步:去到 告警管理 -》 告警规则页面中,配置一个告警策略,在告警策略的通知配置部分,勾选feishu,并在告警接收组中选择ops-team,至此,就可以把产生的告警推送到你的飞书了;

Q:默认通知媒介中,feishufeishucard 有什么区别?

A: feishu 是纯文本的展示方式,feishucard 支持多媒体方式的展示效果。

开源版
Flashcat
Flashduty