zabbix内存CPU使用率每周报表脚本 python

环境:python3.7

需要pip安装环境:pymysql,xlsxwriter 

#!/usr/bin/python
#encoding:utf-8

import pymysql
import time,datetime
import xlsxwriter
import smtplib
import traceback
from email.mime.multipart import MIMEMultipart   
from email.mime.text import MIMEText
from email.header import Header  
    

#zabbix数据库信息:
zdbhost = '192.168.1.xx'
zdbuser = 'zabbix'
zdbpass = 'zabbix'
zdbport = 3306
zdbname = 'zabbix'

#生成文件名称:
linuxfilename = 'Linux_Report_Cpu_Mem_%s.xlsx' % time.strftime("%Y-%m-%d", time.localtime())
windowsfilename = 'Windows_Report_Cpu_Mem_%s.xlsx' % time.strftime("%Y-%m-%d", time.localtime())

#生成zabbix哪个分组报表
groupname = 'Linux'
groupname_2 = 'Windows'

#需要查询的key列表 [名称,表名,key值,取值,格式化,数据整除处理]
keys = [
['CPU平均空闲值','trends','system.cpu.util[,idle]','avg','%.2f',1],
['CPU最小空闲值','trends','system.cpu.util[,idle]','min','%.2f',1],
['物理内存大小(单位G)','trends_uint','vm.memory.size[total]','avg','',1048576000],
['可用平均内存(单位G)','trends_uint','vm.memory.size[available]','avg','',1048576000],
['swap空闲率%','trends','system.swap.size[,pfree]','avg','%.2f',1],
]

keys_2=[
['windows CPU平均使用率','trends',r'perf_counter[\\Processor(_Total)\\% Processor Time]','avg','%.2f',1],
['windows CPU最大使用率','trends',r'perf_counter[\\Processor(_Total)\\% Processor Time]','max','%.2f',1],
['物理内存大小(单位G)','trends_uint','vm.memory.size[total]','avg','',1048576000],
['可用平均内存(单位G)','trends_uint','vm.memory.size[free]','avg','',1048576000],
['虚拟内存空闲率%','trends','vm.vmemory.size[pavailable]','avg','%.2f',1],
]

