zabbix-5.0.14
需求
1、按需求导出所有的监控数据,比如任意指定一周内,导出所有主机的监控项,比如所有服务器的的最小负载,最大负载和平均负载,监控项包括,负载,CPU,磁盘和流量,导出到execl表格去
2、按需求导出所有服务器的故障时长,如任意指定一周内的所有主机故障时常,试过 ZbxTable 这个工具,但不靠谱,搞不到想要的数据,手动一个个查找后填表的方法不算
prometheus-2.36.0
1、按需求导出所有的监控数据,比如任意指定一周内,导出所有主机的监控项,比如所有服务器的的最小负载,最大负载和平均负载,监控项包括,负载,CPU,磁盘和流量,导出到execl表格去
2、按需求导出所有服务器的故障时长,如任意指定一周内的所有主机故障时常,手动一个个查找后填表的方法不算
3、prometheus包含自定义监控的数据,这个没什么头绪
谢谢!
这个比较复杂,请加私信
Zabbix导出很简单
dic1['Hostname']=i['name']
dic1['IP']=i['interfaces'][0]['ip']
dic1['磁盘C:Total(B)']=round(float(item1[0][0]['value'])/1024**3,2)
dic1['磁盘最大C:Used(B)']=round(float(item2[0][0]['value_max'])/1024**3,2)
dic1['内存Total(B)']=round(float(item1[1][0]['value'])/1024**3,2)
dic1['内存最大Used(B)']=round(float(item2[1][0]['value_max'])/1024**3,2)
dic1['内存平均used(B)']=round(float(item2[1][0]['value_avg'])/1024**3,2)
dic1['CPU负载最大值']=item2[2][0]['value_max']
dic1['CPU负载平均值']=item2[2][0]['value_avg']
dic1['CPU 核数']=item1[2][0]['value']
x = time.localtime(int(item1[2][0]['clock']))
item1[2][0]['clock'] = time.strftime("%Y-%m-%d %H:%M:%S", x)
dic1['clock']=item1[2][0]['clock']
host.append(dic1)
print(item)
print(host)
return host
def writecsv(getitem1):
with open('data.csv','w',encoding='utf-8-sig') as f:
#f.write(codecs.BOM_UTF8)
writer = csv.DictWriter(f,csvheader)
writer.writeheader()
for row in getitem1:
writer.writerow(row)
prometheus
获取主机IP,区分待机节点
def getTargetsStatus(serverip):
'''
获取主机IP,去掉宕机的节点
:param address:http api地址
:return: 存活主机列表,宕机主机列表
'''
url = 'http://' + serverip + ':9090' + '/api/v1/targets'
logger.info("获取节点IP地址:%s" % url)
response = requests.request('GET', url)
aliveNum, totalNum = 0, 0
#存活主机列表
uplist = []
#宕机主机列表
downList = []
if response.status_code == 200:
targets = response.json()['data']['activeTargets']
# print(type(targets))
# print(targets)
for target in targets:
totalNum += 1
if target['health'] == 'up':
aliveNum += 1
uplist.append(target['discoveredLabels']['__address__'].split(':')[0])
else:
downList.append(target['labels']['instance'].split(':')[0])
#去掉localhost
#todo 需要将去掉localhost改成IP
# print(uplist.index('localhost:9090'))
if uplist.index('localhost') != None:
uplist.remove('localhost')
return uplist,downList
获取cpu
def getCpuavage(serverip,nodeip,interval):
'''
cpu的使用率是空闲和使用时间的比例,并不是利用率
获取cpu30天内的使用率 1-(avg(irate(node_cpu_seconds_total{instance="192.168.2.29:9100",mode="idle"}[30d]))) * 100
http://10.61.150.104:9090/api/v1/query?query=\
(1 - (avg(irate(node_cpu_seconds_total{instance="192.168.2.29:9100",mode="idle"}[30d])))) * 100
:param serverip apiserver地址
:param nodeip 节点地址
:param interval 瞬时向量间隔30
:return value of cpu使用率
'''
heard = 'http://'+serverip+':9090'+'/api/v1/query?query='
expr = '(1-(avg(irate(node_cpu_seconds_total{instance="'+ nodeip+ ':9100",mode="idle"}[' + str(interval) +'d])))) * 100'
url = heard+expr
logger.info("执行查询CPU使用率:%s" % url)
response = requests.request('GET', url)
if response.status_code == 200:
# todo 有没有别的方法
if len(response.json()['data']['result']) != 0:
value = response.json()['data']['result'][0]['value'][1]
else:
value = 0
logger.error("获取结果为空")
else:
value = 0
logger.error("请求失败")
return value
获取内存
类似第二步骤:有一点要注意内存的使用率prometheus在centos7中可以使用node_memory_MemAvailable_bytes在centos6中需要使用(1-((node_memory_Buffers_bytes{job=".*"}+node_memory_Cached_bytes{job="."}+node_memory_MemFree_bytes{job="."})/ (node_memory_MemTotal_bytes{job="."}))) 100
在用接口请求的时候,报错“parse error: unexpected identifier "node_memory_Cached_bytes”
分别请求的时候可以获取到值,还没弄清楚原因#todo。所以只好选择分开计算然后用python做二元运算。
获取磁盘
max((node_filesystem_size_bytes{job="$job",fstype="ext.?|xfs"}-node_filesystem_free_bytes{job="$job",fstype="ext.?|xfs"}) *100/(node_filesystem_avail_bytes {job="$job",fstype="ext.?|xfs"}+(node_filesystem_size_bytes{job="$job",fstype="ext.?|xfs"}-node_filesystem_free_bytes{job="$job",fstype="ext.?|xfs"})))by(instance)
磁盘有个比较麻烦的地方无法获取全部的磁盘容量。比如/dev/sda /dev/sdb 总有一块没有获取到数据。也有待研究。#todo
获取GPU、负载
avg(irate(dcgm_gpu_utilization{instance="192.168.2.29:9100"}[1m]))
max_over_time(node_load5{instance="192.168.2.29:9100"}[30d])
根据IP查询cpu、内存、磁盘、GPU的30天的平均值,并返回一个execl行数据的列表
def getnodeinfo(serverip,nodeip,interval,devploment):
'''
:return: ["部门", "IP", "CPU使用率", "RAM使用率", "Disk使用率","Gpu使用率","负载"]
'''
nodeinfolist = []
logger.info("执行节点信息查询 %s" % nodeip)
# 获取CPU使用率
cpuinfo = format_data(getCpuavage(serverip, nodeip, interval))
# 获取内存使用率
raminfo = format_data(getRamavage(serverip, nodeip, interval))
# 获取磁盘根目录使用率
diskinfo = format_data(getDiskavage(serverip, nodeip))
# 获取GPU使用率
gpuinfo = format_data(getGpuavage(serverip, nodeip, interval))
# 获取负载信息
uptimeinfo = format_data(getUptime(serverip, nodeip, interval))
for i in [devploment, nodeip, cpuinfo, raminfo,diskinfo, gpuinfo, uptimeinfo]:
nodeinfolist.append(i)
return nodeinfolist
新建execl,按execl模块要求重构数据成二位数组[[]],并写入execl
def write_excel_xls(path, sheet_name, value):
index = len(value) # 获取需要写入数据的行数
workbook = xlwt.Workbook() # 新建一个工作簿
sheet = workbook.add_sheet(sheet_name) # 在工作簿中新建一个表格
for i in range(0, index):
for j in range(0, len(value[i])):
sheet.write(i, j, value[i][j]) # 像表格中写入数据(对应的行和列)
workbook.save(path) # 保存工作簿
logger.info("xls格式表格写入数据成功!")
#追加
def write_excel_xls_append(path, value):
index = len(value) # 获取需要写入数据的行数
workbook = xlrd.open_workbook(path) # 打开工作簿
sheets = workbook.sheet_names() # 获取工作簿中的所有表格
worksheet = workbook.sheet_by_name(sheets[0]) # 获取工作簿中所有表格中的的第一个表格
rows_old = worksheet.nrows # 获取表格中已存在的数据的行数
new_workbook = copy(workbook) # 将xlrd对象拷贝转化为xlwt对象
new_worksheet = new_workbook.get_sheet(0) # 获取转化后工作簿中的第一个表格
for i in range(0, index):
for j in range(0, len(value[i])):
new_worksheet.write(i+rows_old, j, value[i][j]) # 追加写入数据,注意是从i+rows_old行开始写入
new_workbook.save(path) # 保存工作簿
logger.info("xls格式表格【追加】写入数据成功!")
prometheus的数据可以通过PQL查询展示,也可以通过grafana配置大屏展示。
从你的描述来看,如果需要导入到excel表格需要自己写工具,通过prometheus http api查询你想要的数据再转换成你想要的格式。
prometheus本身应该没有这种功能