使用Python發(fā)送grafana快照拼合成的監(jiān)控日?qǐng)?bào)

Grafana是一套開(kāi)源的監(jiān)控圖表顯示框架,可以很方便地和監(jiān)控框架結(jié)合來(lái)顯示精美的監(jiān)控圖,比如常見(jiàn)的基于Zabbix監(jiān)控來(lái)顯示圖表。但是grafana本身只能通過(guò)一定的監(jiān)控指標(biāo)觸發(fā)告警通知,不支持定期發(fā)送日?qǐng)?bào)。

見(jiàn)網(wǎng)上大神使用Grafana reporter實(shí)現(xiàn)了日?qǐng)?bào)功能,實(shí)力有限沒(méi)有完成搭建。

參考http://www.itdecent.cn/p/03cf0fc9c746實(shí)現(xiàn)了以下日?qǐng)?bào)發(fā)送。

# -*- coding: UTF-8 -*-
import os
import time
import datetime
import threading
import urllib2
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.utils import parseaddr, formataddr
import logging

print "timer is started!!!!!"

#本地路徑
#file_path = "/mnt/c/Users/admin/Desktop/"
#log_path = "/mnt/c/Users/admin/Desktop/timer.log"
#容器內(nèi)文件路徑,注意結(jié)尾必須為斜線(xiàn)
file_path = "/mnt/deployer/monitor/imgs/"
log_path = file_path + "../timer.log"
print "log_path=" + log_path

##################################################
#匯報(bào)時(shí)間
alert_time = "09:00:00"
##################################################

##################################################
to_address = ['abc@163.com', 
#              '1234@163.com'] # 如果想發(fā)給多人,可以放入一個(gè)數(shù)組

cc_reciver = [edg@11.com'] ##['xxxxxxxx@qq.com', 'xxxxxxxx@qq.com'] # 如果想添加抄送人,也可以是單人或者數(shù)組的形式




#################################################


#logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',level=logging.DEBUG )
##打印日志到控制臺(tái)

logging.basicConfig(level=logging.DEBUG ,#控制臺(tái)打印的日志級(jí)別
                    filename=log_path,
                    filemode='a',##模式,有w和a,w就是寫(xiě)模式,每次都會(huì)重新寫(xiě)日志,覆蓋之前的日志
                    #a是追加模式,默認(rèn)如果不寫(xiě)的話(huà),就是追加模式
                    format=
                    '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
                    #日志格式
                    )

logging.info(  '圖片存放路徑為:' + file_path )
logging.info(  '日志存放文件為:' + log_path )


to_addr=''
cc_reciv=''
for to_add in range(len(to_address)): 
    to_addr = to_addr + to_address[to_add] + ";"
for cc_rec in range(len(cc_reciver)): 
    cc_reciv = cc_reciv + cc_reciver[cc_rec] + ";"
logging.info(  "收件人:"  + to_addr)
logging.info(  "抄送地址:"  + cc_reciv)

logging.info(  "匯報(bào)時(shí)間:"  + alert_time)

img_urls = [
["cluster_vcore_persent","http://127.0.0.1:3000/render/d-solo/J0mqLSlWk/neng-li-kai-fang-ji-qun-zong-lan-copybywyg?orgId=1&panelId=92&width=1000&height=500&tz=Asia%2FShanghai",""], 
##集群vcore
["queue_mem_persent","http://127.0.0.1:3000/render/d-solo/J0mqLSlWk/neng-li-kai-fang-ji-qun-zong-lan-copybywyg?orgId=1&panelId=56&width=1000&height=500&tz=Asia%2FShanghai",""],
##各個(gè)隊(duì)列內(nèi)存絕對(duì)使用百分比
["cluster_stor_persent","http://127.0.0.1:3000/render/d-solo/J0mqLSlWk/neng-li-kai-fang-ji-qun-zong-lan-copybywyg?orgId=1&panelId=98&width=1000&height=500&tz=Asia%2FShanghai",""],
##集群存儲(chǔ)使用情況總覽
["tenant_hdfs_persent","http://127.0.0.1:3000/render/d-solo/J0mqLSlWk/neng-li-kai-fang-ji-qun-zong-lan-copybywyg?orgId=1&panelId=50&width=1000&height=500&tz=Asia%2FShanghai",""],
##各租戶(hù)HDFS文件數(shù)
["cluster_rpc_persent","http://127.0.0.1:3000/render/d-solo/J0mqLSlWk/neng-li-kai-fang-ji-qun-zong-lan-copybywyg?orgId=1&panelId=34&width=1000&height=500&tz=Asia%2FShanghai",""],
#集群RPC隊(duì)列和處理時(shí)間#
["cluster_io_persent","http://127.0.0.1:3000/render/d-solo/J0mqLSlWk/neng-li-kai-fang-ji-qun-zong-lan-copybywyg?orgId=1&panelId=18&width=1000&height=500&tz=Asia%2FShanghai",""]
##集群網(wǎng)絡(luò)IO
]

F_stamp =  int(round(time.time()*1000))
F_time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
S_stamp = F_stamp - 7 * 24 * 3600*1000
S_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()- 7 * 24 * 3600))


