通过Python脚本实现机房环控及服务器硬盘自动化巡检并推送飞书

先上效果图:

在这里插入图片描述

环境概要:

  • 系统: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)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值