先上效果图:
环境概要:
- 系统:Centos7
- 环控数据:从环控系统SQL server数据库中获取
- 硬盘数据:从zabbix监控系统中获取
- 取值方法:ZabbixAPI,sqlcmd
脚本内容:
from pprint import pprint
from pyzabbix.api import ZabbixAPI
import time
from datetime import datetime, timedelta
import io
import sys
import requests
import json
import subprocess
# 数据库连接信息
source_server = '192.168.1.1'
source_database = 'Dataku'
source_username = 'sa'
source_password = '12345678'
#飞书URL,这里填飞书群机器人的webhook 地址
url = "https://open.feishu.cn/open-apis/bot/v2/hook/d232304d4d-c23sdd4-4134b-92340e-832341275243d0"
# 重定向输出到缓冲区
output_buffer = io.StringIO()
sys.stdout = output_buffer
# 脚本运行时间
starttime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
start_time = time.time()
print("自动晨检时间" + " " + starttime)
# zabbixAPI登录
zapi = ZabbixAPI('http://192.168.1.2/')
zapi.login('Admin', '231231231')
# 获取所有的主机组信息-------------------------协助通过zabbixapi获取监控项id信息的
#groups = zapi.hostgroup.get(output=['groupid', 'name'])
#pprint(groups)
# 获取指定组ID下的所有主机ID
#group_id = 4
#hosts = zapi.host.get(groupids=group_id, output=['hostid', 'name'])
# 检查主机ID及name信息
#pprint(hosts)
# 要查询的主机ID
#host_id = '10084'
# 获取指定主机下的所有监控项
#items = zapi.item.get(hostids=[host_id], output=['itemid', 'name', 'key_'])
#pprint(items)
#分割线-------------------------协助通过zabbixapi获取监控项id信息的
# 定义要获取的监控项,这里我是填我自己获取到的监控项ID及name信息,需要自行根据情况修改
items = [
{'itemid': '44937', 'name': '/: Free'},
{'itemid': '42270', 'name': 'Memory'},
{'itemid': '42269', 'name': 'CPU'},
{'itemid': '35276', 'name': 'ZABBIX版本'}
]
# 获取监控项的最新值
data = zapi.item.get(itemids=[i['itemid'] for i in items], output=['itemid', 'lastvalue'])
# 调整输出格式
result = {}
for d in data:
itemid = d['itemid']
# 查找对应的监控项
for item in items:
if item['itemid'] == itemid:
result[item['name']] = d['lastvalue']
break
# 格式化输出结果
zabbix_version = result['ZABBIX版本']
server_free = "{:.2f}%".format(float(result['/: Free']))
server_memory = "{:.2f}%".format(float(result['Memory']))
server_cpu = "{:.2f}%".format(float(result['CPU']))
# 输出结果
print(f"ZABBIX版本:{zabbix_version} 当前Server性能:/:Free {server_free} 内存:Used {server_memory} CPU:Used {server_cpu}")
print()
# 要查询的键值前缀和后缀,这里定义的是硬盘状态监控项的前缀
item_key_prefix = 'inspur.server.disk.status.'
# 获取指定组ID下的所有主机ID,这里我是要查询id为77的组中所有主机id和name信息
group_id = 77
hosts = zapi.host.get(groupids=group_id, output=['hostid', 'name'])
# 初始化异常监控项列表
error_items = []
# 初始化计数器
count = 0
# 获取指定所有主机的指定监控项的值
for host in hosts:
host_id = host['hostid']
host_name = host['name']
items = zapi.item.get(hostids=[host_id], output=['itemid', 'name', 'key_'], search={'key_': f"{item_key_prefix}"})
if not items:
continue
for item in items:
item_id = item['itemid']
item_key = item['key_']
item_name = item['name']
item_value = zapi.item.get(itemids=item_id, output=['lastvalue'])[0]['lastvalue']
# 检查监控项及监控值
# print(f"Host: {host_name}, {item_key} ({item_name}): {item_value}")
count += 1
if float(item_value) > 1:
error_items.append({
'host_name': host_name,
'item_name': item_name,
'item_value': item_value
})
# 输出异常信息和监控项信息
if error_items:
print('服务器磁盘:异常:')
for item in error_items:
print(f"{item['host_name']}: {item['item_name']} ({item['item_value']})")
else:
print(f"所有服务器磁盘状态:正常,共检查了{count}个磁盘监控项。")
#机房温湿度传感器监测状态监控项,这里是因为我提取用另外的数据库脚本将值已经对接到zabbix,所以直接读取他的结果
item1_id = '79907'
#机房温湿度传感器通讯状态监控项,这里是因为我提取用另外的数据库脚本将值已经对接到zabbix,所以直接读取他的结果
item2_id = '79906'
# 获取指定监控项的值
item1_value = zapi.item.get(itemids=[item1_id], output=['lastvalue'])[0]['lastvalue']
item2_value = zapi.item.get(itemids=[item2_id], output=['lastvalue'])[0]['lastvalue']
# 输出监控项的值,这里偷懒了一下,时间的检查项在我另外一个脚本中
print(f"所有机房温湿度传感器监测状态: {item1_value},共检查了20个监控项")
print(f"所有机房温湿度传感器通讯状态: {item2_value},共检查了10个监控项")
print()
print("Zabbix系统最近24小时告警记录:")
# 获取以当前时间为准的最近24小时的故障告警记录,仅输出告警主机和告警信息,过滤掉带恢复通知的告警记录
def get_alerts():
now = int(time.time())
alerts = zapi.alert.get(
output=["subject", "message"],
time_from=now - 24 * 3600, # 获取以当前时间为准的最近24小时的告警记录
time_till=now,
sortfield="clock",
sortorder="DESC"
)
if alerts:
output = ''
for alert in alerts:
message = alert['message']
if '恢复通知' in message:
continue # 过滤掉带恢复通知的告警记录
host = ''
problem = ''
lines = message.split('\r\n')
for line in lines:
if '告警主机' in line:
host = line.split(':')[1]
elif '告警信息' in line:
problem = line.split(':')[1]
if host and problem:
output += f"告警主机:{host}\n告警信息:{problem}\n\n"
if output:
return output
else:
return '最近24小时无告警'
else:
return '最近24小时无告警'
if __name__ == '__main__':
alerts = get_alerts()
print(alerts)
# 查询数据,这里需要确认的是在环控数据库中,每个机房的温湿度对应的列名及ID,还有库名,表结构
data = {}
for room, temp_prop, humi_prop in [('机房1', 'K2004001', 'K2004002'), ('机房2', 'K2008001', 'K2008002'),
('机房3', 'K2009001', 'K2009002'), ('机房4', 'K2007001', 'K2007002')]:
# 构造查询语句
sql = f"SELECT curvalue FROM {source_database}.dbo.devpropertyname WHERE devpropid='{temp_prop}' OR devpropid='{humi_prop}'"
# 执行查询
cmd = f'sqlcmd -S {source_server} -U {source_username} -P {source_password} -d {source_database} -h -1 -Q "{sql}"'
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
# 解析查询结果
result = output.decode().strip().split('\n')
temp = result[0].strip() if result[0] else 'N/A'
humi = result[1].strip() if result[1] else 'N/A'
data[room] = {'温度': temp, '湿度': humi}
# 格式化输出结果
for room, values in data.items():
temp = values['温度']
humi = values['湿度']
print(f"{room}机房:温度 {temp}℃,湿度 {humi}%")
print()
#这里的png也是我通过另外一个脚本做截图,在我别的文章里有
print("每日巡检dashboard请在文件夹中打开路径-文件内容每日自动更新:\\\\192.168.1.4\\Temp\\dashboard.png")
print("-------------------------------------自动巡检测试--------------------------------------")
# 恢复标准输出
sys.stdout = sys.__stdout__
# 获取需要发送的消息
message = output_buffer.getvalue()
# 发送消息
payload_message = {
"msg_type": "text",
"content": {
"text": message
}
}
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=json.dumps(payload_message))
print(response.content.decode('utf-8'))
print(message)