本篇介绍把本地库表中的信息通过python发送到企业微信(sql server)
背景
承接上一篇博文《项目01(实现从Sql Server数据库读取报警数据并发送到企业微信01)》
link
业务逻辑
读取监控主机上DBCenter库中MobileMessages表中的监控内容Content字段发送到企业微信中的自建应用中
设计思路
- 利用python2.6.6发送(线上,脚本主机上的版本)
- 利用python3.9.0发送(新安装,miniconda,内容见下面链接)
link
注意:方案一解决目前的py2脚本乱码问题。(python2.6.6发送有中文乱码问题,已解决,详见下文)
方案二加装一个python3和原有python2共存(python3不存在乱码问题,小心环境替换系统原有py版本的问题)
方案三使用miniconda。(自定义python版本的虚拟环境,考虑到之后会使用python3进行新脚本的编写,
目前选择的是方案三,注意还是它安全高效)
脚本内容分为两部分,部分一为连接数据库读取数据和更新,部分二为通过接口发送信息
部分二参考的链接https://www.cnblogs.com/ddzj01/p/12185254.html
link
01
发送报警信息的python2版本
以下解决了py2乱码的问题
#! /usr/bin/python
#coding:utf8
import pymssql
import os
import requests,json
import urllib3
urllib3.disable_warnings()
s_host = '192.168.66.128'
s_user = 'sa2'
s_password = '1qaz!QAZ'
s_database = 'DBCenter'
#建立连接
connect = pymssql.connect(host = s_host,user = s_user,password = s_password,database = s_database)
#创建一个游标对象,python里的sql语句都要通过cursor来执行
cursor = connect.cursor()
#取出需要发生报警的信息,content是报警内容
sql01 = "select Content from MobileMessages where Status = 0"
sql02 = "update MobileMessages set Status = 1,SentTime =GETDATE() where status = 0"
cursor.execute(sql01)
contents = cursor.fetchall()
#fetchall 查不到结果,返回(),表示一个空的二维元祖,并退出程序
if not contents:
os._exit(0)
#for content in contents:
# print(content[0])
cursor.execute(sql02)
###填写参数###
# Corpid是企业号的标识
Corpid = "********"
# Secret是管理组凭证密钥
Secret = "**********"
# 应用ID
Agentid = "100000*"
# token_config文件放置路径
Token_config = r'/tmp/zabbix_wechat_config.json'
###下面的代码都不需要动###
def GetTokenFromServer(Corpid, Secret):
"""获取access_token"""
Url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
Data = {
"corpid": Corpid,
"corpsecret": Secret
}
r = requests.get(url=Url, params=Data, verify=False)
print(r.json())
if r.json()['errcode'] != 0:
return False
else:
Token = r.json()['access_token']
file = open(Token_config, 'w')
file.write(r.text)
file.close()
return Token
def SendMessage(Partyid, Subject, Content):
"""发送消息"""
# 获取token信息
try:
file = open(Token_config, 'r')
Token = json.load(file)['access_token']
file.close()
except:
Token = GetTokenFromServer(Corpid, Secret)
# 发送消息
Url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % Token
Data = {
"toparty": Partyid,
"msgtype": "text",
"agentid": Agentid,
"text": {"content": Subject + '\n' + Content},
"safe": "0"
}
r = requests.post(url=Url, data=json.dumps(Data), verify=False)
# 如果发送失败,将重试三次
n = 1
while r.json()['errcode'] != 0 and n < 4:
n = n + 1
Token = GetTokenFromServer(Corpid, Secret)
if Token:
Url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % Token
r = requests.post(url=Url, data=json.dumps(Data), verify=False)
print(r.json())
return r.json()
if __name__ == '__main__':
Partyid = str("2")
Subject = str("报警信息显示")
for i in range(len(contents)):
for j in range(len(contents[0])):
Content = contents[i][j]
# print(type(Content))
# print(Content)
Content = Content.encode('utf-8')
Status = SendMessage(Partyid, Subject, Content)
print(Status)
cursor.close()
#connect.commit()
结果
hostmonitor&zabbix 11-9 11:56:03
报警信息显示
测试5555--20201029+++
hostmonitor&zabbix 11-9 11:56:03
报警信息显示
测试6666--20201029+++
hostmonitor&zabbix 11-9 11:56:03
报警信息显示
测试8888--20201029+++
hostmonitor&zabbix 11-9 11:56:03
报警信息显示
测试11111111--20201029++++
hostmonitor&zabbix 11-9 11:56:04
报警信息显示
测试*11111111--20201029++++
关键信息
1.fetchall()导致contents变量是一个二维的元组,需要遍历2次(for两次)
2.需要Content = Content.encode('utf-8')
进行unicode encode> str #unicode经过encode变成str
3.调试中可以使用print(type(Content)),打印变量类型来出错的问题
02
发送报警信息的python3版本
#! /usr/local/python3
#coding:utf8
import pymssql
import os
#import datetime,os
import requests,json
import urllib3
urllib3.disable_warnings()
s_host = '192.168.66.128'
s_user = 'sa2'
s_password = '1qaz!QAZ'
s_database = 'DBCenter'
#建立连接
connect = pymssql.connect(host = s_host,user = s_user,password = s_password,database = s
_database)
#创建一个游标对象,python里的sql语句都要通过cursor来执行
cursor = connect.cursor()
##cursor.execute("select content from MobileMessages where id = %d" , 132308706)
#得到当前系统时间减去5分钟传递给sql01的senttime(此脚本的计划任务可以设置为3分钟执行一次)
#curr_time = datetime.datetime.now()
#datetime-->str
#time_str = datetime.datetime.strftime(curr_time - datetime.timedelta(minutes=5),'%Y-%m
-%d %H:%M:%S')
#取出需要发生报警的信息cretetime是远程表里面的创建时间,content是报警内容
sql01 = "select Content from MobileMessages where Status = 0"
sql02 = "update MobileMessages set Status = 1,SentTime =GETDATE() where status = 0"
cursor.execute(sql01)
contents = cursor.fetchall()
#fetchall 查不到结果,返回(),表示一个空的元祖,并退出程序
if not contents:
os._exit(0)
#for content in contents:
# print(content[0],content[1])
cursor.execute(sql02)
###填写参数###
# Corpid是企业号的标识
Corpid = "********"
# Secret是管理组凭证密钥
Secret = "*********"
# 应用ID
Agentid = "10000**"
# token_config文件放置路径
Token_config = r'/tmp/zabbix_wechat_config.json'
###下面的代码都不需要动###
def GetTokenFromServer(Corpid, Secret):
"""获取access_token"""
Url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
Data = {
"corpid": Corpid,
"corpsecret": Secret
}
r = requests.get(url=Url, params=Data, verify=False)
print(r.json())
if r.json()['errcode'] != 0:
return False
else:
Token = r.json()['access_token']
file = open(Token_config, 'w')
file.write(r.text)
file.close()
return Token
def SendMessage(Partyid, Subject, Content):
"""发送消息"""
# 获取token信息
try:
file = open(Token_config, 'r')
Token = json.load(file)['access_token']
file.close()
except:
Token = GetTokenFromServer(Corpid, Secret)
# 发送消息
Url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % Token
Data = {
"toparty": Partyid,
"msgtype": "text",
"agentid": Agentid,
"text": {"content": Subject + '\n' + Content},
"safe": "0"
}
r = requests.post(url=Url, data=json.dumps(Data), verify=False)
# 如果发送失败,将重试三次
n = 1
while r.json()['errcode'] != 0 and n < 4:
n = n + 1
Token = GetTokenFromServer(Corpid, Secret)
if Token:
Url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s" % T
oken
r = requests.post(url=Url, data=json.dumps(Data), verify=False)
print(r.json())
return r.json()
if __name__ == '__main__':
Partyid = str("2")
Subject = str("报警信息显示")
Content = str(contents)
Status = SendMessage(Partyid, Subject, Content)
# print(Status)
cursor.close()
connect.commit()
结果
报警信息显示
[('测试5555--20201029+++',), ('测试6666--20201029+++',),
('测试8888--20201029+++',),
('测试11111111--20201029++++',),
('测试*11111111--20201029++++',)]
建议以后使用pyhton3,修改python2的乱码问题,是为了直接使用现有的pyhton2环境(最小的更改动作)
miniconda 虚拟环境下需要安装的库
使用pip安装,需要先进入虚拟环境中
pymssql 2.1.5
simplejson 3.17.2
requests 2.24.0 defaults
urllib3 1.25.11 defaults
setuptools 49.6.0.post20201009 defaults
使用方法:
miniconda 虚拟环境外调用python3(外部使用绝对路径调用)
/usr/local/miniconda3/envs/myenv/bin/python pyname.py
常用命令
conda activate myenv
conda deactivate #退出环境
conda使用命令链接
link
脚本中企业微信信息的获取
link
特别特别鸣谢
知数堂Python老师,章老师。(耐心解答我的各种小白问题,最终脚本的信息也是在章老师的耐心指导之下完成的)
(此篇应该不存在以下问题)
本文说明,主要技术内容来自互联网技术大佬的分享,还有一些自我的加工(仅仅起到注释说明的作用)。如有相关疑问,请留言,将确认之后,执行侵权必删