class ReportForm:

    def __init__(self,groupname):
       
        #打开数据库连接
        self.conn = pymysql.connect(host=zdbhost,user=zdbuser,passwd=zdbpass,port=zdbport,db=zdbname,cursorclass=pymysql.cursors.DictCursor)
        self.cursor = self.conn.cursor()

        #获取IP信息:
        self.IpInfoList =self.getHostList(groupname)

 
    #根据zabbix组名获取该组所有IP
    def getgroupid(self,groupname):

        #查询组ID:

        sql = '''select groupid from groups where name = '%s' ''' % groupname

        self.cursor.execute(sql)

        groupid =self.cursor.fetchone()['groupid']

        return groupid

 
    #根据groupid查询该分组下面的所有主机ID(hostid):
    def gethostid(self,groupname):

        groupid =self.getgroupid(groupname)

        sql = '''select hostid from hosts_groups where groupid = %s''' % groupid

        self.cursor.execute(sql)

        hostlist = self.cursor.fetchall()

        return hostlist

 
    #生成IP信息字典:结构为{'119.146.207.19':{'hostid':10086L,},}
    def getHostList(self,groupname):

        hostlist =self.gethostid(groupname)

        IpInfoList = {}

        for i in hostlist:

            hostid = i['hostid']

            sql = '''select host from hosts where status = 0 and available=1 and hostid = %s''' % hostid

            ret =self.cursor.execute(sql)

            if ret:

               IpInfoList[self.cursor.fetchone()['host']] = {'hostid':hostid}

        return IpInfoList

 
    #获取itemid
    def getItemid(self,hostid,itemname):

        sql = '''select itemid from items where hostid = %s and key_ = '%s' ''' % (hostid, itemname)

        if self.cursor.execute(sql):

            itemid =self.cursor.fetchone()['itemid']

        else:

            itemid = None

        return itemid

 
    #查询trends表的值,type的值为min,max,avg三种
    def getTrendsValue(self,type,itemid, start_time, stop_time):

        sql = '''select %s(value_%s) as result from trends where itemid = %s and clock >= %s and clock <= %s''' % (type, type, itemid, start_time, stop_time)

        self.cursor.execute(sql)

        result =self.cursor.fetchone()['result']

        if result == None:

            result = 0

        return result

 
    #查询trends_uint表的值,type的值为min,max,avg三种
    def getTrends_uintValue(self,type,itemid, start_time, stop_time):

        sql = '''select %s(value_%s) as result from trends_uint where itemid = %s and clock >= %s and clock <= %s''' % (type, type, itemid, start_time, stop_time)

        self.cursor.execute(sql)

        result =self.cursor.fetchone()['result']

        if result:

            result = int(result)

        else:

            result = 0

        return result

 

 
    #根据hostid,itemname获取该监控项的值
    def getLastWeekData(self,type,hostid,table,itemname):

        #获取上周的第一天和最后一天
        self.fromdays=7+datetime.date.today().weekday()
        self.todays=datetime.date.today().weekday()+1

        ts_first =int(time.mktime((datetime.date.today()-datetime.timedelta(days=self.fromdays)).timetuple()))

        ts_last =int(time.mktime((datetime.date.today()-datetime.timedelta(days=self.todays)).timetuple()))

 

        itemid =self.getItemid(hostid, itemname)

        function =getattr(self,'get%sValue' % table.capitalize())

 

        return  function(type,itemid, ts_first, ts_last)


    def getInfo(self):

        #循环读取IP列表信息

        for ip,resultdict in  linux.IpInfoList.items():

            print("正在查询 IP:%-15shostid:%5d 的信息!" % (ip, resultdict['hostid']))

        #循环读取keys,逐个key统计数据:

        #ip 192.168.10.106    resultdict{'hostid': 10134L}

            for value in keys:

        #['CPU最小空闲值','trends','system.cpu.util[,idle]','min','%.2f',1]

                #print ("\t正在统计key_:%s" % value[2])

                if not value[2] in linux.IpInfoList[ip]:

                   linux.IpInfoList[ip][value[2]] = {}

                data =  linux.getLastWeekData(value[3],resultdict['hostid'],value[1],value[2])

                linux.IpInfoList[ip][value[2]][value[3]] = data

        #{'192.168.10.213':{'vfs.fs.size[/,total]': {'avg': 52844687360}, 'hostid': 10285L,'vm.memory.size[total]': {'avg': 33615073280}, 'system.swap.size[,total]':{'avg': 16877871104}, 'system.cpu.util[,idle]': {'avg': 97.409428410000004, 'min':94.498400000000004}, 'system.swap.size[,free]': {'avg': 16877871104},'vfs.fs.size[/,free]': {'avg': 45307376183}, 'system.cpu.load[percpu,avg5]':{'avg': 0.00272683}, 'vm.memory.size[available]': {'avg': 33064865249, 'min':32991432704}}

    def getInfo2(self):

        #循环读取IP列表信息

        for ip,resultdict in  windows.IpInfoList.items():

            print("正在查询 IP:%-15shostid:%5d 的信息!" % (ip, resultdict['hostid']))

        #循环读取keys,逐个key统计数据:

        #ip 192.168.10.106    resultdict{'hostid': 10134L}

            for value in keys_2:

        #['CPU最小空闲值','trends','system.cpu.util[,idle]','min','%.2f',1]

                #print ("\t正在统计key_:%s" % value[2])

                if not value[2] in windows.IpInfoList[ip]:

                   windows.IpInfoList[ip][value[2]] = {}
                

                data1 =  windows.getLastWeekData(value[3],resultdict['hostid'],value[1],value[2])

                windows.IpInfoList[ip][value[2]][value[3]] = data1

        #{'192.168.1.213':{'vfs.fs.size[/,total]': {'avg': 52844687360}, 'hostid': 10285L,'vm.memory.size[total]': {'avg': 33615073280}, 'system.swap.size[,total]':{'avg': 16877871104}, 'system.cpu.util[,idle]': {'avg': 97.409428410000004, 'min':94.498400000000004}, 'system.swap.size[,free]': {'avg': 16877871104},'vfs.fs.size[/,free]': {'avg': 45307376183}, 'system.cpu.load[percpu,avg5]':{'avg': 0.00272683}, 'vm.memory.size[available]': {'avg': 33064865249, 'min':32991432704}}

 
    #生成xls文件
    def writeToXls(self,xlsfilename,keysname):

            #创建文件
            workbook =xlsxwriter.Workbook(xlsfilename)

            #生产时间区间
            start_day=datetime.date.today()-datetime.timedelta(days=self.fromdays)
            end_day=datetime.date.today()-datetime.timedelta(days=self.todays)

            #创建工作薄
            worksheet =workbook.add_worksheet('%s至%s' % (start_day,end_day))
            #设置列宽
            worksheet.set_column('A:G', 18)

            #创建单元格格式
            format1 = workbook.add_format()
            format1.set_fg_color('#003063')
            format1.set_font_color('white')
            format1.set_border(1)

            format2 = workbook.add_format()
            format2.set_border(1)

            #写入第一列:
            worksheet.write(0,0,"主机名称IP",format1)
            i = 1
            for ip in self.IpInfoList:
               worksheet.write(i,0,ip,format2)
               i = i + 1

            #写入其他列(如果列数为5,则写内存百分比):
            i = 1
            k = 1
            for value in keysname:
                if i == 5:
                    k=i+1
                    worksheet.write(0,i,"可用内存百分比%",format1)
                    worksheet.write(0,k,value[0],format1)
                else:
                    k=i
                    worksheet.write(0,k,value[0],format1)

                #写入该列内容(内存百分比数据由前两列数据相除获得):
                j = 1
                for ip,result in self.IpInfoList.items():
                    if i==5:
                       worksheet.write(j,5, '=ROUND(E%s/D%s*100,2)'%(j+1, j+1),format2)
                    if value[4]:
                       worksheet.write(j,k, value[4] % result[value[2]][value[3]],format2)
                    else:
                       worksheet.write(j,k, "{:.2f}".format(result[value[2]][value[3]] / value[5]),format2)
                       
                    j = j + 1

                i = i + 1
            
            workbook.close()


    #关闭数据库连接
    def __del__(self):
        

        self.cursor.close()

        self.conn.close()
        

