六步使用Python寫一個小小的自動化項目監控客網站全實現
在公司里做的一個介面系統,主要是對接第三方的系統介面,所以,這個系統里會和很多其他公司的項目交互。隨之而來一個很蛋疼的問題,這麼多公司的介面,不同公司介面的穩定性差別很大,訪問量大的時候,有的不怎麼行的介面就各種出錯了。
這個介面系統剛剛開發不久,整個系統中,處於比較邊緣的位置,不像其他項目,有日誌庫,還有簡訊告警,一旦出問題,很多情況下都是用戶反饋回來,所以,我的想法是,拿起python,為這個項目寫一個監控。如果在調用某個第三方介面的過程中,大量出錯了,說明這個介面有有問題了,就可以更快的採取措施。
項目的也是有日誌庫的,所有的info,error日誌都是每隔一分鐘掃描入庫,日誌庫是用的mysql,表裡有幾個特別重要的欄位:
level 日誌級別
message 日誌內容file_name Java代碼文件
log_time 日誌時間
有日誌庫,就不用自己去線上環境掃日誌分析了,直接從日誌庫入手。由於日誌庫在線上時每隔1分鐘掃,那我就去日誌庫每隔2分鐘掃一次,如果掃到有一定數量的error日誌就報警,如果只有一兩條錯誤就可以無視了,也就是短時間爆發大量錯誤日誌,就可以斷定系統有問題了。報警方式就用發送郵件,所以,需要做下面幾件事情:
1. 操作MySql。
2. 發送郵件。3. 定時任務。4. 日誌。5. 運行腳本。
明確了以上幾件事情,就可以動手了。
一、操作資料庫
使用MySQLdb這個驅動,直接操作資料庫,主要就是查詢操作。
獲取資料庫的連接:
defget_con():
host="127.0.0.1"
port=3306logsdb="logsdb"user="root"password="never tell you"con=MySQLdb.connect(host=host,user=user,passwd=password,db=logsdb,port=port,charset="utf8")returncon
從日誌庫里獲取數據,獲取當前時間之前2分鐘的數據,首先,根據當前時間進行計算一下時間。之前,計算有問題,現在已經修改。
defcalculate_time():
now=time.mktime(datetime.now().timetuple())-60*2result=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(now))returnresult
然後,根據時間和日誌級別去日誌庫查詢數據
defget_data():
select_time=calculate_time()http://logger.info("select time:"+select_time)sql="select file_name,message from logsdb.app_logs_record ""where log_time >"+"""+select_time+""""and level="+""ERROR"""order by log_time desc"conn=get_con()cursor=conn.cursor()cursor.execute(sql)
results=cursor.fetchall()cursor.close()conn.close()returnresults二、發送郵件
使用python發送郵件比較簡單,使用標準庫smtplib就可以
這裡使用163郵箱進行發送,你可以使用其他郵箱或者企業郵箱都行,不過host和port要設置正確。
defsend_email(content):
sender="sender_monitor@163.com"receiver=["rec01@163.com","rec02@163.com"]host="smtp.163.com"
port=465msg=MIMEText(content)msg["From"]="sender_monitor@163.com"msg["To"]="rec01@163.com,rec02@163.com"msg["Subject"]="system error warning"try:smtp=smtplib.SMTP_SSL(host,port)smtp.login(sender,"123456")smtp.sendmail(sender,receiver,msg.as_string())http://logger.info("send email success")
exceptException,e:logger.error(e)三、定時任務
使用一個單獨的線程,每2分鐘掃描一次,如果ERROR級別的日誌條數超過5條,就發郵件通知。
deftask():
whileTrue:http://logger.info("monitor running")results=get_data()ifresultsisnotNoneandlen(results)>5:content="recharge error:"http://logger.info("a lot of error,so send mail")
forrinresults:content+=r[1]+"
"send_email(content)sleep(2*60)四、日誌
為這個小小的腳本配置一下日誌log.py,讓日誌可以輸出到文件和控制台中。
# coding=utf-8
importlogginglogger=logging.getLogger("mylogger")logger.setLevel(logging.DEBUG)fh=logging.FileHandler("monitor.log")
fh.setLevel(http://logging.INFO)ch=logging.StreamHandler()ch.setLevel(http://logging.INFO)formatter=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")fh.setFormatter(formatter)ch.setFormatter(formatter)logger.addHandler(fh)logger.addHandler(ch)
所以,最後,這個監控小程序就是這樣的app_monitor.py
# coding=utf-8
importthreading
importMySQLdbfromdatetimeimportdatetimeimporttimeimportsmtplibfromemail.mime.textimportMIMETextfromlogimportloggerdefget_con():host="127.0.0.1"port=3306logsdb="logsdb"user="root"password="never tell you"con=MySQLdb.connect(host=host,user=user,passwd=password,db=logsdb,port=port,charset="utf8")returncondefcalculate_time():now=time.mktime(datetime.now().timetuple())-60*2result=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(now))returnresultdefget_data():select_time=calculate_time()http://logger.info("select time:"+select_time)sql="select file_name,message from logsdb.app_logs_record ""where log_time >"+"""+select_time+""""and level="+""ERROR"""order by log_time desc"conn=get_con()cursor=conn.cursor()cursor.execute(sql)results=cursor.fetchall()cursor.close()conn.close()returnresultsdefsend_email(content):sender="sender_monitor@163.com"receiver=["rec01@163.com","rec02@163.com"]host="smtp.163.com"port=465msg=MIMEText(content)msg["From"]="sender_monitor@163.com"msg["To"]="rec01@163.com,rec02@163.com"msg["Subject"]="system error warning"try:smtp=smtplib.SMTP_SSL(host,port)smtp.login(sender,"123456")smtp.sendmail(sender,receiver,msg.as_string())http://logger.info("send email success")exceptException,e:logger.error(e)deftask():whileTrue:http://logger.info("monitor running")results=get_data()ifresultsisnotNoneandlen(results)>5:content="recharge error:"http://logger.info("a lot of error,so send mail")forrinresults:content+=r[1]+"
"send_email(content)time.sleep(2*60)defrun_monitor():monitor=threading.Thread(target=task)monitor.start()if__name__=="__main__":run_monitor()五、運行腳本
腳本在伺服器上運行,使用supervisor進行管理。
在伺服器(centos6)上安裝supervisor,然後在/etc/supervisor.conf中加入一下配置:
[program:app-monitor]
command=python/root/monitor/app_monitor.pydirectory=/root/monitoruser=root
然後在終端中運行supervisord啟動supervisor。
在終端中運行supervisorctl,進入shell,運行status查看腳本的運行狀態。
六、總結
這個小監控思路很清晰,還可以繼續修改,比如:監控特定的介面,發送簡訊通知等等。
因為有日誌庫,就少了去線上正式環境掃描日誌的麻煩,所以,如果沒有日誌庫,就要自己上線上環境掃描,在正式線上環境一定要小心哇~
本文由作者為 Defshine,內容略經小編改編和加工,觀點跟作者無關,最後感謝作者的辛苦貢獻與付出。
你想更深入了解學習Python知識體系,你可以看一下我們花費了一個多月整理了上百小時的幾百個知識點體系內容:
【超全整理】《Python自動化全能開發從入門到精通》筆記全放送
為了方便大家學習,我建立了一個Python交流群,目前群內已經有450個小夥伴,學習寂寞的小夥伴不妨一起來玩~群號:475035830
推薦閱讀:
※Python 家族有多龐大
※Python數據分析及可視化實例之CentOS7.2+Python3x+Flask部署標準化配置流程