zabbix自動發現佔用記憶體最大top10程序並監控資源
背景
相信每一位運維人員手裡都掌握著不少的伺服器,少則幾十臺,多則成百上千,線上伺服器跑的服務五花八門,每臺伺服器資源消耗都不同,如果能夠對資源消耗較高的程序實現自動發現監控將對排查問題有很大的幫助。
實現
匯出資料
在zabbix客戶端下新建一個專門存放指令碼的資料夾,新建一個指令碼檔案top.sh。
mkdir -p /opt/zabbix_agent/scripts
vi top.sh
使用 top 命令獲取伺服器當前執行狀態,將結果重定向到一個文字檔案中。
- cat top.sh
#!/bin/sh
top -n -b 1 > /tmp/top.txt
注: 該命令的意思是執行一次top命令並將結果重定向到top.txt檔案中去
建立定時任務
將該命令新增到zabbix使用者的計劃任務中去,每分鐘執行一次並清空,使文字中保證一份資料。
crontab -e
*/1 * * * * /opt/zabbix_agent/scripts/top.sh > /dev/null
放進去之後在tmp目錄下會生成一個top.txt檔案
- head -10 /tmp/top.txt
獲取程序名
獲取到資料後,對資料進行處理,獲取佔用資源高的程序名
- cat check_process.sh
#!/bin/bash
TABLESPACE=`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$6}END{for(k in a)print a[k]/1024,k}'|sort -gr|head -10|cut -d" " -f2`
COUNT=`echo "$TABLESPACE" |wc -l`
INDEX=0
echo '{"data":['
echo "$TABLESPACE" | while read LINE; do
echo -n '{"{#PROCESSNAME}":"'$LINE'"}'
INDEX=`expr $INDEX + 1`
if [ $INDEX -lt $COUNT ]; then
echo ','
fi
done
echo ']}'
注: 最關鍵的是tail -n +8 /tmp/top.txt|awk ‘{a[
NF]+= 6}END{for(k in a)print a[k]/1024,k}’|sort -gr|head -10|cut -d” ” -f2這條命令:這條命令的意思是從top.txt檔案中取出從第八行到末尾行的資料,然後使用awk對這些資料進行累加,效果是以最後一列為關鍵字,每個關鍵字對應的第6列的數值進行累加,輸出第六列資料的累加結果和最後一列資料,然後使用sort進行排序,注意這裡的引數是使用-gr而不是使用-nr是因為獲取到的第六列的值是以KB為單位的,假如某程序佔用記憶體大於10G的話,將會使用科學記數法計數,sort -nr引數無法對科學記數法進行計數,需要將引數改成-gr才行,其中的-r是進行反向排序,同時為了防止zabbix獲取到該值是科學記數法獲取的值從而無法識別,先將該值/1024將單位變成MB,當zabbix獲取到資料後再*1024*1024將該值還原成BYTE單位。head -10是取出佔用記憶體最大的十個程序,然後使用cut對資料進行切分,獲得十個程序的程序名。
將獲取到的十個程序名進行json格式化的輸出,輸出結果如下:
# ./check_process.sh
{"data":[
{"{#PROCESSNAME}":"httpd"},
{"{#PROCESSNAME}":"sshd"},
{"{#PROCESSNAME}":"zabbix_agentd"},
{"{#PROCESSNAME}":"sftp-server"},
{"{#PROCESSNAME}":"bash"},
{"{#PROCESSNAME}":"gpk-update-icon"},
{"{#PROCESSNAME}":"clock-applet"},
{"{#PROCESSNAME}":"crond"},
{"{#PROCESSNAME}":"vmtoolsd"},
{"{#PROCESSNAME}":"dbus-daemon"}]}
注:本例是以 RES 作為標準衡量資源消耗,可通過其他指標來監控。
獲取資源消耗
獲取某個程序佔用的cpu和記憶體資源情況
$ cat process_monitor.sh
#!/bin/sh
process=$1
name=$2
case $2 in
mem)
echo "`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$6}END{for(k in a)print a[k]/1024,k}'|grep "$process"|cut -d" " -f1`"
;;
cpu)
echo "`tail -n +8 /tmp/top.txt|awk '{a[$NF]+=$9}END{for(k in a)print a[k],k}'|grep "$process"|cut -d" " -f1`"
;;
*)
echo "Error input:"
;;
esac
exit 0
在本地測試一下取值:
$ sh ./scripts/processmonitor.sh httpd mem
20.0977
$ sh ./scripts/processmonitor.sh httpd cpu
0
能獲取到值了之後就需要在zabbix_agentd.conf裡面配置相應的鍵值來獲取資料了,下面是需要新增的配置:
$ tail -3 zabbix_agentd.conf
#top_process
UserParameter=process.discovery,/opt/zabbix_agent/scripts/check_process.sh
UserParameter=process.resource[*],/opt/zabbix_agent/scripts/process_monitor.sh $1 $2
新增該配置之後需要重啟zabbix_agentd才能使配置生效,在服務端驗證是否能夠獲取到資料了,在服務端使用zabbix_get命令來獲取資料,下面是執行的結果:
$ /usr/local/zabbix/bin/zabbix_get -s xxx.xxx.xxx.xxx -k "process.discovery"
{"data":[
{"{#PROCESSNAME}":"httpd"},
{"{#PROCESSNAME}":"sshd"},
{"{#PROCESSNAME}":"zabbix_agentd"},
{"{#PROCESSNAME}":"sftp-server"},
{"{#PROCESSNAME}":"bash"},
{"{#PROCESSNAME}":"gpk-update-icon"},
{"{#PROCESSNAME}":"clock-applet"},
{"{#PROCESSNAME}":"crond"},
{"{#PROCESSNAME}":"vmtoolsd"},
{"{#PROCESSNAME}":"dbus-daemon"}]}
上面的xxx.xxx.xxx.xxx代表的是客戶端的IP地址,-k後面的引數就是剛剛我們在客戶端上面新增的引數
$ /usr/local/zabbix/bin/zabbix_get -s xxx.xxx.xxx.xxx -k "process.resource[httpd,mem]"
20.125
$ /usr/local/zabbix/bin/zabbix_get -s xxx.xxx.xxx.xxx -k"process.resource[httpd,cpu]"
0
建立模板
在服務端測試客戶端取值沒有問題。接下來就需要在web端配置模板了。在組態—》模板—》建立模板裡面建立一個模板,叫做Temple Top Process如下圖所示:
建立一個應用集叫做top of process resource,如下圖所示:
建立好後,需要新增探索規則了,新建探索規則,如下圖所示:
其中的鍵值就是我們在客戶端上面配置的鍵值,資料更新間隔我這裡設定為1分鐘,就是說每間隔1分鐘它就會去客戶端獲取佔用記憶體最大的十個程序,可以根據需求自己設定,然後取它們的記憶體和cpu佔用資源資料。下面就需要配置專案原型了,如下圖所示:
如上圖所示,{#PROCESSNAME}獲取的就是十個資源消耗高的程序,process.resource[{#PROCESSNAME},mem]就是我們在客戶端配置的鍵值,其中獲取的記憶體數值單位是MB,這裡將它轉換成BYTE單位,所以將獲取到的數值*1024*1024=1048576,單位改成Byte,將該專案應用到top of process resource應用集上。這樣,一個專案原型就做成功了。下面是cpu佔用資源的專案原型配置:
新增完專案原型後需要配置圖形原型,如下圖所示:
新增好圖形原形後,該模版就製作成功了,接下來將該模板新增到主機上,就能夠獲取到資料了,這裡因為我設定的自動發現時間間隔是1分鐘,在生產環境中建議將自動發現間隔改為3600秒。
注:本次監控還存在不完善的地方,如以 RES 為標準是否合理,獲取所需資源時,如果兩個程序包含相同的欄位會報錯。
致謝
感謝gerfw
提供的思路。