#发送邮件
def sendmail():
    #设置smtplib所需的参数
    #下面的发件人,收件人是用于邮件传输的
    smtpserver = 'mail.qq.com'
    sender='[email protected]'
    #收件人为多个收件人,逗号分隔
    to_mail=['[email protected]']
    cc_mail=['[email protected]']
        
    #设置标题
    subject = '测试Zabbix监控周报:内存、CPU'
    subject=Header(subject, 'utf-8').encode()
        
    #构造邮件对象MIMEMultipart对象
    #下面的主题,发件人,收件人,日期是显示在邮件页面上的。
    msg = MIMEMultipart('mixed') 
    msg['Subject'] = subject
    msg['From'] = '[email protected]'
    #收件人为多个收件人和抄送人,通过join将列表转换为以;为间隔的字符串
    msg['To'] = ";".join(to_mail)
    msg['Cc'] = ";".join(cc_mail)        
    #构造文字内容   
    text = "Zabbix监控周报:内存、CPU\n\n请查收!"    
    text_plain = MIMEText(text,'plain', 'utf-8')    
    msg.attach(text_plain)
        
    #构造附件
    linuxfile=open(r'%s' % linuxfilename,'rb').read()
    text_att = MIMEText(linuxfile, 'base64', 'utf-8') 
    text_att["Content-Type"] = 'application/octet-stream'
    text_att["Content-Disposition"] = 'attachment; filename=%s' % linuxfilename
    msg.attach(text_att)

    windowsfile=open(r'%s' % windowsfilename,'rb').read()
    text_att2 = MIMEText(windowsfile, 'base64', 'utf-8') 
    text_att2["Content-Type"] = 'application/octet-stream'
    text_att2["Content-Disposition"] = 'attachment; filename=%s' % windowsfilename
    msg.attach(text_att2)
        
    #发送邮件,同时发到收件人和抄送人
    smtp = smtplib.SMTP()    
    smtp.connect('mail.shanghaitrust.com', '25')
    smtp.sendmail(sender, to_mail+cc_mail, msg.as_string())  
    smtp.quit()
 

if __name__ == "__main__":
    try:
        
        linux = ReportForm(groupname)

        linux.getInfo()

        linux.writeToXls(linuxfilename,keys)

        windows = ReportForm(groupname_2)

        windows.getInfo2()

        windows.writeToXls(windowsfilename,keys_2)

        sendmail()
    except:
        #捕获异常,写入日志
        f=open("zabbix_log.txt",'a')  
        traceback.print_exc(file=f)  
        f.flush()  
        f.close()   

 

你可能感兴趣的:(Python,Zabbix)