本文已参与「新人创作礼」活动,一起开启掘金创作之路。
==前 言==
当例行的Job报错后,大家都希望第一时间得到反馈,或者oncall你手机,或者邮件报警 ,身为阿里系的公司,钉钉当然是首选的交流工具之一,这里介绍一种调度Job报错或者异常触发钉钉报警的Python 3.x脚本;
==钉钉准备==
首先你得先建个群,群最少三个人,然后点击群助手,添加机器人,具体操作如图1,好了之后群里的机器人会说第一句话 “大家好!我是 贾维斯 机器人,很高兴为你们服务。”,然后你会得到这个机器人的webhook,其实就是一个ulr api,请妥善保管这个机密,而且只有群主,管理员以及创建这个机器人的主人才有权限修改这个机器人,如图2。
图1 添加机器人贾维斯 图2 得到机器人的webhook==核心代码编写==
核心代码其实就是调用了阿里钉钉的一个api,普通版如下:
def ding_alert(web_hook, ding_text, at_mobile):
url = web_hook ##刚刚获取的机器人webhook
msg = {
"msgtype": "text",
"text": {"content": ""},
"at": {"atMobiles": [""], "isAtAll": 0} ##需要@谁查看消息
} ##msg是个key,values的dictionary
msg["text"]["content"] = ding_text ##将要发送的消息赋值给message
if not at_mobile:
msg["at"]["isAtAll"] = 1 ##=1表示@all
else:
msg["at"]["atMobiles"] = "[" + at_mobile + "]"
headers = {'Content-Type': 'application/json'}
f = requests.post(url, data=json.dumps(msg), headers=headers)
有些公司为了安全,生产服务器不提供网络,这时候需要采用能连接外网的代理服务器来代理发送消息,毕竟钉钉本身是外网使用 的,即你在家也能看到钉钉消息,以下是代理服务器版本。
def ding_alert(web_hook, ding_text, at_mobile):
proxy_host = 10.234.56.78:14531 ##代理服务器端口
url = web_hook
msg = {
"msgtype": "text",
"text": {"content": ""},
"at": {"atMobiles": [""], "isAtAll": 0}
}
proxies = {
'http': proxy_host,
'https': proxy_host
}
msg["text"]["content"] = ding_text
if not at_mobile:
msg["at"]["isAtAll"] = 1
else:
msg["at"]["atMobiles"] = "[" + at_mobile + "]"
headers = {'Content-Type': 'application/json'}
f = requests.post(url, data=json.dumps(msg), headers=headers, proxies=proxies)
==封装成完整的代码项目==
既然调用的参数都是固定的,那么可以把这些参数写到mysql的库里存储,Python读取 mysql即可,所有,首先,建立一个mysql的config库,将这些参web_hook, ding_text, at_mobile等存入config库的cfg_ding_talk_warning_report表,该表的ddl sql语句如下:
CREATE TABLE `cfg_ding_talk_warning_report` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',
`ding_talk_group_id` bigint(20) NOT NULL COMMENT '钉钉组名id',
`ding_talk_group_name` varchar(200) NOT NULL COMMENT '钉钉组名',
`robot_url` varchar(500) NOT NULL COMMENT '机器人ulr',
`robot_name` varchar(500) DEFAULT NULL COMMENT '机器人名字',
`warning_report_text` varchar(500) NOT NULL COMMENT '报警内容',
`at_people_phone` varchar(500) DEFAULT NULL COMMENT '提醒谁看',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` varchar(50) NOT NULL COMMENT '创建人',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`update_by` varchar(50) NOT NULL COMMENT '修改人',
`is_enable` int(11) NOT NULL COMMENT '是否有效',
`level_desc` varchar(50) NOT NULL COMMENT '紧急等级:普通,中等,紧急',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
具体值如图3
图3 配置表存储信息整个项目的排版如图4:
图4 项目排版树图其中配置文件myconfig.ini里面记录的是代理服务器和刚刚说到的存配置信息表 cfg_ding_talk_warning_report的server信息:
[proxy]
proxy_host=agencyserver:port
[mysql_dw_config]
host = prod
port = 3306
user = user
passwd =
db = config
charset = utf8
代理版本ding_talk_with_agency
import requests
import configparser
import json
import pymysql
from sqlalchemy import create_engine
import pandas as pd
import sys
import os
def getcon():
config = configparser.ConfigParser()
file_path = os.path.dirname(__file__)
ini_path = "%s/../conf/myconfig.ini"%file_path
config.read(ini_path)
config_host = config['mysql_dw_config']["host"]
config_port = int(config['mysql_dw_config']["port"])
config_user = config['mysql_dw_config']["user"]
config_passwd = config['mysql_dw_config']["passwd"]
config_db = config['mysql_dw_config']["db"]
config_charset = config['mysql_dw_config']["charset"]
## print(config_host+'\t'+config_port+'\t'+config_user+'\t'+config_passwd+'\t'+config_db+'\t'+config_charset)
try:
print(1)
conn = pymysql.Connect(host=config_host, port=config_port, database=config_db, user=config_user,password=config_passwd, charset=config_charset)
return conn
except Exception as e:
print(e)
def ding_alert(web_hook, ding_text, at_mobile):
config = configparser.ConfigParser()
file_path = os.path.dirname(__file__)
ini_path = "%s/../conf/myconfig.ini"%file_path
config.read(ini_path)
proxy_host = config['proxy']["proxy_host"]
url = web_hook
msg = {
"msgtype": "text",
"text": {"content": ""},
"at": {"atMobiles": [""], "isAtAll": 0}
}
proxies = {
'http': proxy_host,
'https': proxy_host
}
msg["text"]["content"] = ding_text
if not at_mobile:
msg["at"]["isAtAll"] = 1
else:
msg["at"]["atMobiles"] = "[" + at_mobile + "]"
headers = {'Content-Type': 'application/json'}
f = requests.post(url, data=json.dumps(msg), headers=headers, proxies=proxies)
def main(argv):
myid=int(argv[1])
dw_config=getcon()
sqlcmd = """ SELECT * FROM cfg_ding_talk_warning_report WHERE id=%d and is_enable=1"""
sql1 = sqlcmd % (myid)
ding_talk_dataframe=pd.read_sql(sql1,dw_config)
##print(ding_talk_dataframe)
if ding_talk_dataframe.empty:
print("no DingDingTalk Report")
else:
url=ding_talk_dataframe['robot_url'].values[0]
print("url:"+url)
text=ding_talk_dataframe['robot_name'].values[0]+":"+ding_talk_dataframe['warning_report_text'].values[0]+" 处理等级:"+ding_talk_dataframe['level_desc'].values[0]
print("text:"+text)
atMobile=ding_talk_dataframe['at_people_phone'].values[0]
print("atMobile:"+atMobile)
ding_alert(url, text, atMobile)
if __name__ == "__main__":
main(sys.argv)
非代理版本ding_talk_with_no_agency.py
import requests
import configparser
import json
import pymysql
from sqlalchemy import create_engine
import pandas as pd
import sys
import os
def getcon():
config = configparser.ConfigParser()
file_path = os.path.dirname(__file__)
ini_path = "%s/../conf/myconfig.ini"%file_path
config.read(ini_path)
config_host = config['mysql_dw_config']["host"]
config_port = int(config['mysql_dw_config']["port"])
config_user = config['mysql_dw_config']["user"]
config_passwd = config['mysql_dw_config']["passwd"]
config_db = config['mysql_dw_config']["db"]
config_charset = config['mysql_dw_config']["charset"]
## print(config_host+'\t'+config_port+'\t'+config_user+'\t'+config_passwd+'\t'+config_db+'\t'+config_charset)
try:
print(1)
conn = pymysql.Connect(host=config_host, port=config_port, database=config_db, user=config_user,password=config_passwd, charset=config_charset)
return conn
except Exception as e:
print(e)
def ding_alert(web_hook, ding_text, at_mobile):
url = web_hook
msg = {
"msgtype": "text",
"text": {"content": ""},
"at": {"atMobiles": [""], "isAtAll": 0}
}
msg["text"]["content"] = ding_text
if not at_mobile:
msg["at"]["isAtAll"] = 1
else:
msg["at"]["atMobiles"] = "[" + at_mobile + "]"
headers = {'Content-Type': 'application/json'}
f = requests.post(url, data=json.dumps(msg), headers=headers)
def main(argv):
myid=int(argv[1])
dw_config=getcon()
sqlcmd = """ SELECT * FROM cfg_ding_talk_warning_report WHERE id=%d and is_enable=1"""
sql1 = sqlcmd % (myid)
ding_talk_dataframe=pd.read_sql(sql1,dw_config)
##print(ding_talk_dataframe)
if ding_talk_dataframe.empty:
print("no DingDingTalk Report")
else:
url=ding_talk_dataframe['robot_url'].values[0]
print("url:"+url)
text=ding_talk_dataframe['robot_name'].values[0]+":"+ding_talk_dataframe['warning_report_text'].values[0]+" 处理等级:"+ding_talk_dataframe['level_desc'].values[0]
print("text:"+text)
atMobile=ding_talk_dataframe['at_people_phone'].values[0]
print("atMobile:"+atMobile)
ding_alert(url, text, atMobile)
if __name__ == "__main__":
main(sys.argv)
调用脚本
##后面的1表示配置表里面的主键id
python ding_talk_with_agency.py 1 ##代理版本
python ding_talk_with_no_agency.py 1 ##非代理版本
整个项目已经备份上传至git hub,版权所有,欢迎借鉴,地址链接 :dingding_talk_report