def do_job():

    
    print time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
    logging.info(  '>>>>>>>>>>>>>時(shí)間到啦,開(kāi)始干活!' )
    
    if __name__ == '__main__':
    # 下載要的圖片
        F_stamp =  int(round(time.time()*1000))
        F_time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time()))
        S_stamp = F_stamp - 7 * 24 * 3600*1000
        S_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()- 7 * 24 * 3600))
        logging.info(  '本次監(jiān)控的開(kāi)始時(shí)間為:'+ str(S_time)+ ',對(duì)應(yīng)時(shí)間戳為:' + str(S_stamp))
        logging.info(  '本次監(jiān)控的結(jié)束時(shí)間為:'+ str(F_time)+ ',對(duì)應(yīng)時(shí)間戳為:' + str(F_stamp))
        ##逐個(gè)下載圖片
        for index in range(len(img_urls)): 
            img_name = file_path + img_urls[index][0]  + str(S_time)+ "-" + str(F_time) + ".png"
            img_url = img_urls[index][1] + "&from=" + str(S_stamp) + "&to=" + str(F_stamp)
        #    print img_url
            api_token = "amNfbmxrZjpqY19ubGtmQDEyMw==" #廊坊集群的
        #   img_name = "img" + time.strftime('%Y%m%d%H%M%S',time.localtime(time.time())) + ".png"
            logging.info(  '>>>>>>>>>>>>>開(kāi)始下載圖片' + img_name )
            download_img(img_url, api_token, img_name) 
            img_urls[index][2] = img_name
            logging.info(  '>>>>>>>>>>>>>下載完成-圖片' + img_name)
                    
        define_email();
        logging.info(   '>>>>>>>>>>>>>郵件發(fā)送成功')
        ##調(diào)用清理函數(shù)
        del_files(file_path)
   
    global timer
    timer = threading.Timer(86400, do_job) # 86400秒就是一天
    timer.start()

def del_files(path):
    logging.info(  '清理上個(gè)月的歷史文件')
    # 1. 獲取「今天」
    today = datetime.date.today()
    # 2. 獲取當(dāng)前月的第一天
    first = today.replace(day=1)
    # 3. 減一天,得到上個(gè)月的最后一天
    last_month = first - datetime.timedelta(days=1)
    # 4. 格式化成指定形式
    last_month_f = last_month.strftime("%Y-%m")
    logging.info(  '上個(gè)月為' + last_month_f)
    for root,dirs,files in os.walk(path):#(使用 os.walk ,這個(gè)方法返回的是一個(gè)三元tupple(dirpath(string), dirnames(list), filenames(list)), 其中第一個(gè)為起始路徑, 第二個(gè)為起始路徑下的文件夾, 第三個(gè)是起始路徑下的文件.)
        for name in files:
            if last_month_f in name:#判斷某一字符串是否具有某一字串,可以使用in語(yǔ)句
                logging.info(  '刪除歷史文件' + os.path.join(root,name))
                os.remove(os.path.join(root,name))##os.move語(yǔ)句為刪除文件語(yǔ)句



# 計(jì)算當(dāng)前時(shí)間到指定時(shí)間點(diǎn)的描述差
def get_interval_secs(target_time):
    today = (datetime.date.today()).strftime('%Y%m%d')
    today_time = today + "-" + target_time
    today_time_date = datetime.datetime.strptime(today_time, '%Y%m%d-%H:%M:%S')
    now = datetime.datetime.now()
    interval = today_time_date - now
    secs = interval.total_seconds()
    if (secs > 0): return secs
    else: return secs + 86400

timer = threading.Timer(get_interval_secs(alert_time), do_job) ### 郵件的發(fā)送時(shí)間
timer.start()

######################## 下載要的圖片

def download_img(img_url, api_token, img_name ):
    header = {"Authorization": "Basic " + api_token} # 設(shè)置http header
    request = urllib2.Request(img_url, headers=header)
#    print request
    try:
        response = urllib2.urlopen(request)
        filename =  img_name
        if (response.getcode() == 200):
            with open(filename, "wb") as f:
                f.write(response.read()) # 將內(nèi)容寫(xiě)入圖片
            return filename
    except:
        return "failed"

#########################發(fā)送郵件############

