您好,登錄后才能下訂單哦!
一、要求
? ? 最近公司大佬要求將應用每天的存活狀態,輸出成報表的形式,每天以郵件的方式發送給他們。報表里面要輸出:應用名、應用所在服務器IP、應用掛掉的時間點、應用掛掉的持續時間。
二、環境介紹
????我們公司用的監控系統,是小米的open-falcon,而app-alive的監控是用小米推薦的urlooker,urlooker監控的模式,是每分鐘將應用狀態推送到open-falcon。而我們這邊又用自己拿框架開發的ops系統,ops直接調用open-falcon的接口,在ops里面,可以看到應用存活的狀態,且ops.app_detail表記錄了應用id(唯一標識)及應用名。所以一開始我的想法是:去ops記錄應用狀態的表直接查詢。結果去查詢才發現,ops有兩張表是記錄跟應用狀態有關的數據。一張記錄的是應用down掉持續時間聚合后的信息,一張記錄的是1天、30天應用的存活率。。。。這根本跟我要的東西不一樣,所以最后思考半天,我決定直接去urlooker拿取數據。
關于urlooker數據庫:
? ?有兩張表跟app-alive有關:urlooker.strategy和 urlooker.item_status00,第一張表有兩個字段有用:urlooker.strategy.ops_cp_app_id(與ops.app_detail.id一一對應)和urlooker.strategy.environment(區分測試、預發布、release環境),第二張表urlooker.item_status00即是urlooker每分鐘push的數據,這張表默認保存12小時的數據。
三、查詢urlooker數據庫獲取數據源
通過跨庫聯表查詢,獲取所需的數據源,我這里查詢的結果是所有 result不為0即應用掛掉狀態的信息,并通過組內排序輸出。
SELECT ????????ops.app_detail.app_name, ????????urlooker.item_status00.sid?AS?sid, ????????urlooker.strategy.ops_cp_app_id, ????????urlooker.item_status00.ip, ????????urlooker.strategy.note, ????????urlooker.item_status00.result, ????????ROUND(?urlooker.item_status00.push_time?)?AS?down_time, ????????FROM_UNIXTIME(?urlooker.item_status00.push_time?)?AS?new_time? FROM ????????urlooker.item_status00 ????????LEFT?JOIN?urlooker.strategy?ON?urlooker.item_status00.sid?=?urlooker.strategy.id ????????LEFT?JOIN?ops.app_detail?ON?ops.app_detail.id?=?urlooker.strategy.ops_cp_app_id? WHERE ????????urlooker.strategy.environment?=?"release"? ????????AND?urlooker.item_status00.result?<>?"0"? ORDER?BY ????????sid?DESC, ????????down_time?DESC;
本來我想直接通過sql取做定時任務,但是關于數據源的計算及處理,實在不知道咋整(吃了沒技術的虧啊,應該用存儲過程可以實現)。所以直接將數據源導出,用shell去處理。
四、處理數據源
編寫shell腳本,處理數據源:
#?cat?send_app_alived.sh? #!/bin/bash DataInputPath=/home/app-alive/source.txt DataOutputPath=/home/app-alive/$(date?+%F)-output.csv #data? mysql?-uops_ro?-pxxxx?-e?"source?/home/app-alive/select.sql"?>?$DataInputPath??2>/dev/null app_id=$(awk?'{?print?$2}'?$DataInputPath?|grep?-v?sid|uniq) if?[?!?-f?"$DataOutputPath"?]; then ??echo?"應用名,服務器IP,應用停止時間,停止持續時間"?>?$DataOutputPath fi for?id?in?$app_id do ??down_time=$(awk?'{if($2=='$id')?print?$7}'?$DataInputPath) ??app_name=$(awk?'{if($2=='$id')?print?$1}'?$DataInputPath|uniq) ??app_ip=$(awk?'{if($2=='$id')?print?$4}'?$DataInputPath|uniq) ??down_time_num=$(awk?'{if($2=='$id')?print?$7}'?$DataInputPath|wc?-l) ??if?[?"$down_time_num"?-eq?"1"?]; ??then ????G_time=$(date?-d?"1970-01-01?UTC?$down_time?seconds"?+"%Y-%m-%d?%H:%M") ????echo?"$app_name,$app_ip,$G_time,1分鐘"?>>?$DataOutputPath ??else ????sum=0 ????count=0 ????for?i?in?$down_time ????do ??????sum=$((i-sum)) ??????if?[?$sum?-ne?-60?]?&&?[?$sum?-ne?$i?]; ??????then ???????G_time=$(date?-d?"1970-01-01?UTC?$down_sum?seconds"?+"%Y-%m-%d?%H:%M") ???????echo?"$app_name,$app_ip,$G_time,${count}分鐘"?>>?$DataOutputPath ???????count=0 ??????fi ??????if?[?$count?-eq?0?]; ??????then ????????down_sum=$i ??????fi ??????count=$((count?+?1)) ??????sum=$i ????done ????if?[?$count?-eq?1?]; ????then ??????G_time=$(date?-d?"1970-01-01?UTC?$down_sum?seconds"?+"%Y-%m-%d?%H:%M") ??????echo?"$app_name,$app_ip,$G_time,1分鐘"?>>?$DataOutputPath ????fi ??fi done
這個腳本處理完后,輸出的結果為:
# cat 2019-10-24-output.csv
用名,服務器IP,應用停止時間,停止持續時間
app01,10.25.100.36,2019-10-24 02:21,1分鐘
app01,10.81.126.19,2019-10-24 02:17,1分鐘
app02,10.81.126.19,2019-10-24 10:43,14分鐘
......
但是這里輸出的只是12小時的數據,所以加個計劃任務:
59 11,23 * * * /usr/bin/bash /home/app-alive/send_app_alived.sh
五、python腳本發送郵件
網上隨便找個python腳本,修改下:
#?cat?sendmail.py #?!/usr/bin/env?python #?-*-?coding:?utf-8?-*- import?smtplib import?email.mime.multipart import?email.mime.text from?email.mime.text?import?MIMEText from?email.mime.multipart?import?MIMEMultipart from?email.mime.application?import?MIMEApplication from?email.mime.multipart?import?MIMEMultipart from?email.mime.base?import?MIMEBase import?email import?base64 import?time import?os class?send_mail: def?__init__(self,?From,?To,?pw,?file_path,?file_header,?file_body): #?發送人 self.From?=?From #?收件人['aaa@a.com','bbb@a.com'] self.To?=?list(To) #抄送人 #?self.Cc?=?list(Cc) #?登錄郵件密碼base64.encodestring('明文')加密后密碼 self.pw?=?pw #?文件具體路徑(路徑+文件名稱) self.file_path?=?file_path #?標題頭 self.file_header?=?file_header #?內容 self.file_body?=?file_body def?login(self): server?=?smtplib.SMTP('smtp.qq.com') server.starttls() #?pwd?=?base64.decodestring(self.pw) server.login(self.From,?self.pw) try: receive?=?self.To #receive.extend(self.Cc) server.sendmail(self.From,self.To,self.atta()) finally: server.quit() def?atta(self): main_msg?=?MIMEMultipart() #?內容 text_msg?=?MIMEText(self.file_body) main_msg.attach(text_msg) try: contype?=?'application/octet-stream' maintype,?subtype?=?contype.split('/',?1) data?=?open(self.file_path,?'rb') file_msg?=?MIMEBase(maintype,?subtype) file_msg.set_payload(data.read()) data.close() email.encoders.encode_base64(file_msg) basename?=?os.path.basename(self.file_path.split('/')[-1]) file_msg.add_header('Content-Disposition',?'attachment',?filename=basename) main_msg.attach(file_msg) except?Exception?as?ret: print(ret) main_msg['From']?=?self.From main_msg['To']?=?";".join(self.To) #?main_msg['Cc']?=?";".join(self.Cc) #?標題頭 main_msg['Subject']?=?self.file_header main_msg['Date']?=?email.utils.formatdate() fullText?=?main_msg.as_string() return?fullText if?__name__?==?'__main__': fileTime?=?time.strftime("%Y-%m-%d",?time.localtime()) s?=?send_mail('9426096@qq.com',?['1224877@qq.com','xiang.yi@ai.com'],'jshntbmbejj',?"/home/app-alive/"+fileTime+"-output.csv",?'應用存活記錄',?'') s.login() ????print('發送成功!')
好了,就完成了。。。。雖然實現了,但是感覺好傻的樣子,open-falcon不好用啊,公司趕緊招個運維開發吧,我好難~~
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。