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

联系方式

联系方式主要用途有两个

  1. 可以控制用户信息中展示哪些联系方式,把不会用到的联系方式可以关闭
  2. 有时候用户自己新增加的通知媒介,比如公司内部的im,需要配置用户的联系方式,可以在这里创建

联系方式1

新增联系方式后可以在创建用户-联系方式选择。

联系方式2

使用场景

用户自己创建的通知媒介和联系方式主要在自定义通知脚本中使用,下面是一个脚本调用举例,你可以参考样例脚本,对接自己的内部通信工具。

系统会把告警事件的内容encode成json,然后通过stdin的方式传给通知脚本,脚本示例如下:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sys
import json
import urllib2

reload(sys)
sys.setdefaultencoding('utf8')  # 设置默认编码为utf-8

class Sender(object):
    @classmethod
    # 方法send_newtalk,newtalk要和配置的通知媒介一致;
    def send_newtalk(cls, payload):
        try:
            #print("Starting send_newtalk".encode('utf-8'))
            # 从payload中获取事件数据
            event = payload.get('event')
            # 获取通知用户对象
            users = event.get("notify_users_obj")
            # 获取告警规则名称
            rule_name = event.get("rule_name")
            # 默认事件状态为“触发
            event_state = "Triggered"
            # 如果事件已恢复,则状态为“恢复”
            if event.get("is_recovered"):
                event_state = "Recovered"
            # 用于存储Dingtalk机器人令牌和用户电话
            tokens = {}
            phones = {}

            #print("Extracting user information".encode('utf-8'))
            # 遍历用户,收集电话和Dingtalk令牌
            for u in users:
                if u.get("phone"):
                    phones[u.get("phone")] = 1

                contacts = u.get("contacts")
                # dingtalk_robot_token,需要根据需求替换对应名称,在夜莺通知设置-联系方式设定名称,用户里面配置参数
                if contacts.get("dingtalk_robot_token", ""):
                    tokens[contacts.get("dingtalk_robot_token", "")] = 1
            # 设置请求头
            headers = {
                "Content-Type": "application/json;charset=utf-8"
            }

            #print("Tokens: {}".format(tokens).encode('utf-8'))
            #print("Phones: {}".format(phones).encode('utf-8'))
            # 遍历令牌,构建请求并发送到Dingtalk
            for t in tokens:
                url = "https://oapi.dingtalk.com/robot/send?access_token={}".format(t)
                body = {
                    "msgtype": "markdown",
                    "markdown": {
                        "title": "{} - {}".format(event_state, rule_name),
                        "text": "{} {}".format(payload.get('tpls').get("dingtalk.tpl", "dingtalk.tpl not found"), ' '.join(["@"+i for i in phones.keys()]))
                    },
                    "at": {
                        "atMobiles": list(phones.keys()),
                        "isAtAll": False
                    }
                }

                #print("Sending request to URL: {}".format(url).encode('utf-8'))
                #print("Request body: {}".format(body).encode('utf-8'))

                data = json.dumps(body)
                req = urllib2.Request(url, data=data, headers=headers)
                req.get_method = lambda: "POST"
                response = urllib2.urlopen(req)
                result = response.read()
                #print("Response status code: {}".format(response.getcode()).encode('utf-8'))
                #print("Response text: {}".format(result).encode('utf-8'))
        # 捕获所有异常,防止程序崩溃
        except Exception as e:
            #print("Error in send_newtalk: {}".format(e).encode('utf-8'))

def main():
    try:
        #print("Reading payload from stdin".encode('utf-8'))
        payload = json.load(sys.stdin)
        with open(".payload", 'w') as f:
            f.write(json.dumps(payload, indent=4))
        #print("Payload written to .payload file".encode('utf-8'))

        for ch in payload.get('event').get('notify_channels'):
            send_func_name = "send_{}".format(ch.strip())
            #print("Processing channel: {}, function name: {}".format(ch, send_func_name).encode('utf-8'))
            if not hasattr(Sender, send_func_name):
                #print("Function {} not found".format(send_func_name).encode('utf-8'))
                continue
            send_func = getattr(Sender, send_func_name)
            send_func(payload)

    except Exception as e:
        print("Error in main: {}".format(e).encode('utf-8'))

def hello():
    print("hello nightingale".encode('utf-8'))

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

示例脚本中有很多 print 打印的输出,主要是为了方便调试使用。如果开启,可通过 n9e 的日志进行查看,日志调试在 INFO.log,报错状态在 ERROR.log,过滤关键词 event_script_notify

脚本日志

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云
OpenSource
开源版
Flashcat
Flashcat