def define_email():

    
    sender = '*@chinaunicom.cn'  # 發(fā)件箱
    # receiver = 'xxxxxxxx@qq.com'  # 發(fā)給單人時(shí)的郵件接收郵箱
    

    reciver = to_address + cc_reciver
    
    smtpserver = "smtp.chinaunicom.cn" # 郵件服務(wù)器,如果是qq郵箱那就是這個(gè)了,其他的可以自行查找
    username = 'aaaaa@chinaunicom.cn' # 發(fā)件箱
    password = '*****' # 上發(fā)件箱密碼
    
    msgRoot = MIMEMultipart('related') # 郵件類(lèi)型,如果要加圖片等附件,就得是這個(gè)
    msgRoot['Subject'] = '廊坊集群資源監(jiān)控'+ str(S_time) + '~~~~' + str(F_time)  # 郵件標(biāo)題,以下設(shè)置項(xiàng)都很明了
    msgRoot['From'] = sender
    # msgRoot['To'] = receiver # 發(fā)給單人
    msgRoot['To'] = ",".join( to_address ) # 發(fā)給多人
    #message['Cc'] = ";".join(cc_reciver) # 抄送人
    try:
        # 以下為郵件正文內(nèi)容,含有一個(gè)居中的標(biāo)題和一張圖片
        content = MIMEText('<html>\
        <head>\
            <title>Page 1</title>\
            <meta http-equiv="content-type" content="text/html; charset=utf-8"/>\
        </head>\
        <body>\
            <div id="string" >您好:</div></p>\
            <div id="string" >&nbsp &nbsp &nbsp 廊坊集群資源使用情況如下:</div></p>\
        \
            <div id="string"  >&nbsp &nbsp &nbsp 1.集群Vcore使用百分比:</p>\
            &nbsp &nbsp &nbsp <img src="cid:image1" alt="image1"  /></div></p>\
        \
            <div id="string" >&nbsp &nbsp &nbsp 2.各隊(duì)列內(nèi)存絕對(duì)使用百分比:</p>\
            &nbsp &nbsp &nbsp <img src="cid:image2" alt="image2"  /></div></p>\
        \
            <div id="string"  >&nbsp &nbsp &nbsp 3.集群存儲(chǔ)使用情況總覽:</p>\
            &nbsp &nbsp &nbsp <img src="cid:image3" alt="image3"  /></div></p>\
        \
            <div id="string"  >&nbsp &nbsp &nbsp 4.各租戶(hù)HDFS文件數(shù):</p>\
            &nbsp &nbsp &nbsp <img src="cid:image4" alt="image4"  /></div></p>\
        \
            <div id="string"  >&nbsp &nbsp &nbsp 5.集群RPC隊(duì)列和處理時(shí)間:</p>\
            &nbsp &nbsp &nbsp <img src="cid:image5" alt="image5"  /></div></p>\
        \
            <div id="string"  >&nbsp &nbsp &nbsp 6.集群網(wǎng)絡(luò)IO:</p>\
            &nbsp &nbsp &nbsp <img src="cid:image6" alt="image6"  /></div></p>\
        \
            <div id="string"  >&nbsp &nbsp &nbsp </p>\
            <div id="string"  >&nbsp &nbsp &nbsp </p>\
            <div id="string"  >&nbsp &nbsp &nbsp </p>\
            <div id="string"  >&nbsp &nbsp &nbsp </p>\
            <div id="string"  >&nbsp &nbsp &nbsp </p>\
            <div id="string"  >&nbsp &nbsp &nbsp </p>\
        </body>\
        </html>\
        \
        ','html','utf-8')
        # 如果有編碼格式問(wèn)題導(dǎo)致亂碼,可以進(jìn)行格式轉(zhuǎn)換:
        # content = content.decode('utf-8').encode('gbk')
        msgRoot.attach(content)
    
        # 上面加的圖片src必須是cid:xxx的形式,xxx就是下面添加圖片時(shí)設(shè)置的圖片id
        # 添加圖片附件
        for index in range(len(img_urls)): 
            img_name = img_urls[index][2]
            fp = open(img_name, 'rb')
            msgImage = MIMEImage(fp.read())
            fp.close()
    #        imageid = "image" + str(index+1)
            msgImage.add_header('Content-ID', str("image" + str(index+1))) # 這個(gè)id用于上面html獲取圖片
            msgRoot.attach(msgImage)
    except:
        content = MIMEText('<html>\
        <head>\
            <title>Page 1</title>\
            <meta http-equiv="content-type" content="text/html; charset=utf-8"/>\
        </head>\
        <body>\
            <div id="string" >您好:</div>\
            <div id="string" >&nbsp &nbsp &nbsp 廊坊集群資源日?qǐng)?bào)發(fā)送失敗,請(qǐng)盡快處理。</div></p>\
        </body>\
        </html>\
        \
        ','html','utf-8')
        # 如果有編碼格式問(wèn)題導(dǎo)致亂碼,可以進(jìn)行格式轉(zhuǎn)換:
        # content = content.decode('utf-8').encode('gbk')
        msgRoot.attach(content)


    # 連接郵件服務(wù)器,因?yàn)槭褂肧MTP授權(quán)碼的方式登錄
    smtp = smtplib.SMTP('smtp.chinaunicom.cn:25')
    smtp.login(username, password)
    smtp.sendmail(sender, reciver, msgRoot.as_string())
    smtp.quit()
    

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容