1. 程式人生 > >使用Python查詢MySQL數據庫生成Excel文件發送監控周報。

使用Python查詢MySQL數據庫生成Excel文件發送監控周報。

Python MySQL Excel

業務方要求每周發一封周報出來,將過去一周的線上項目的詳細信息發送出來,我們的監控用的是zabbix,過去一直是手動填寫,非常耗時耗力,而且顯得非常不專業,所以我花了幾個月時間學習Python,編寫如下腳本供大家參考,望大神勿笑。

#!/usr/bin/env python
#-*- coding: utf8 -*-
import MySQLdb
import string
import xlsxwriter
import time,datetime
import sys
reload(sys)
sys.setdefaultencoding(‘utf-8‘)

zdbhost = ‘  ‘
zdbuser = ‘  ‘
zdbpass = ‘  ‘
zdbport =  
zdbname = ‘  ‘

#時間戳 取當前時間和7天前的時間 
stop_time = int(time.time())
start_time = stop_time - 604800
date = time.strftime("%Y-%m-%d",time.localtime(stop_time))
xlsfilename = ‘%s業務周報.xlsx‘ % date

#keys格式:itemname itemid type 格式化 groupid
keys = [
    [
        [‘UV/天‘,‘167365‘,‘max‘, ‘%.2f‘, 1,‘48‘,],
        [‘PV/周‘,‘167359‘,‘max‘, ‘%.2f‘, 1,‘48‘,],
        [‘最大並發‘,‘167364‘,‘max‘, ‘%.2f‘, 1,‘48‘,],
        [‘最大並發發生時間‘,‘167364‘,‘max‘, ‘%.2f‘, 1,‘48‘,],
        [‘平均QPS‘,‘167361‘,‘avg‘, ‘%.2f‘, 1,‘48‘],
        [‘最大QPS‘,‘167361‘,‘max‘, ‘%.2f‘, 1,‘48‘],
        [‘最大QPS發生時間‘,‘167361‘,‘max‘, ‘%.2f‘, 1,‘48‘],
        [‘最大帶寬(in)‘,‘81291‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘48‘],
        [‘平均帶寬(in)‘,‘81291‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘48‘],
        [‘最大帶寬(out)‘,‘81292‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘48‘],
        [‘平均帶寬(out)‘,‘81292‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘48‘]
    ],
    [
        [‘UV/天‘,‘168141‘,‘max‘, ‘%.2f‘, 1,‘16‘],
        [‘PV/周‘,‘168135‘,‘max‘, ‘%.2f‘, 1,‘16‘],
        [‘最大並發‘,‘168140‘,‘max‘, ‘%.2f‘, 1,‘16‘],
        [‘最大並發發生時間‘,‘168140‘,‘max‘, ‘%.2f‘, 1,‘16‘,‘‘],
        [‘平均QPS‘,‘168137‘,‘avg‘, ‘%.2f‘, 1,‘16‘],
        [‘最大QPS‘,‘168137‘,‘max‘, ‘%.2f‘, 1,‘16‘],
        [‘最大QPS發生時間‘,‘168137‘,‘max‘, ‘%.2f‘, 1,‘16‘],
        [‘最大帶寬(in)‘, ‘104522‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘16‘],
        [‘平均帶寬(in)‘, ‘104522‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘16‘],
        [‘最大帶寬(out)‘, ‘104523‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘16‘],
        [‘平均帶寬(out)‘, ‘104523‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘16‘]
    ],
    [
        [‘UV/天‘, ‘163672‘,‘max‘, ‘%.2f‘, 1,‘71‘],
        [‘PV/周‘, ‘163666‘,‘max‘, ‘%.2f‘, 1,‘71‘],
        [‘最大並發‘, ‘163671‘,‘max‘, ‘%.2f‘, 1,‘71‘],
        [‘最大並發發生時間‘, ‘163671‘,‘max‘, ‘%.2f‘, 1,‘71‘,‘‘],
        [‘平均QPS‘,‘163668‘,‘avg‘, ‘%.2f‘, 1,‘71‘],
        [‘最大QPS‘,‘163668‘,‘max‘, ‘%.2f‘, 1,‘71‘],
        [‘最大QPS發生時間‘,‘163668‘,‘max‘, ‘%.2f‘, 1,‘71‘],
        [‘最大帶寬(in)‘, ‘84942‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘71‘],
        [‘平均帶寬(in)‘, ‘84942‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘71‘],
        [‘最大帶寬(out)‘, ‘84943‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘71‘],
        [‘平均帶寬(out)‘, ‘84943‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘71‘]
    ],
    [
        [‘UV/天‘, ‘154707‘,‘max‘, ‘%.2f‘, 1,‘132‘],
        [‘PV/周‘, ‘154722‘,‘max‘, ‘%.2f‘, 1,‘132‘],
        [‘最大並發‘, ‘154706‘,‘max‘, ‘%.2f‘, 1,‘132‘],
        [‘最大並發發生時間‘, ‘154706‘,‘max‘, ‘%.2f‘, 1,‘132‘,‘‘],
        [‘平均QPS‘,‘154703‘,‘avg‘, ‘%.2f‘, 1,‘132‘],
        [‘最大QPS‘,‘154703‘,‘max‘, ‘%.2f‘, 1,‘132‘],
        [‘最大QPS發生時間‘,‘154703‘,‘max‘, ‘%.2f‘, 1,‘132‘],
        [‘最大帶寬(in)‘, ‘152400‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘132‘],
        [‘平均帶寬(in)‘, ‘152400‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘132‘],
        [‘最大帶寬(out)‘, ‘152402‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘132‘],
        [‘平均帶寬(out)‘, ‘152402‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘132‘]
    ],
    [
        [‘UV/天‘, ‘189559‘,‘max‘, ‘%.2f‘, 1,‘31‘],
        [‘PV/周‘, ‘189553‘,‘max‘, ‘%.2f‘, 1,‘31‘],
        [‘最大並發‘, ‘189558‘,‘max‘, ‘%.2f‘, 1,‘31‘],
        [‘最大並發發生時間‘, ‘189558‘,‘max‘, ‘%.2f‘, 1,‘31‘,‘‘],
        [‘平均QPS‘,‘189555‘,‘avg‘, ‘%.2f‘, 1,‘31‘],
        [‘最大QPS‘,‘189555‘,‘max‘, ‘%.2f‘, 1,‘31‘],
        [‘最大QPS發生時間‘,‘189555‘,‘max‘, ‘%.2f‘, 1,‘31‘],
        [‘最大帶寬(in)‘, ‘190757‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘31‘],
        [‘平均帶寬(in)‘, ‘190757‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘31‘],
        [‘最大帶寬(out)‘, ‘190758‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘31‘],
        [‘平均帶寬(out)‘, ‘190758‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘31‘]
    ],
    [
        [‘UV/天‘,‘188642‘,‘max‘, ‘%.2f‘, 1,‘50‘],
        [‘PV/周‘,‘188636‘,‘max‘, ‘%.2f‘, 1,‘50‘],
        [‘最大並發‘,‘188641‘,‘max‘, ‘%.2f‘, 1,‘50‘],
        [‘最大並發發生時間‘,‘188641‘,‘max‘, ‘%.2f‘, 1,‘50‘,‘‘],
        [‘平均QPS‘,‘188638‘,‘avg‘, ‘%.2f‘, 1,‘50‘],
        [‘最大QPS‘,‘188638‘,‘max‘, ‘%.2f‘, 1,‘50‘],
        [‘最大QPS發生時間‘,‘188638‘,‘max‘, ‘%.2f‘, 1,‘50‘],
        [‘最大帶寬(in)‘, ‘33707‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘50‘],
        [‘平均帶寬(in)‘, ‘33707‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘50‘],
        [‘最大帶寬(out)‘, ‘33712‘,‘max‘, ‘%.2f‘, ‘1048576‘,‘50‘],
        [‘平均帶寬(out)‘, ‘33712‘,‘avg‘, ‘%.2f‘, ‘1048576‘,‘50‘]
    ]
]

