主頁 > 後端開發 > Zabbix使用python匯出性能資料execl表-從零到無

Zabbix使用python匯出性能資料execl表-從零到無

2020-12-06 06:03:51 後端開發

- - 時間:2020年12月5日

- - 作者:飛翔的小胖豬

前言

使用zabbix作為基礎環境的監控系統時,除了通過web頁面和自定義告警通知手段獲取當前主機服務器運行狀態,趨勢資料也是很重要的,透過趨勢資料可以了解服務器在某個時間范圍內關鍵指標情況,是否長期高負載運行或長期空閑狀態,在虛擬化或云平臺環境下趨勢資料可作為服務器資源壓碩訓收擴容參考資料,文章通過使用python腳本連接zabbix后端的mysql資料庫,查詢整理服務器運行性能資料生成execl檔案,

環境

 

 

腳本說明

該腳本只試用于linux作業系統中,具體作業思路及流程如下:

1.獲取到主機所在監控模板的id號(步驟可以參考我https://www.cnblogs.com/Pigs-Will-Fly/p/13954583.html這篇文章中)文章中不涉及id號查詢方法,

2.獲取指定監控模板下所包含的所有主機id號,

3.使用主機id號和主機名形成字典,以便后期整合資料用,

4.使用主機id號結合item指標查詢出每個機器每個指標唯一的item號并生成字典,

5.使用item號查詢出具體的資料,

6.整合之前的所有資料,以主機名為key生成字典,

7.寫入資料到execl表中,

PS:腳本再查詢主機ID時使用的是監控模板ID,而不是使用分組ID號,

 

腳本檔案

#!/usr/bin/python3
# @Date: 2020/10/29 21:16
# @Author: lvan
# @email: [email protected]
# -*- coding: utf-8 -*-

import pymysql
import time,datetime
import math
from decimal import *
import xlsxwriter
import xlrd
#打開資料庫連接函式
def open_mysql_db(zdbhost,zdbuser,zdbpass,zdbport,zdbname):
    print(".開始連接資料庫...")
    conn = pymysql.connect(host=zdbhost, user=zdbuser, passwd=zdbpass, port=zdbport, db=zdbname, charset="utf8")
    cursor = conn.cursor()
    print("--完成:連接資料庫,狀態OK!")
    return cursor

# 指定模板ID,獲取模板中包含的主機id號
def get_temp_id(db_cursor,groupid):
    print("開始獲取模板中包含主機ID號...")
    sql = '''select hostid from hosts_templates where templateid = "{0}"'''.format(groupid)
    db_cursor.execute(sql)
    hostlist = [i for i in list("%s" %j for j in db_cursor.fetchall())]
    print("--完成:主機ID號獲取,狀態OK!")
    return hostlist
    #結果為['10357', '10362', '10363', '10365']


#通過hostid獲取到主機的host名,定義一個保存主機IP地址和ID號的字典
def get_host_for_hostid(hostlist,db_cursor):
    print('.開始生成主機id號和主機名對應關系...')
    Ipinfo_dict = dict()
    for hostid in hostlist:  #每次從hostlist中取一個hostid出來,然后獲取到指定的host通過字典的方式加入到IpinfoList中去,
        #print("hostid:",hostid)
        sql = '''select host from hosts where status = 0 and hostid = {0}'''.format(hostid)
        ret = db_cursor.execute(sql)
        if ret:
            for i in db_cursor.fetchone():
                Ipinfo_dict[hostid] = i
    print('--完成:主機id與主機名關系生成,狀態OK!')
    return Ipinfo_dict
    #結果{'10357': '192.168.111.131', '10362': '192.168.111.11', '10363': '192.168.111.12', '10365': '192.168.111.124'}



#獲取指定id號的主機的item資源號,在trends表和trends_uint中
def get_itemid(keys,hostlist,db_cursor):
    print('.開始獲取ITEM號...')
    Item_key_dict = dict()
    Hostid_Item_dict = dict()
    Item_name_list = list()
    item_name_dir = dict()
    for bb in ['trends','trends_uint']:
        Iteminfo_list = list()
        for j in keys[bb]:
            for k in hostlist:
                #print("this is %s,this er %s",j,k)
                sql = '''select itemid from items where hostid = {0} and key_ = "{1}" '''.format(k,j)
                if db_cursor.execute(sql):
                    itemid = "".join("%s" %i for i in list(db_cursor.fetchone()))
                    Hostid_Item_dict[itemid] = k
                    Iteminfo_list.append(itemid)
                    item_name_dir[itemid] = j
                else:
                    itemid = None
            Item_key_dict[bb] =Iteminfo_list
    print('--完成:ITEM號獲取,狀態OK!')
    return Item_key_dict,Hostid_Item_dict,item_name_dir
    #結果:輸出的item_dict: {'trends': ['33875', '34302', '34367', '34497', '33882', '34309', '34374', '34504', '33878', '34305', '34370', '34500'], 'trends_uint': ['33903', '34330', '34395', '34525', '33905', '34332', '34397', '34527']}
    #輸出的item_host_dict: {'33875': '10357', '34302': '10362', '34367': '10363', '34497': '10365', '33882': '10357', '34309': '10362', '34374': '10363', '34504': '10365', '33878': '10357', '34305': '10362', '34370': '10363', '34500': '10365', '33903': '10357', '34330': '10362', '34395': '10363', '34525': '10365', '33905': '10357', '34332': '10362', '34397': '10363', '34527': '10365'}



#整合資料,之前得主機id,ip地址,item值名,item名整合在一起,
def format_all_data(host_id_list,id_ip_dir,Item_key_dict,Hostid_Item_dict,Item_name_dir,item_values_dir_list):
    print('.開始整合資料...')
    resut_info = dict()
    for i in list(id_ip_dir.values()):
        temp_values_dir = dict()
        #print(i) #通過ip來確定,如果i和item_name_dir里面資料查出來的一致則記錄資料到字典,當資料記錄完畢后添加到最終字典中,并開啟下一次回圈,清空temp_values_dir字典
        for j in list(Item_name_dir.keys()):
            #print(j)
            temp_ip = id_ip_dir[Hostid_Item_dict[j]]
            temp_item_name = Item_name_dir[j]
            temp_value = item_values_dir_list[j]
            if temp_ip == i:
                temp_values_dir[temp_item_name] = temp_value
        resut_info[i] = temp_values_dir
    print('--完成:整合資料完成,狀態OK!')
    return resut_info
    #最終想得到的資料格式為:{ip:{{cpu:[最小,中間,最大]}},{記憶體:[最小,中間,最大]}}


#查詢指定表中的指定指標的資料,反饋itemid和及值名字型別大小,
def get_items_valuesb(item_dict_r,db_cursor,start_time,end_time):
    print('.開始查詢資料...')
    resultlist = {}
    for table_name in ['trends','trends_uint']:
        for itemid in item_dict_r[table_name]:
            sql = '''select min(value_min),avg(value_avg),max(value_max) from {2} where itemid = {3} and clock >= {4} and clock <= {5}'''.format(type, type, table_name, itemid, start_time, end_time)
            db_cursor.execute(sql)
            result = db_cursor.fetchall()
            for aa,bb,cc in result:
                value_list = list()
                value_list.append(aa)
                value_list.append(bb)
                value_list.append(cc)
                resultlist[itemid] = value_list
    print('完成:資料查詢完成,狀態OK!')
    return  resultlist
    #生成格式為{itemid:[min,avg,max]}


#寫入資料到execl中
def writeexecl(format_data_r_dict,file_dir):
    # 創建檔案
    print('開始生成execl檔案...')
    workbook = xlsxwriter.Workbook(file_dir)
    # 創建作業薄
    worksheet = workbook.add_worksheet()
    print(" 創建作業薄");
    # 寫入標題(第一行)
    i = 0
    for value in ["ip地址", "CPU負載谷值", "CPU負載均值", "CPU負載峰值","根目錄使用GB",'根目錄使用百分比GB','更目錄總量GB','記憶體可用谷值GB','記憶體可用均值GB','記憶體可用峰值GB','記憶體總大小GB','CPU空閑谷','CPU空閑均','CPU空閑峰','CPU個數']:
        worksheet.write(0, i, value)
        i = i + 1
        # 寫入內容:
    j = 1
    for ip_host in list(format_data_r_dict.keys()):
        #這為一行
        value=https://www.cnblogs.com/Pigs-Will-Fly/p/ format_data_r_dict[ip_host]
        worksheet.write(j, 0, ip_host)
        worksheet.write(j, 1, value['system.cpu.load[all,avg15]'][0])
        worksheet.write(j, 2, value['system.cpu.load[all,avg15]'][1])
        worksheet.write(j, 3, value['system.cpu.load[all,avg15]'][2])
        worksheet.write(j, 4, '{}GB'.format(math.ceil(value['vfs.fs.size[/,used]'][0] / 1024 / 1024 / 1024)))
        worksheet.write(j, 5, '{:.2f}%'.format(value['vfs.fs.size[/,pused]'][0]))
        worksheet.write(j, 6, '{}GB'.format(math.ceil(value['vfs.fs.size[/,total]'][0] / 1024 / 1024 / 1024)))
        worksheet.write(j, 7, '{}GB'.format(math.ceil(value['vm.memory.size[available]'][0] / 1024 / 1024 / 1024)))
        worksheet.write(j, 8, '{}GB'.format(math.ceil(value['vm.memory.size[available]'][1] / 1024 / 1024 / 1024)))
        worksheet.write(j, 9, '{}GB'.format(math.ceil(value['vm.memory.size[available]'][2] / 1024 / 1024 / 1024)))
        worksheet.write(j, 10, '{}GB'.format(math.ceil(value['vm.memory.size[total]'][0] / 1024 / 1024 / 1024)))
        worksheet.write(j, 11, '{:.2f}%'.format(value['system.cpu.util[,idle]'][0]))
        worksheet.write(j, 12, '{:.2f}%'.format(value['system.cpu.util[,idle]'][1]))
        worksheet.write(j, 13, '{:.2f}%'.format(value['system.cpu.util[,idle]'][2]))
        worksheet.write(j, 14, value['system.cpu.num'][0])
        j = j + 1
    workbook.close()
    print(" 完成:execl檔案生成,狀態OK!路徑為: ",file_dir)

if __name__ == "__main__":
    # zabbix資料庫資訊:
    zdbhost1 = "192.168.111.124"
    zdbuser1 = "zabbix"
    zdbpass1 = "password"
    zdbport1 = 3306
    zdbname1 = "zabbix"
    #監控模板id號
    groupid = 10001
    #定義時間范圍,此處填寫的時時間戳,可使用https://tool.lu/timestamp/網頁工具自行轉換,所以失效了自行百度,
    start_time = 0
    end_time = 999999999999
    #設定execl保存檔案名
    save_file_dir = 'test2222.xls'
    # 需要查詢的key串列,trends_unit字典里面的是trends_uint里的值;trends字典里面的是trends的值
    keys = {
        'trends_uint': [
            'vfs.fs.size[/,used]',
            'vm.memory.size[available]',
            'vm.memory.size[total]',
            'system.cpu.num',
            'vfs.fs.size[/,total]',
        ],
        'trends': [
            'system.cpu.load[all,avg15]',
            'system.cpu.util[,idle]',
            'system.swap.size[,pfree]',
            'vfs.fs.size[/,pused]',
        ],
    }
    db_r = open_mysql_db(zdbhost1,zdbuser1,zdbpass1,zdbport1,zdbname1)
    hostid_r = get_temp_id(db_r,groupid)
    ee = get_host_for_hostid(hostid_r,db_r)
    a,b,c=get_itemid(keys,hostid_r,db_r)
    ff = get_items_valuesb(a, db_r,start_time,end_time)
    ll = format_all_data(hostid_r,ee,a,b,c,ff)
    writeexecl(ll,save_file_dir)
View Code

 

如何使用腳本

讀者在copy腳本到自己本地后還需要對腳本中部分位置進行修改(下列沒有提到的地方盡量不要修改),需要修改的清單如下,

.基本引數類:

    》資料庫地址

    》資料庫用戶名

    》資料庫用戶密碼

    》資料庫埠

    》資料庫庫名

    》監控模板id號

    》時間范圍開始時間

    》時間范圍結束時間

    》execl檔案保存位置

.指標類:

    》keys字典值需要根據需求在其后添加對應指標

.execl類:

    》根據需求修改writeexecl函式中列名及列資料

 

基本引數修改:

基本引數類在main()函式中一目了然按照實際情況修改就行了,

 

修改指標及execl修改:

腳本中的指標和execl輸出的內容基本包含了服務器主要關注的點,讀者可以直接使用腳本中的指標及execl輸出格式,如果需要對指標和execl輸出結果進行修改,需要做到execl輸出內容一定要在keys字典中,

指標:

在main()函式的keys字典中根具實際需求添加(execl中用到的資料必須包含在keys,keys中的資料可以不被execl使用),

  

 

execl輸出:

writeexecl()函式中定義了execl輸出的列及實際資料,修改該函式時需要做到列名數量和實際資料列資料一致,

    列名:在for value in 列中紅色圈的串列中添加或者修改字符,

 

    具體資料:writeexecl()函式中修改具體資料來源時需要注意資料填入的具體列數,

 列名:0表示第一列,根據實際情況寫入資料到具體列,

 指標:keys字典中的值,需要寫入到execl中才寫入進來,

 下標:每一個指標在收集資料時都是一致的,下標0表示該指標的最小值,1表示該指標的均值,2表示該指標的峰值,

 

執行結果

 

結果execl表

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/230500.html

標籤:Python

上一篇:還能這樣偷懶?用Python實作網站自動簽到腳本

下一篇:Python爬蟲實戰案例:取喜馬拉雅音頻資料詳解

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more