RRDTools 教学 (三)
时间:2007-02-14 来源:evegl
6.4 Question: 如何抓 CISCO Switch(假設 24 port) 每個 port 流量呢 ?
6.4.1 方法一
CODE:
[Copy to clipboard]
# 先使用 mrtg 產生 cfg 檔
cfgmaker Community_String@Switch_or_Router_IP >; mrtg.cfg
再來修改 mrtg.cfg , 加入這三行,在最前面
CODE:
[Copy to clipboard]
# 表示使用 rrdtool 來做 data 的 log , 而不使用 log file
LogFormat: rrdtool
# rrdtool 所在路徑,如果你裝 rrdtool 的 prefix=/usr 那就是在 /usr/bin 下
PathAdd: /usr/bin/
# 自己找 RRDs.pm 在哪,如果 prefix=/usr 那大概就是在下面這個 path
LibAdd: /usr/lib/perl/
再來,只要跑 mrtg mrtg.cfg ,那 mrtg 就幫你建好 rrd 檔在 LogDir 內(一般同 WorkDir: ),
CODE:
[Copy to clipboard]
[root@log mrtg]# mrtg /etc/mrtg/mrtg.cfg
[root@log mrtg]# ls -la *.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_10.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_11.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_12.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_13.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_14.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_15.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_16.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_17.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_18.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_19.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_1.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_20.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_21.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_22.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_23.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_24.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_2.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_3.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_4.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_5.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_6.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_7.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_8.rrd
-rw-r--r-- 1 nobody users 84740 May 27 15:15 168.95.1.253_9.rrd
再來,我會百分之百建議到 http://my14all.sourceforge.net/ 抓 14all.cgi 來繪圖.
請辨明上述網站上的版本說明,14all.cgi 抓回來後要修改三個地方
CODE:
[Copy to clipboard]
#..前略
#if MRTG_lib.pm (from mrtg) is not in the module search path (@INC)
# uncomment the following line and change the path appropriatly:
# 修改這個,找你的 mrtg 的 lib 的路徑在哪裏,建議您將 mrtg 的 pm
# 皆 copy 到 perl modules 的所在目錄
use lib qw(MRTG_lib.pm);
# if RRDs (rrdtool perl module) is not in the module search path (@INC)
# uncomment the following line and change the path appropriatly
# or use a LibAdd: setting in the config file
# 這個是你的 rrdtool 的 RRDS.pm 所在路徑,與你現況不符需修改
use lib qw(/usr/local/rrdtool-1.0.38/lib/perl);
#中間略
### where the mrtg.cfg file is
# anywhere in the filespace
#$cfgfile = '/home/mrtg/mrtg.cfg';
# relative to the script
#$cfgfile = 'mrtg.cfg';
# use this so 14all.cgi gets the cfgfile name from the script name
# (14all.cgi ->; 14all.cfg)
# 修改這個對應到你的 mrtg.cfg
$cfgfile = '/etc/mrtg/mrtg.cfg';
# 後略
以上都修改完成後,將 14all.cgi 置於 mrtg 的 WorkDir 下,並請注意,14all.cgi 需
1. chmod 為 755
2. 對目錄有寫入權限
3. 且該目錄具有執行 CGI 功能 (Apache 中的 Options ExecCGI).
然後你就可以用 http://IP/WorkDir/14all.cgi 來看 mrtg+rrd 所畫出來的圖了.這是一個呈現的範例:
所以,您看是不是很簡單呢 ? (我是覺得 14all.cgi 很簡單且好用,您覺不覺得我就不知道了),用這種東
西有快速簡便的好處,就像用 CACTI 一樣簡單 (http://www.cacti.net/)
6.4.2 用自己寫的方法
建檔的方式就不在說明,上述的 mrtg 產生的 .rrd file 一個就 ds0 (in), 一個叫 ds1(out),所以我
們可以直接拿來使用,並使用 mrtg 會 collection 的 tool,而不用像前面 tcpdump 的例子自己寫
update 語法 (當然,你喜歡也可以囉)
CODE:
[Copy to clipboard]
[root@log mrtg]# rrdtool info 192.168.0.253_1.rrd
filename = "192.168.0.253_1.rrd"
rrd_version = "0001"
step = 300
last_update = 1117181102
ds[ds0].type = "COUNTER"
ds[ds0].minimal_heartbeat = 600
ds[ds0].min = 0.0000000000e+00
ds[ds0].max = 1.2500000000e+06
ds[ds0].last_ds = "3689202706"
ds[ds0].value = 1.0680042424e+05
ds[ds0].unknown_sec = 0
ds[ds1].type = "COUNTER"
ds[ds1].minimal_heartbeat = 600
ds[ds1].min = 0.0000000000e+00
ds[ds1].max = 1.2500000000e+06
ds[ds1].last_ds = "3880427199"
ds[ds1].value = 2.7916855892e+05
ds[ds1].unknown_sec = 0
#後略
我相信前面的 rrdtool create 介紹您有看懂,這裏一定不會有問題,有問題的話,請在從頭看起.
利用原來的東西畫圖
CODE:
[Copy to clipboard]
#!/bin/sh
INTERFACE=$1
RRDFILE="/www/htdocs/mrtg/192.168.0.253_$INTERFACE.rrd"
date_range="day week month year"
for t in $date_range
do
rrdtool graph /www/htdocs/mrtg/sample1_$t.png \
--title "Switch ($SWITCH) #$INTERFACE 流量" \
-s `date -d "-1 $t" +%s` \
DEF:in=$RRDFILE:ds0:AVERAGE \
DEF:out=$RRDFILE:ds1:AVERAGE \
COMMENT:"In/Out MAX AVG NOW \n" \
AREA:in#00ff00:"In ": \
GPRINT:in:MAX:"%10.0lf" \
GPRINT:in:AVERAGE:"%10.0lf" \
GPRINT:in:LAST:"%10.0lf\n" \
LINE2:out#0000ff:"Out": \
GPRINT:out:MAX:"%10.0lf" \
GPRINT:out:AVERAGE:"%10.0lf" \
GPRINT:out:LAST:"%10.0lf" \
-w 600 -h 150
done
畫出來的樣子:
如果只有這樣的功能,其實誰會想用呢?用 14all.cgi 就好了,不過再來我們看看其他的呈現方式囉,
CODE:
[Copy to clipboard]
#!/bin/sh
#一張圖上,圖出兩個 Interface 的流量
RRDFILE1="/www/htdocs/mrtg/192.168.0.253_14.rrd"
RRDFILE2="/www/htdocs/mrtg/192.168.0.253_15.rrd"
date_range="day week month year"
for t in $date_range
do
rrdtool graph /www/htdocs/snmp.enum.org.tw/images/sample2_$t.png \
--title "Switch #14/#15 INTERFACE 流量" \
-s `date -d "-1 $t" +%s` \
DEF:in1=$RRDFILE1:ds0:AVERAGE \
DEF:in2=$RRDFILE2:ds0:AVERAGE \
DEF:out1=$RRDFILE1:ds1:AVERAGE \
DEF:out2=$RRDFILE2:ds1:AVERAGE \
CDEF:n_out1=out1,-1,* \
CDEF:n_out2=out2,-1,* \
COMMENT:"In/Out MAX AVG NOW \n" \
AREA:in1#ff0000:"In14 ": \
GPRINT:in1:MAX:"%10.0lf" \
GPRINT:in1:AVERAGE:"%10.0lf" \
GPRINT:in1:LAST:"%10.0lf\n" \
STACK:in2#00ff00:"In15 ": \
GPRINT:in2:MAX:"%10.0lf" \
GPRINT:in2:AVERAGE:"%10.0lf" \
GPRINT:in2:LAST:"%10.0lf\n" \
AREA:n_out1#ff0000:"In14 ": \
GPRINT:out1:MAX:"%10.0lf" \
GPRINT:out1:AVERAGE:"%10.0lf" \
GPRINT:out1:LAST:"%10.0lf\n" \
STACK:n_out2#00ff00:"In15 ": \
GPRINT:out2:MAX:"%10.0lf" \
GPRINT:out2:AVERAGE:"%10.0lf" \
GPRINT:out2:LAST:"%10.0lf\n" \
-w 600 -h 150
done
以上用法主要著重在 CDEF,及 STACK 的應用, CDEF 將某些值轉成負數,以描繪出 in 在上(正值),out 在
下(負值),並以 AREA/STACK 將圖疊在一起,例如,如果您有兩個出口線路,就非常適合這種做法
結果:
所以,若你需要,可以堆疊出許多圖,也可以畫得很簡單,就看你的需要了.
6.5 描繪每部 DNS 的回應狀況
敝人專注於 DNS 之研究,所以回到老本行,我們看看如何來呈現此一問題
CODE:
[Copy to clipboard]
# rrdtool 建檔語法,您可以一部 DNS 建一個 rrd file , 也可以合在一起建
rrdtool create /root/study/dnsquery.rrd -s 60 \
DS:a:GAUGE:600:-100:10000 \
DS:b:GAUGE:600:-100:10000 \
DS:c:GAUGE:600:-100:10000 \
DS:d:GAUGE:600:-100:10000 \
DS:ns:GAUGE:600:-100:10000 \
DS:f:GAUGE:600:-100:10000 \
DS:g:GAUGE:600:-100:10000 \
RRA:AVERAGE:0.5:1:14400 \
RRA:AVERAGE:0.5:6:4800 \
RRA:AVERAGE:0.5:24:1200 \
RRA:AVERAGE:0.5:288:600 \
RRA:MAX:0.5:1:14400 \
RRA:MAX:0.5:6:4800 \
RRA:MAX:0.5:24:1200 \
RRA:MAX:0.5:288:600
取值及畫圖
CODE:
[Copy to clipboard]
#!/bin/sh
RRD_PATH="/root/study/dnsquery.rrd"
IMAGE_PATH="/www/htdocs/mrtg"
#DNS List
host="a.dns.tw b.dns.tw 61.220.48.1 d.dns.tw ns.twnic.net e.dns.tw f.dns.tw"
rrd_data=""
for dns in $host
do
#取得 dig 最後面的所顯示的查詢時間
msec=`/bin/dig @$dns . ns | grep 'Query time' | sed -e 's/.*: \(.*\) [a-z].*/\1/'`
if [ -z $msec ];then
msec=-100
echo "$dns ?#93;有回應,請您注意"| mail MyEmail -s "$dns 無回應"
fi
rrd_data="$rrd_data:$msec"
done
now=`date +%s`
echo $rrd_data
rrdtool update $RRD_PATH ${now}${rrd_data}
time="day week "
for t in $time
do
rrdtool graph $IMAGE_PATH/dnsquery-$t.jpg \
-t "DNS Query Response Time (${t}ly)" \
-w 600 -h 250 -s `date -d "-1 $t" +%s` -v "msec" -X b \
DEF:a=dnsquery.rrd:a:MAX \
DEF:b=dnsquery.rrd:b:MAX \
DEF:c=dnsquery.rrd:c:MAX \
DEF:d=dnsquery.rrd:d:MAX \
DEF:ns=dnsquery.rrd:ns:MAX \
DEF:f=dnsquery.rrd:f:MAX \
DEF:g=dnsquery.rrd:g:MAX \
CDEF:z0=-1,a,b,c,d,ns,f,g,+,+,+,+,+,+,7,/,* \
CDEF:a1=a,3000,+ \
CDEF:a11=3000,a,a,-,+ \
CDEF:b1=b,2500,+ \
CDEF:b11=2500,a,a,-,+ \
CDEF:c1=c,2000,+ \
CDEF:c11=2000,a,a,-,+ \
CDEF:d1=d,1500,+ \
CDEF:d11=1500,a,a,-,+ \
CDEF:ns1=ns,1000,+ \
CDEF:ns11=1000,a,a,-,+ \
CDEF:f1=f,500,+ \
CDEF:f11=500,a,a,-,+ \
CDEF:g1=g, \
AREA:z0#c0c0c0:"Average Response Time(msec)" \
COMMENT:"\n" \
AREA:a1#ff0000:"a.dns.tw" \
GPRINT:a:MAX:"%12.0lf" \
GPRINT:a:AVERAGE:"%12.0lf" \
GPRINT:a:MIN:"%12.0lf" \
GPRINT:a:LAST:"%12.0lf\n" \
AREA:a11#ffffff \
AREA:b1#800000:"b.dns.tw" \
GPRINT:b:MAX:"%12.0lf" \
GPRINT:b:AVERAGE:"%12.0lf" \
GPRINT:b:MIN:"%12.0lf" \
GPRINT:b:LAST:"%12.0lf\n" \
AREA:b11#ffffff \
AREA:c1#00ff00:"c.dns.tw" \
GPRINT:c:MAX:"%12.0lf" \
GPRINT:c:AVERAGE:"%12.0lf" \
GPRINT:c:MIN:"%12.0lf" \
GPRINT:c:LAST:"%12.0lf\n" \
AREA:c11#ffffff \
AREA:d1#008000:"d.dns.tw" \
GPRINT:d:MAX:"%12.0lf" \
GPRINT:d:AVERAGE:"%12.0lf" \
GPRINT:d:MIN:"%12.0lf" \
GPRINT:d:LAST:"%12.0lf\n" \
AREA:d11#ffffff \
AREA:ns1#0000ff:"ns.twnic.net" \
GPRINT:ns:MAX:"%8.0lf" \
GPRINT:ns:AVERAGE:"%12.0lf" \
GPRINT:ns:MIN:"%12.0lf" \
GPRINT:ns:LAST:"%12.0lf\n" \
AREA:ns11#ffffff \
AREA:f1#000080:"f.dns.tw" \
GPRINT:f:MAX:"%12.0lf" \
GPRINT:f:AVERAGE:"%12.0lf" \
GPRINT:f:MIN:"%12.0lf" \
GPRINT:f:LAST:"%12.0lf\n" \
AREA:f11#ffffff \
AREA:g1#ff8040:"g.dns.tw" \
GPRINT:g1:MAX:"%12.0lf" \
GPRINT:g1:AVERAGE:"%12.0lf" \
GPRINT:g1:MIN:"%12.0lf" \
GPRINT:g1:LAST:"%12.0lf\n" \
COMMENT:"note:<0 means no response\n"
done
這個做法很特別,你也可以轉化成像 ping 等的用法,CDEF 那一段主要在產生每個 HOST 有 500 的差距,
描繪原則即是,畫 a (這個值最大),以白色畫 3000 以下,意即去掉 AREA 3000 以下的部份,在 2500 上
畫 b, 再 2500 以下畫白色 (清除)....其他同理, 所以最後呈現每部主機的 DNS 查詢反應時間的結果,
程式稍複雜,但圖的觀感簡單清楚.
其他 DNS 部份,一般人關心是查詢或回應的狀況,若有心者可看一下這篇上的說明
http://bbs.chinaunix.net/forum/viewtopic.php?t=423629
此篇對許多 ISP 或 Domain Name 代管業者應有不少助益.
6.6 Apache Virtual Host 流量偵測
本例不用 mod_accounting ,因為其僅支援 1.3.x, 不過若您有心可以自己看看如何做,本例由 Demonbane
推薦的 mod_watch(http://www.snert.com/Software/mod_watch/index.shtml)來實現,安裝方法參考上述
網址(裝不起來不要問我哦).
CODE:
[Copy to clipboard]
#httpd.conf 部份內容
LoadModule watch_module modules/mod_watch.so
<IfModule mod_watch.c>;
<Location /watch-info>;
SetHandler watch-info
</Location>;
<Location /watch-table>;
SetHandler watch-table
</Location>;
</IfModule>;
VirtualDocumentRoot /www/htdocs/%0
VirtualScriptAlias /www/htdocs/%0/cgi-bin/
我們可以試以下列指令求得某一個 VH 的流量
CODE:
[Copy to clipboard]
[root@log study]# /usr/local/sbin/mod_watch.pl -f ifInOctets,ifOutOctets http://my_someone_virtual_host/watch-info
4538020
235836805
4.37
my_someone_virtual_host
這個東西到這邊巳經很明顯的是 mrtg 的輸出格式,所以你若了解的話基本上 mrtg 的作法就很簡單了
CODE:
[Copy to clipboard]
# 建檔 ,請多注意 $1 用意
#!/bin/sh
vh=$1
rrdtool create /root/study/mod_watch_$vh.rrd -s 300 \
DS:in:COUNTER:600:0:100000000 \
DS:out:COUNTER:600:0:100000000 \
DS:req:COUNTER:600:0:100000000 \
DS:doc:COUNTER:600:0:100000000 \
DS:gabege:COUNTER:600:0:1 \
RRA:AVERAGE:0.5:1:14400 \
RRA:AVERAGE:0.5:6:4800 \
RRA:AVERAGE:0.5:24:1200 \
RRA:AVERAGE:0.5:288:600 \
RRA:MAX:0.5:1:14400 \
RRA:MAX:0.5:6:4800 \
RRA:MAX:0.5:24:1200 \
RRA:MAX:0.5:288:600
CODE:
[Copy to clipboard]
#更新資料及畫圖
#!/bin/sh
vh=$1
RRDFILE=/root/study/mod_watch_$vh.rrd
IMAGE_PATH=/www/htdocs/211.72.210.251/images
now=`date +%s`
IN_OUT=`/usr/local/sbin/mod_watch.pl -f ifInOctets,ifOutOctets http://$1/watch-info| head -2 | tr '\n' ':'`
REQ_DOC=`/usr/local/sbin/mod_watch.pl -f ifRequests,ifDocuments http://$1/watch-info|head -2 | tr '\n' ':'`
rrdtool update $RRDFILE $now:${IN_OUT}${REQ_DOC}0
for t in day week month year
do
rrdtool graph $IMAGE_PATH/mod_watch_${vh}_${t}.png -t "mod_watch 範例" \
-s `date -d "-1 $t" +%s` \
DEF:in=$RRDFILE:in:AVERAGE \
DEF:out=$RRDFILE:out:AVERAGE \
DEF:req=$RRDFILE:req:AVERAGE \
DEF:doc=$RRDFILE:doc:AVERAGE \
AREA:in#00ff00:"流入 " \
GPRINT:in:MAX:"%12.0lf" \
GPRINT:in:AVERAGE:"%12.0lf" \
GPRINT:in:MIN:"%12.0lf" \
GPRINT:in:LAST:"%12.0lf\n" \
LINE1:out#0000ff:"流出 " \
GPRINT:out:MAX:"%12.0lf" \
GPRINT:out:AVERAGE:"%12.0lf" \
GPRINT:out:MIN:"%12.0lf" \
GPRINT:out:LAST:"%12.0lf\n" \
LINE1:req#ff0000:"Request " \
GPRINT:req:MAX:"%12.0lf" \
GPRINT:req:AVERAGE:"%12.0lf" \
GPRINT:req:MIN:"%12.0lf" \
GPRINT:req:LAST:"%12.0lf\n" \
LINE1:doc#800000:"Document" \
GPRINT:doc:MAX:"%12.0lf" \
GPRINT:doc:AVERAGE:"%12.0lf" \
GPRINT:doc:MIN:"%12.0lf" \
GPRINT:doc:LAST:"%12.0lf\n" \
-w 400 -h 100
done
結果
發現沒 ? 什麼問題呢 ? 仔細想想為什麼 Request/Document 值為 0 呢 !? 該如何解決.....
7. 結語
該說的前面都說了,想不想學 rrdtool 完全看你對系統的掌握度...本來是只介紹 rrdtool 的,不過想說
寫多點,就 mrtg/14all.cgi 寫多點了. mrtg/rrd/14all.cgi 摸熟, 對你會很有幫助...官網是一定要去
的地方,不要只看什麼教學文件..那很難學得透徹.
註: 看不到圖不能怪我...