一,Python簡介
二,監(jiān)控基本原理
三,監(jiān)控框架代碼分析
四,監(jiān)控源代碼分析
五, 文章總結(jié)有福利
為什么要腳本監(jiān)控呢,這是個(gè)非常嚴(yán)重需要注意的問題,為什么需要一個(gè)腳本監(jiān)控,
因?yàn)槟_本監(jiān)控是服務(wù)器的進(jìn)程,
如果寫代碼不夠健壯,他運(yùn)行十幾天二十幾天他突然蹦了,怎么辦如果這時(shí)候有一個(gè)腳本去監(jiān)控服務(wù)進(jìn)程就可以節(jié)省自己很多時(shí)間,
一,Python簡介
Python是近年來最火的一個(gè)熱點(diǎn),沒有之一。從性質(zhì)上來講它和我們熟知的C、JAVA、php等沒有什么本質(zhì)的區(qū)別,也是一種開發(fā)語言,而且已經(jīng)進(jìn)階到主流的二十多種開發(fā)語言的top 5(數(shù)據(jù)源自最新的TIOBE排行榜)。
Python 是一個(gè)高層次的結(jié)合了解釋性、編譯性、互動(dòng)性和面向?qū)ο蟮哪_本語言,具有很強(qiáng)的可讀性,相比其他語言經(jīng)常使用英文關(guān)鍵字,其他語言的一些標(biāo)點(diǎn)符號,它具有比其他語言更有特色語法結(jié)構(gòu)。
優(yōu)點(diǎn)
1.“優(yōu)雅”、“明確”、“簡單”- 所以Python程序看上去總是簡單易懂,
2. 開發(fā)效率高- Python有非常強(qiáng)大的第三方庫,基本上你想通過計(jì)算機(jī)實(shí)現(xiàn)任何功能,Python官方庫里都有相應(yīng)的模塊進(jìn)行支持,直接下載調(diào)用后,在基礎(chǔ)庫的基礎(chǔ)上再進(jìn)行開發(fā),
3. 高級語言- 當(dāng)你用Python語言編寫程序的時(shí)候,你無需考慮諸如如何管理你的程序使用的內(nèi)存一類的底層細(xì)節(jié)
4,如果你需要你的一段關(guān)鍵代碼運(yùn)行得更快或者希望某些算法不公開,你可以把你的部分程序用C或C++編寫,然后在你的Python程序中使用它們。
5. 由于它的開源本質(zhì),Python已經(jīng)被移植在許多平臺(tái)上(經(jīng)過改動(dòng)使它能夠工 作在不同平臺(tái)上)。如果你小心地避免使用依賴于系統(tǒng)的特性,那么你的所有Python程序無需修改就幾乎可以在市場上所有的系統(tǒng)平臺(tái)上運(yùn)行
6. 如果你需要你的一段關(guān)鍵代碼運(yùn)行得更快或者希望某些算法不公開,你可以把你的部分程序用C或C++編寫,然后在你的Python程序中使用它們。
缺點(diǎn)
7. 代碼運(yùn)行速度慢
8. 發(fā)布程序時(shí)必須公開源代碼
二,監(jiān)控基本原理
1. cactio
cacti不是監(jiān)控工具,他是個(gè)依賴于SNMP的數(shù)據(jù)采集和數(shù)據(jù)呈現(xiàn)的工具。
數(shù)據(jù)采集、 保存數(shù)據(jù)[SQL, txt].
數(shù)據(jù)展示(rrdtool 繪圖)。
數(shù)據(jù)分析和報(bào)警(很一般)。
2. nagIOS。
功能:數(shù)據(jù)報(bào)警(報(bào)警功能是Nagios的特色功能) [ 故障觸發(fā),故障恢復(fù)都可以。
依賴分析報(bào)警(能自動(dòng)的識(shí)別到關(guān)鍵設(shè)備的故障,關(guān)聯(lián)設(shè)備不會(huì)報(bào)警)。
數(shù)據(jù)采集(采集的數(shù)據(jù)是弱項(xiàng),他只關(guān)心警戒位,只關(guān)心正常與否的狀態(tài),狀態(tài)轉(zhuǎn)換時(shí)可以實(shí)現(xiàn)報(bào)警,所以它采集的數(shù)據(jù)不需要保存),當(dāng)然也有插件彌補(bǔ)這個(gè)不足,如PNP4Nagios。
3. zabbix (php)(推薦)
Nagiostcacti整合互相彌補(bǔ)不足!I
nagios和 cacti不適合超大規(guī)模的監(jiān)控、由于大規(guī)模的帶寬和網(wǎng)絡(luò)限制,會(huì)導(dǎo)致監(jiān)控的延遲等問題,所以有很多是 nagios+ cacti整合,但是依然不適合在大規(guī)模的環(huán)境中,不適合分布式部署, Nagios在大規(guī)模中就會(huì)出現(xiàn)延遲,失
去 Nagios本事的特色。
那么 zabbix同時(shí)整合了 cacti和 Nagios特點(diǎn)的工具,而且還具有了前兩者不具有的工具,支持分布式等等。
4. 補(bǔ)充工具:
netdata:托管在github上的一款類型zabbix的開源監(jiān)控工具h(yuǎn)ttps:/
/github. com/firehol/netdata
open- falcon:小米公司開源的企業(yè)級監(jiān)控工具(python)(推薦)
Ganglia類似于 zabbix,大型分布式監(jiān)控系統(tǒng)
開源監(jiān)控工具對比http://www.oschina.net/news/67525/monitoring-tools
5. 監(jiān)控軟件數(shù)據(jù)采集的方式
SNMP 協(xié)議。
agent 代理的方式去采集數(shù)據(jù)。
shell 腳本api 接口
6. 數(shù)據(jù)展示方式
php html App
7. 數(shù)據(jù)告警
mail,msm,微信,電話,釘釘機(jī)器人
三,框架源代碼分析
常見shell
基本結(jié)構(gòu)
- vim file.sh
- chmod +x file.sh #授權(quán)
- sh +xv file.sh #調(diào)試
- ./file.sh #絕對路徑,執(zhí)行腳本
基本腳本構(gòu)成
- 命令
- 變量
- 單一目的的小程序,由shell來解釋命令并告訴kernel;
- set
- -e 這句語句告訴bash如果任何語句的執(zhí)行結(jié)果不是true則應(yīng)該退出
- -c dir:在讀取 makefile 之前改變到指定的目錄dir;
- 管道
- 重定向
- 退出
命令
- 替換:變量=${變量}、變量=$(命令)、變量=表達(dá)式、變量=‘字符串’、變量=值
- 查看:echo $X
- 賦值:expr
- 運(yùn)算:let、&成功執(zhí)行命令2、||#失敗執(zhí)行命令2
if [-n/-z $string] #如果string非空/空,返回True;
if [xx1 -d/-a/-o xx2] #不存在、并列(文件1比文件2新)、或;
[-e/-d/-f/-L/-r/-s/-h FILENAME] #如果FILENAME存在/為目錄/為常規(guī)文件/符號鏈接/可讀/長度不為0/軟鏈接,則為真
- 比較:-gt、-lt、-eq
- 處理:#、%、/
- 特殊變量(參數(shù))
- 移動(dòng):shift #把變量從參數(shù)數(shù)組中移除
范圍
seq a b
seq -w b
循環(huán)、條件
- for
- if
- while
xpect
例題:
1. 測試一:監(jiān)控磁盤的使用率,>90%時(shí)給root發(fā)郵件
2.測試二:寫一個(gè)腳本解決DOS攻擊生產(chǎn)案例
提示:根據(jù)web日志或者或者網(wǎng)絡(luò)連接數(shù),監(jiān)控當(dāng)某個(gè)IP并發(fā)連接數(shù)或者短時(shí)內(nèi)PV達(dá)到100,即調(diào)用防火墻命令封掉對應(yīng)的IP,監(jiān)控頻率每隔3分鐘。
法一:
# !/bin/bash
IP=`netstat -nut | awk '{print $5}' | cut -d: -f1 | grep -o '.*[0-9]' | awk '{++ip[$1]}END{for(i in ip)print ip[$1],i}' | sort -n
IP=`netstat -nut | awk '{print $5}' | cut -d: -f1 | grep -o '.*[0-9]' | awk '{++ip[$1]}END{for(i i n ip)print ip[$1],i}' | sort -n | awk '{if($1>1)p rint $2}'`
3. 測試三:查看10.0.0.0/24網(wǎng)段中的在線用戶數(shù);
ping:測試主機(jī)間網(wǎng)絡(luò)的連通性
22. env CLOUD_MySQL_ENV=test exec /opt/cloud_mysql/bin/uwsgi --die-on-term --ini /opt/cloud_mysql/conf/uwsgi.in
nmap:一款開源的網(wǎng)絡(luò)探測器和安全審核工具,它可以快速掃描大型網(wǎng)絡(luò)
4. 批量創(chuàng)建文件及改名(不同的系統(tǒng)語法有所不同,此為另一種思路)
15.passwd=`echo $(date+%t%N)$RANDOM|md5sum|cut -c 2-9` #$RANDOM表示內(nèi)部變量,可以創(chuàng)建隨機(jī)數(shù);date+X%設(shè)置系統(tǒng)時(shí)間格式
16. useradd oldboy$n >&/dev/null&& user_status=$?
17. echo "$passwd"|passwd --stdinoldboy$n >&/dev/null && pass_status=$? #用echo xxx | yyy --stdin zzz,其中xxx為和終端交互內(nèi)容
python
#當(dāng)前時(shí)間
time.strtime(’%y-%m-%d’)
#磁盤狀態(tài)
os.open('df -h ',‘r’).readline()
#表示形態(tài)
‘n’.join(xxx)
#寫入數(shù)據(jù)
f.write(’%s’ % str)、f.flush() 、f.close()
四,監(jiān)控源代碼分析
1,PS命令查看linux程序進(jìn)程
2,shell腳本
利用PS命令查看server進(jìn)程的狀態(tài),如死亡、就重新啟動(dòng)。做一個(gè)死循環(huán)輪訓(xùn)。
30秒去輪詢這個(gè)這個(gè)進(jìn)程。死亡就繼續(xù)重啟。
3,效果
PS查看進(jìn)程號,此時(shí)procnum = 3 然后用kill 命令殺死進(jìn)程之后
然后腳本檢測到后,進(jìn)而重啟。這時(shí)server的進(jìn)程號已經(jīng)變化。這樣server服務(wù)器的進(jìn)程就完成的死亡重啟的監(jiān)控。
綜合起來這句指令的意思就是:
以詳細(xì)格式查看所有進(jìn)程,從中選出具有關(guān)鍵字 Manipulator 的進(jìn)程,但是排除掉用于查找的grep自身進(jìn)程,對于滿足上面條件的結(jié)果,統(tǒng)計(jì)其行數(shù),也就是看有幾個(gè)帶有Manipulator關(guān)鍵字的進(jìn)程,將統(tǒng)計(jì)的結(jié)果賦值給變量monitor 。
if…then…else…fi : shell腳本里面 if 語句的用法, fi 符號與 if 符號成對使用,表示 if 語句的結(jié)束。
if [ $monitor -eq 0 ] : if 語句的判斷用 test 或者 “[ ]” ,符號” $“ 表示取變量的值, -eq表示等于, -gt大于, -lt小于, -ge大于等于,-le小于等于。
echo :用于輸出顯示。
用于運(yùn)行Manipulator程序。
二、對使用python打開的多個(gè)程序的監(jiān)控
因?yàn)橹雷约合胍O(jiān)控的程序的具體名字,所以對于這一類程序的監(jiān)控也可以用上面的方法,但是這一類情況也讓我們思索另一種方法進(jìn)行監(jiān)控。
在我的 /home/mk90/Documents/restart_pro 文件夾里有 test.py 和 test2.py 兩個(gè)python程序,現(xiàn)在我要看這兩個(gè)程序是否已經(jīng)打開,如果沒有就打開它們。
multi_restart.sh
declare -a Array : 表示聲明了一個(gè)數(shù)組 Array
這句指令包含的內(nèi)容較多
pgrep 是通過程序的名字來查詢進(jìn)程的工具;
sed是一個(gè)很好的文件處理工具,本身是一個(gè)管道命令,主要是以行為單位進(jìn)行處理,可以將數(shù)據(jù)行進(jìn)行替換、刪除、新增、選取等特定工作,詳細(xì)用法可以參考
https://blog.csdn.net/zhushuai1221/article/details/53114178
sed -n 1p : 的作用就是對前面查找的結(jié)果,讀取第一行,同樣 sed -n 2p 就是讀取第二行 ;
awk '{print $1}’ : awk命令通常是將所列出的行,根據(jù)條件打印出某一列或幾列,這里就是打印以空格為分隔符的第一列(其實(shí)也只有一列,因?yàn)閜grep命令只輸出進(jìn)程的pid號;
那么
兩條指令的意思就是,查看名為python的進(jìn)程,把查到的第一個(gè)進(jìn)程的pid號賦值給Array[0],把第二個(gè)賦值給Array[1];
后面的判斷就是只要有進(jìn)程pid號,說明進(jìn)程存在,否則進(jìn)程不存在。
這句代碼的意思就是打開一個(gè)新的終端,執(zhí)行命令 ”python /home/mk90/Documents/restart_pro/test2.py“,執(zhí)行完畢后該終端保持存在不關(guān)閉。
gnome-terminal 是終端的一種,Ubuntu系統(tǒng)的終端就是這種版本, 參數(shù) -x 表示后面出現(xiàn)的都當(dāng)做命令執(zhí)行,并且只執(zhí)行一次;
bash 是防止終端立即關(guān)閉,如果輸入:
終端執(zhí)行后會(huì)一閃就關(guān)閉,甚至看不到執(zhí)行的效果;
"-c"選項(xiàng)使shell解釋器從一個(gè)字符串中而不是從一個(gè)文件中讀取并執(zhí)行shell命令;
exec bash 使終端運(yùn)行命令后仍然存在。
缺陷:
用這種方法有一個(gè)缺陷,就是需要知道會(huì)有幾個(gè)python程序以及它們的的順序;如果有兩個(gè)的話,操作第二個(gè)是正常的,可以重啟,但是如果第一個(gè)程序死了,也會(huì)重啟第二個(gè)程序!!!因?yàn)榈谝粋€(gè)進(jìn)程中斷之后,系統(tǒng)實(shí)時(shí)監(jiān)測,第二個(gè)進(jìn)程變成了最前面的也是唯一的python進(jìn)程,那么它認(rèn)為第一個(gè)程序還在運(yùn)行,而第二個(gè)程序停止了,所以會(huì)重啟第二個(gè)程序。
總結(jié);有什么問題和需要相關(guān)資料的都可以私信‘資料'兩字可MF領(lǐng)取相關(guān)資料,C++、linux,shell,Kali,
首先明白一個(gè)前提,我們是發(fā)現(xiàn)問題才會(huì)告警發(fā)郵件通知,那么當(dāng)告警腳本未加載時(shí),說名當(dāng)前監(jiān)控項(xiàng)正常。或者之前出現(xiàn)異常,但是已經(jīng)恢復(fù)。
腳本的目的是防止問題出現(xiàn),處于修復(fù)期的頻繁告警。我們可以定義一個(gè)時(shí)間閾值,一小時(shí)。比如距離上一次問題出現(xiàn),也就是距離上一次告警的時(shí)間大于一小時(shí),我們認(rèn)為就是一個(gè)新的異常,否則就是一個(gè)尚未解決的故障。
每次告警,我們都記錄一個(gè)絕對時(shí)間戳,當(dāng)下一次告警到來時(shí),用當(dāng)前時(shí)間戳減去上一次報(bào)警的時(shí)間戳,然后if判斷該差值,從而確定告警動(dòng)作。
在具體腳本中定義t2為上一次告警時(shí)間戳,t1為當(dāng)前時(shí)間戳,t1-t2就是我們要的判斷值。t1可以用命令直接獲取,t1=`date +%s` t2 要從日志中獲取。但是還有一個(gè)問題,對于第一次告警,該t2從哪里來了,也簡單,我們自己定義一個(gè)滿足新異常條件的時(shí)間戳就可以,比如兩小時(shí)之前。
對于一個(gè)已發(fā)現(xiàn)待解決的故障,也就是對應(yīng)上面時(shí)間戳差值小于一小時(shí)的情況,如果我們的腳本是一分鐘執(zhí)行一次,就可以做一個(gè)計(jì)數(shù)器,每發(fā)現(xiàn)一次,計(jì)數(shù)一次,當(dāng)計(jì)數(shù)器大于10時(shí),也就是異常持續(xù)了10分鐘,這時(shí)候發(fā)送郵件一次,同時(shí)清空計(jì)時(shí)器。
因?yàn)閙ail.py 腳本決定了發(fā)送郵件必須帶三個(gè)參數(shù),收件人郵箱,主題, 內(nèi)容。因此mail.sh 調(diào)用mail.py 必須傳遞給它三個(gè)參數(shù),那么這三個(gè)參數(shù)最終來自哪里呢,來自監(jiān)控項(xiàng)腳本,比如load.sh
傳遞順序?yàn)?load.sh---->mail.sh----->mail.py
再解釋mail.sh 第一行,log=$1 , 是一個(gè)變量賦值語句,此時(shí)的$1就是load.sh 傳遞過來的郵箱名稱。
在程序中我么看到后面將時(shí)間戳保存在了/tmp/$log 下面,該復(fù)制語句是為了給該日志文件取一個(gè)有意義的名稱,便于以后管理。當(dāng)然可以給出其他賦值,比如log=time.txt