def report():
    ‘‘‘打開數據庫連接‘‘‘
    conn = MySQLdb.connect(host=zdbhost,user=zdbuser,passwd=zdbpass,port=zdbport,db=zdbname,charset=‘utf8‘)
    cursor = conn.cursor(cursorclass=MySQLdb.cursors.DictCursor)

    i = 2
    group = {"132":"微信公眾號", "71":"微信電視", "16":"chiq3音視頻", "48":"launcher", "50":"個性化推薦", "31":"語義雲"}
    value1 = {}
    value = {}
    #創建文件
    workbook = xlsxwriter.Workbook(xlsfilename)
            #定義Excel中的格式,參考http://xlsxwriter.readthedocs.io/
    merge_format = workbook.add_format({
        ‘bold‘:     True,
        ‘border‘:   True,
        ‘align‘:    ‘center‘,
        ‘valign‘:   ‘vcenter‘,
        ‘fg_color‘: ‘#D7E4BC‘,
    })
    merge_format1 = workbook.add_format({
        ‘border‘:   True,
        ‘align‘:    ‘center‘,
        ‘valign‘:   ‘vcenter‘,
        ‘text_wrap‘:   True,
    })

    #創建工作薄
    worksheet = workbook.add_worksheet()
    worksheet.set_column(‘A:L‘,11)
            #寫入第一行
    worksheet.merge_range(‘A1:L1‘, ‘業務監控周報(%s)‘.decode(‘utf-8‘) % date, merge_format) 
            #寫入其他行
    worksheet.write(1,0,‘項目名稱‘.decode(‘utf-8‘),merge_format1)
    for targets in keys:
        groupid = targets[0][5]
        worksheet.write(i,0,group[groupid].decode(‘utf-8‘),merge_format1)
        j = 1

        for target in targets:
            item = target[0]
            itemid = target[1]
            sql2 = ‘‘‘select %s(value_%s) as result from trends_uint where itemid = %s and clock >= %s‘‘‘ % (target[2], target[2], itemid, start_time)
            try:
                cursor.execute(sql2)
                result2 = cursor.fetchone()[‘result‘]
            except MySQLdb.OperationalError:
                result2 = "Not monitored"

            if target[0] in [‘最大QPS發生時間‘,‘最大並發發生時間‘]:
                #sql3 = ‘‘‘select clock from trends_uint where itemid = %s and value_%s = %s  and clock >= %s and clock <= %s ‘‘‘ % (target[1], target[2], result2, start_time, stop_time)
                sql3 = ‘‘‘select clock from trends_uint where itemid = %s and value_%s = %s  and clock >= %s limit 1‘‘‘ % (target[1], target[2], result2, start_time)
                try:
                    cursor.execute(sql3)
                    result3 = cursor.fetchone()[‘clock‘]
                    result2 = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(result3)) 
                except MySQLdb.OperationalError:
                    result2 = "Not monitored"
            #處理數據
            if not result2:
                result2 = "Not monitored"
            if type(result2) is str:
                result = result2
            else:
                if result2 > 1000:
                    if result2 > 1000000:
                        if result2 > 1000000000:
                            result = str(‘%.2f‘ %(float(result2)/1000000000)) + ‘G‘
                        else:
                            result = str(‘%.2f‘ %(float(result2)/1000000)) + ‘M‘
                    else:
                        result = str(‘%.2f‘ %(float(result2)/1000)) + ‘K‘
                else:
                    result = result2
            value1.update({itemid:result})
            value.update({groupid:value1})
            worksheet.write(1,j,item.decode(‘utf-8‘),merge_format1)
            worksheet.write(i,j,value[groupid][itemid],merge_format1)
            j += 1
        i += 1

    workbook.close()
    cursor.close()
    conn.close()
if __name__ == "__main__":
   report()

最終效果,每周由腳本發送郵件

技術分享圖片

使用Python查詢MySQL數據庫生成Excel文件發送監控周報。