天天看點

監控cacti中的RRDtool用法詳解

 作為一個合格的運維工程師,監控技能必須是要掌握的,當然監控的軟體很多很多(cacti,nagios,zabbix...)。而生産環境中一般隻運用1、2種而已。是以全部掌握這些有點不靠譜。是以選擇其中一種掌握之即可,當工作環境變化後還可以以之為跳闆進行别的監控的學習。。。

 筆者不記得什麼時候收集的rrdtool的用法了,是以參考的位址也不能貼出來了。忘原作者看到相似的地方見諒。

 筆者老師為馬哥教育的馬老師。這篇文章也參考了其講課視訊。大家可以通過連結到馬哥那觀看其cacti視訊。

一、建立RRD資料庫(.rrd檔案)

rrdtool [options] command command_options

而commands包括:

create, update, updatev, graph, dump, restore,last, first, info, fetch, tune, resize, xport

這一講我們将着重介紹一下creat指令的使用

1

2

3

4

5

6

<code>rrdtool create filename</code>

<code>[--start|-b start time]</code>

<code>[--step|-s step]</code>

<code>[DS:ds-name:DST:heartbeat:min:max]</code>

<code>// DS:ds-name:GAUGE | COUNTER | DERIVE | ABSOLUTE:heartbeat:min:max</code>

<code>[RRA:CF:xff:steps:rows]</code>

我們用一個例子對整個文法進行解釋(以下都用這個例子說明參數的使用):

<code>rrdtool create target.rrd</code>

<code>--start </code><code>1023654125</code>

<code>--step </code><code>300</code>

<code>DS:mem:GAUGE:</code><code>600</code><code>:</code><code>0</code><code>:</code><code>671744</code>

<code>RRA:AVERAGE:</code><code>0.5</code><code>:</code><code>12</code><code>:</code><code>24</code>

<code>RRA:AVERAGE:</code><code>0.5</code><code>:</code><code>288</code><code>:</code><code>31</code>

簡單的先說吧:

create 很容易了解,就是建立一個新的Round Robin Database (RRD) 資料庫檔案以存儲資訊。

filename習慣上會以 .rrd 結尾,請記住這個資料庫檔案的名字。

--start 這個參數可以指定 filename 的資料記錄起始日期,你可以指定為 1970 年至今的秒數(參數為-b `date -d "1970/01/01" +%s`),如果你不指定,那麼起始時間預設就是現在。

--step 采集資料的間隔時間,習慣上我們會設 300 (秒),當然你可以自行調整,這也是RRD的優勢所在。但是采集周期不應該過短也不應小于你的update rrd檔案周期,否則可能會造成伺服器負載過重。

後面兩個參數需要慢慢了解,我把文法和例子拿下來對比一下,大家就可能明白了。

[DS:ds-name:DST:heartbeat:min:max]

// DS:ds-name:GAUGE | COUNTER | DERIVE | ABSOLUTE:heartbeat:min:max

對比例子

DS:mem:GAUGE:600:0:671744

下面以例子來說明:

DS:用來聲明資料源的,也可以了解為聲明資料變量的關鍵字。這個是必須寫的,不能按照你的意願修改成其他表述方式。

DS-NAME:變量名,可以了解為你給這個資料源起的助記符(簡稱DSN)。當每一個重新整理周期到來的時候,資料文檔中各變量對應的值就會被更新。這個變量對應的值在官方文檔中也叫做主要資料點――PDP(Primary Data Point)。

DST:DS的類型,通常有:GAUGE, COUNTER, DERIVE, 和ABSOLUTE 四種,下面依次介紹:

GAUGE:

我們用的最多的就是GAUGE了,它的中文解釋是:測量。在這裡它表示實際的值。比如說輸入次序為98 100 98,那麼輸出順序也是98 100 98。

COUNTER:

累計值,自己進行計算,比如說輸入次序為98 100 98,那麼輸出順序也是2 -2,怎麼出來的這兩個數值呢?100-98 98-100,其實就是兩個內插補點,它表示的是經過一個重新整理周期的變化率。

DERIVE:

也是累計值,和COUNTER一樣的,唯一不同的是它不存在負值,最小的是0,不如-2那麼它就隻劃0,結果為 2 0

ABSOLUTE:

如同COUNTER,但COUNTER可能overflow(數值過大),是以會取絕對值

補充:COUNTER/DERIVE/AVSOLVTE 雖然都是取內插補點,但會再除以兩次間隔間的秒數。

例,兩次間隔間為300秒,那畫出來的就是 2/300,-2/300 的值

再給出一個例子幫助大家了解:

Values = 300, 600, 900, 1200 實際值輸入值(每隔300S輸入一個)

Step = 300 seconds 重新整理周期

COUNTER DS = 1, 1, 1, 1 COUNTER定義的DS的值

DERIVE DS = 1, 1, 1, 1 DERIVE定義的DS的值

ABSOLUTE DS = 1, 2, 3, 4 ABSOLUTE定義的DS的值

GAUGE DS = 300, 600, 900, 1200 GAUGE定義的DS的值

heartbeat 心跳有效期

比如在例子中,我們定義了心跳有效時間是600秒,也就是兩個重新整理周期。舉個例子,在12點的時候沒有産生資料,那麼前後300S(共600S)的平均值就 會繪成12點的值,但如果在兩個重新整理周期内,都沒有接收到資料更新,那麼這個時候,必須往資料文檔中寫入一個(UN)UNKNOWN值。這是  RRDTool的一個特别的地方。要知道MRTG在處理網絡中斷的時候,記錄的是0值。這個0和UN還是有一定差別的。

min:max 記錄資料的最小值和最大值

DS數值的有效範圍,超出就是UN喽。也可以寫成 U:U 代表不限範圍。

小技巧:将資料源建立方式記為 "三文字,三數字"

DS講完了就該講RRA了,那麼什麼是RRA呢?

RRA: 更簡單,它的作用就是定義更新的資料是如何記錄的,RRA 即 Round Robin Archive,Archive是什麼,存檔。比如我們每5分鐘 産生一條重新整理的資料,那麼一個小時就是12條。每天就是288條。這麼龐大的資料量,一定不可能都存下來。肯定有一個合并(consolidate)資料 的方式,那麼這個就是RRA的作用了。

 下面具體介紹怎麼應用RRA:

使用方法:RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows

RRA:用以聲明RRAs的關鍵字

CF:consolidation function 合并方式,包含四類:

AVERAGE, MIN,MAX, LAST //平均值,最大值,最小值,最後一筆

上面說過了,經過一個重新整理周期,會獲得一個主資料點(PDP),将若幹個PDPs使用合并方式(CF)合并後會産生一個合并資料點CDP(consolidated data point)。

xff:xfiles factor 和unkown資料有關,很多資料都取0.5

step:有step條PDP合并形成一條CDP

row:記錄的合并資料點CDP條數

我們在例子中對RRA是這樣定義的:

RRA:AVERAGE:0.5:12:24 //1天

RRA:AVERAGE:0.5:288:31 //1月

對于第一個RRA,12條的PDP(每經過一個重新整理周期産生一個PDP)經過CFed(AVERAGE),也就是取平均值,産生一個CDP,24個  CDPs存檔。我們一起來計算一下時間,如果一個周期是300秒,那麼12個PDP的産生時間就是一個小時,也就是一個小時産生一個CDP。24個  CDPs時間就是一天。說明這條通過這條RRA,我們可以取得一天的資料值。一天後,又經過一個小時。就會産生第25條,那麼如何記錄這個第25條資料 呢?根據我們這個RRA的定義,它将會替代第一條CDP的位置。

執行個體(檢測某核心交換的端口)(create_nic_7609.sh)

/usr/local/rrd/bin/rrdtool create /www/rrd/NIC_7609.rrd -s 300 \

DS:ifInOctets1:COUNTER:600:U:U \

DS:ifInOctets2:COUNTER:600:U:U \

DS:ifInOctets9:COUNTER:600:U:U \

DS:ifInOctets11:COUNTER:600:U:U \

DS:ifInOctets14:COUNTER:600:U:U \

DS:ifInOctets53:COUNTER:600:U:U \

DS:ifOutOctets1:COUNTER:600:U:U \

DS:ifOutOctets2:COUNTER:600:U:U \

DS:ifOutOctets9:COUNTER:600:U:U \

DS:ifOutOctets11:COUNTER:600:U:U \

DS:ifOutOctets14:COUNTER:600:U:U \

DS:ifOutOctets53:COUNTER:600:U:U \

RRA:AVERAGE:0.5:1:4800 \

RRA:AVERAGE:0.5:6:2400 \

RRA:AVERAGE:0.5:24:1200 \

RRA:AVERAGE:0.5:288:600 \

RRA:MAX:0.5:1:4800 \

RRA:MAX:0.5:6:2400 \

RRA:MAX:0.5:24:1200 \

RRA:MAX:0.5:288:600

我們舉例來看

RRA:AVERAGE:0.5:1:603 \

RRA:AVERAGE:0.5:6:603 \

RRA:AVERAGE:0.5:24:603 \

RRA:AVERAGE:0.5:288:800 \

RRA:MAX:0.5:1:603 \

RRA:MAX:0.5:6:603 \

RRA:MAX:0.5:24:603 \

RRA:MAX:0.5:288:800

解釋一下,首先你要記得step我們設定為300秒,那麼

0.5:1:603

因為我們将step設定為300秒,若原計算時間點為12:00,記錄時11:57:30~12:02:30的平均值為主,這個值若在此時間點內隻有一筆資料的話,其意即是平均值,是以此一值即表共要記錄幾筆,603是指要存603筆,超過603筆,則最早一筆將被移出。

0.5:6:603 僅就6解釋,取6筆資料(每筆為step值,在此意即5分鐘)為平均值( 30 分鐘), 存 603 筆

0.5:24:603 24 即2小時

0.5:288:800 288 即1天

請注意,不是0.5:1:603中的1 就是五分鐘,這個是依據你的--step值而定,如果--step 3600,那0.5:6:603這一行就是六小 時合起來的平均值了。若将 AVERAGE 換成MIN/MAX 的意義則是取該時間點中 (如上例之5min/30min/2hr..)之最大值或最小 值,而通常在監測系統時最大值與平均值是比較有實際意義的。下面這個圖來幫助你記憶。

RRA:MIN:0.5:1:600 \

RRA:MIN:0.5:6:700 \

RRA:MIN:0.5:24:775 \

RRA:MIN:0.5:288:797 //一般可按cacti标準取值

第二講:rrd資料的更新(update)

在建立好文檔後,我們要用程式定時更新資料文檔(.rrd)然後才能根據資料文檔畫圖。以采集核心交換流量為例,首先我們要抓到各端口的流量,可以通過  snmp協定來取得資料。如果你機器上沒有snmp,那麼安裝最新的net-snmp包(PS:被監控端一般上安裝的是net-snmp, 監控端安裝的是net-snmp-utils,當然,如果你需要被監控端添加通知故障功能的話,也需要安裝net-snmp),安裝完成後測試snmp,在提示符下鍵入:

7

8

9

10

<code>$ snmpwalk</code>

<code>No hostname specified.</code>

<code>Usage: snmpwalk [options...] &lt;hostname&gt; {&lt;community&gt;} [&lt;objectID&gt;]</code>

<code>UCD-snmp version: </code><code>5.1</code><code>.</code><code>2</code>

<code>-h </code><code>this</code> <code>help message.</code>

<code>-H Display configuration file directives understood.</code>

<code>-V display version number.</code>

<code>-v </code><code>1</code><code>|2c|</code><code>3</code> <code>specifies snmp version to </code><code>use</code><code>.</code>

<code>SNMP Version </code><code>1</code> <code>or 2c specific</code>

<code>……</code>

出現以上資訊表示net-snmp安裝成功。

snmp的使用:

# snmpwalk -v 2c 核心交換IP位址 裝置的community_string OID

具體的snmp用法及系統預設的OID還有Shell檔案的執行方法可參考 cacti 中文論壇 的相關文檔,這裡我就不廢話了。我們這一講将主要說說如何更新rrd檔案資訊。

文法:

<code>rrdtool{update|updatev} filename [--template|-t ds-name[:ds-name]...] N|timestamp:value[:value...] at-timestamp@value[:value...] [timestamp:value[:value...] ...]</code>

例如:

$ rrdtool update tcpdump.rrd 1061811856:114:0:50:1199:0:821073

上面的 1061811856 即時間值,如果就是要現在的時間值,可以 N 代表,但要轉換成秒值,通常我們都會用

$ timestamp=`date +%s `

來轉現在秒數,如果是某些特定時間,則可以

$ timestamp=`date -d "2003/08/15 12:00" +%s`

後面跟着所有的更新的資料,按照DS定義的順序用冒号格開。

關于更新的資料需要你寫個小程式取資料,或用snmpget/snmpwalk抓資料來做rrdtool update,然後用crontab根據你在rrdtool create 時的step決定執行的時間點。這裡就應該用到shell的知識了,最常見的就是用Shell的正規表達式過濾通過 snmp取得的資訊

我們看到了,通過snmp取得的核心交換的資訊是非常之多的,這些資訊當然不可能都用到,我們要從中選取我們要的資訊。我們使用正規表達式對字元流進行過濾并排列成我們需要的方式。

對于正規表達式,這裡不做解釋,大家可以通過參考一些書輔助一些例子學習。

我們要取得的是端口的流入和流出的資料,是以我們使用snmp中的兩個選項:ifInOctets和ifOutOctets 。分别對應的是端口的流入流量和流出流量。

特别地,對于采集100M及其以下的端口流量,這兩個參數是完全正确的,但是如果是1000M的端口,就會出現流量和實際值相差甚遠。在查過很多資料後發 現,原因是這樣方式的計數模式,計數字長為32bit,如果采集1000M端口資料會發生資料溢出。我們要使用64bit的字長來計數。是以我們應該選用 的OID參數為:ifHCInOctets和ifHCOutOctets。

讓我們來看個例子

RRD_FILE=/www/rrd/NIC_7609.rrd (.rrd資料文檔的位置)

sec=300 //睡眠時間,也就是采集周期

while [ 1 ] //用一個循環

do

rrd_data="" //下面實際用到的是正規表達式的串拼接

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCInOctets |grep ".*ifHCInOctets.1 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCInOctets |grep ".*ifHCInOctets.2 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCInOctets |grep ".*ifHCInOctets.9 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCInOctets |grep ".*ifHCInOctets.11 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCInOctets |grep ".*ifHCInOctets.14 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCInOctets |grep ".*ifHCInOctets.53 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCOutOctets |grep ".*ifHCOutOctets.1 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCOutOctets |grep ".*ifHCOutOctets.2 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCOutOctets |grep ".*ifHCOutOctets.9 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCOutOctets |grep ".*ifHCOutOctets.11 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCOutOctets |grep ".*ifHCOutOctets.14 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' ':'`

rrd_data =$rrd_data`snmpwalk -v 2c IP位址 -c snmp團體名  ifHCOutOctets |grep ".*ifHCOutOctets.53 = " | sed -e 's/.*: \(.*\)$/\1/'| tr '\n' '\0'`

now=`date +%s` //目前時間距離1970的秒數

/usr/local/rrd/bin/rrdtool update $RRD_FILE $now:${rrd_data} //調用更新指令

sh ./NIC_7609_Graph.sh //調用繪圖腳本畫圖,下面一節就介紹

sleep $sec //休息,等待下一個周期的到來

done //循環體結束

[補充]如果你得到了如下提示:

IF-MIB::ifHCInOctets = No Such Object available on this agent at this OID

有可能你的網卡是100M,那麼就用ifOutOctets來測試就可以了。

rrdtool第三講:畫圖

畫圖的文法很多,我隻把最有用的列出來,有興趣的朋友可以到官方網站上去查Manual。

方法:rrdtool graph image-filename,參數介紹如下

image-filename:圖的檔案名,比如test.png等

[-s|--start seconds]:繪圖起始時間,預設是一天前(-1d),可用-s `date …`來指定時間

[-e|--end time]:繪圖結束時間, 預設是現在(now),除date 的應用外,可用 -e -1w 表示繪圖的時間結束于一周前

[-t|--title title]:圖上顯示的标題

[-v|--vertical-label text]:Y軸上的說明文字

[-w|--width pixels]:繪圖區域,畫圖區寬的大小

[-h|--height pixels]:繪圖區域,畫圖區高的大小

-u:Y軸正值高度

-l:Y軸負值高度

--no-minor 不要副格線

DEF(Define):就是定義一個變量

DEF:vname=rrd_filename:DS_name:CF

用如下表示更清楚一些

DEF:vname=rrd_filename:DS_name:[AVERAGE|MAX..]

主要用處在于您要取出哪個 RRD 檔案的 DSN 到這個 graph 來。

從上很容易看出,你要定義一個虛拟的變量,變量從(.rrd)資料檔案中取得資料源(DS)經過資料合并(CF)後的資料。看到這裡,大家應該知道,前面在定義文檔中為什麼有那麼多的參數,其實都是為了繪圖做準備的。

① vname:虛拟變量名,我們自己取的,以後還要用到。

② rrd_filename:DS_name:CF :資料檔案(.rrd)的全路徑-&gt;資料源變量-&gt;合并方法。

舉個例子吧:DEF:in_bytes_1=$RRD_PATH:ifInOctets1:AVERAGE

然而,我們覺得光有記錄的資料源變量還是不夠的,我們希望這些資料源變量可以計算。比如我希望把某兩個端口的流量加在一起作為一個變量畫圖,那麼這是我們就需要CDEF

CDEF 一個虛拟的變數,其值為 DEF 的某些運算,文法如下:

文法:CDEF:vname=rpn-expression

先舉一個例子,我們從例子中說明問題。我們取得某端口流入流量的位元組數,我們希望畫在圖上的是bit為機關,很明顯我們要将位元組數乘以8。

例:

DEF:in_bytes_1=$RRD_PATH:ifInOctets1:AVERAGE           //這句剛剛說過了

CDEF:in_bits_1= 8,in_bytes_1,*        //将DEF中定義的in_bytes_1×8放在in_bits_1

很好了解吧?那為什麼不寫成in_bits_1= in_bytes_1* 8?現在我們回到文法解釋:

rpn(Reverse Polish Notation)逆波蘭表達式,它的文法規定,表達式必須以逆波蘭表達式的方式給出。那麼什麼是逆波蘭表達式呢?逆波蘭表達式又叫做字尾表達式。哈哈google吧。

正常的表達式 逆波蘭表達式

a+b a,b,+

a+(b-c) a,b,c,-,+

a+(b-c)*d a,d,b,c,-,*,+

那麼a=1+3 就寫成 a=1,3 +了。

http=(smtp+http+telnet)/1024 寫成什麼呢?

http=1024,smtp,http,telnet,+,+,/

下面終于到畫圖了,最常用的是:線和區域。

從圖中可以看出有兩種表示流量的方式,流入用綠色的區域(AREA),流出用藍色的線(LINE)。這就是畫圖的幾個元素。我們還是先看一下文法。

AREA:vname[#rrggbb[:legend]]

LINE{1|2|3}:vname[#rrggbb[:legend]]

STACK:vname[#rrggbb[:legend]]

① vname:根據虛拟變量(vname)畫圖。

② #rrggbb:顔色的16進制表示,可以找個軟體來看。

③ legend:對該顔色的提示,最後會寫在圖上的。

④ 特别的,畫線有粗細之分,是以有LINE1-LINE3,line1最細,LINE3最粗。

⑤ AREA 可以畫出資料數值至0之間的區塊圖

⑥ STACK 是表現在的圖的值,疊在上一個值上

例子:

AREA:in_bits_1#00cc00: " Current In"

LINE1:out_bits_1#0000ff: " Current Out "

請注意,如果使用 AREA/STACK 則需特別注意圖蓋圖的問題,一定要先畫大的值, 再畫小的值,才會有層次的效果,不然,最大的資料若最後畫,你就看不到前面的值了,都被最後一個圖給壓過去了。

關于圖下面的提示怎麼畫呢?我們必須使用這兩條指令GPRINT和COMMENT

GPRINT:vname:CF:format

COMMENT:text

沒有什麼難點,有點像C語言的表達式,舉兩個例子大家就會很好了解的。例:

COMMENT: "Hello World .\c " 以居中的方式顯示Hello world

GPRINT:in_bits_1:AVERAGE:"Average Current\:%8.2lf %S bps"

//顯示in_bits_1的值,精确到小數點後面兩位

這些說明性文字都可以用 \n 等換行符号

例如:

GPRINT:telnet:AVERAGE:"%10.0lf \n"

意即要輸出這段時間中 (-s ~ -e 中,telnet的平均值,%10.0lf 則是為了好算位置)

例子1:

#tcpdump.sh

RRD_PATH="/root/study/tcpdump.rrd"

image_path="/root/study/html"

sec=300

killall tcpdump

mv ip.packet ip.packet.1

tcpdump -w ip.packet tcp or udp or icmp &amp;

scan_port="23 25 53 80 110"

rrd_data=""

for sport in $scan_port

port=`tcpdump -r ip.packet.1 port $sport -v | sed -e 's/.*, len \(.*\))/

\1/g' | tr '\n' '+'`

port=`echo ${port}0| bc`

port=`expr $port / $sec`

rrd_data="$rrd_data$port:"

done

total=`tcpdump -r ip.packet.1 -v |grep -v 'config'| sed -e 's/.*, len \(.*\))/\

1/g' | tr '\n' '+'`

total=` echo ${total}0 | bc`

now=`date +%s`

echo "rrdtool update tcpdump.rrd $now:$rrd_data$total" &gt;&gt;tcpdump.cmd

rrdtool update tcpdump.rrd $now:$rrd_data$total

image_path=/home/httpd/html/enum/study

now=`date "+%Y/%m/%d %H:%M:%S"`

start_time=`date -d "2003/08/12 19:00" +%s`

time="hour day week month year"

for t in $time

/usr/local/bin/rrdtool graph $image_path/example-$t.png \

--title "本機重要 port 流量" \

DEF:t1=$RRD_PATH:telnet:AVERAGE \

DEF:t2=$RRD_PATH:smtp:AVERAGE \

DEF:t3=$RRD_PATH:domain:AVERAGE \

DEF:t4=$RRD_PATH:http:AVERAGE \

DEF:t5=$RRD_PATH:total:AVERAGE \

CDEF:v1=t1,t2,t3,t4,+,+,+ \

CDEF:v2=t1,t2,t3,+,+ \

CDEF:v3=t1,t2,+ \

CDEF:v4=t1 \

CDEF:v5=t5,1024,/ \

COMMENT:"各 PORT 流量統計---最大------平均-------最小-------?#123;在\n" \

AREA:v1#339966:"HTTP" \

GPRINT:t4:MAX:" %12.0lf " \

GPRINT:t4:AVERAGE:"%12.0lf " \

GPRINT:t4:MIN:"%12.0lf " \

GPRINT:t4:LAST:"%12.0lf \n" \

AREA:v2#ffff00:"DNS" \

GPRINT:t3:MAX:" %12.0lf " \

GPRINT:t3:AVERAGE:"%12.0lf " \

GPRINT:t3:MIN:"%12.0lf " \

GPRINT:t3:LAST:"%12.0lf \n" \

AREA:v3#FF0000:"SMTP" \

GPRINT:t2:MAX:" %12.0lf " \

GPRINT:t2:AVERAGE:"%12.0lf " \

GPRINT:t2:MIN:"%12.0lf " \

GPRINT:t2:LAST:"%12.0lf \n" \

AREA:v4#0000ff:"TELNET" \

GPRINT:t1:MAX:" %12.0lf " \

GPRINT:t1:AVERAGE:"%12.0lf " \

GPRINT:t1:MIN:"%12.0lf " \

GPRINT:t1:LAST:"%12.0lf \n" \

LINE2:v5#000000:"全部(Kb)" \

GPRINT:v5:MAX:" %12.0lf " \

GPRINT:v5:AVERAGE:"%12.0lf " \

GPRINT:v5:MIN:"%12.0lf " \

GPRINT:v5:LAST:"%12.0lf \n" \

COMMENT:"\n" \

COMMENT:" Last Updated: $now" \

-v "per second (bytes)" -M -U 10 \

-Y -X b -h 200 -w 480 -s `date -d "-1 $t" +%s`

例子2(NIC_7609_Graph.sh):

繪圖的時候,我們還特别畫出了采集端口的日流量、周流量、月流量和年流量。配合Shell腳本的使用,可以達到很好的效果。

image_path=/www/web/nicimages

RRD_PATH=/www/rrd/FJNUNIC_7609.rrd

port="1 2 9 11 14 53" #端口清單

for p in $port #對每個端口的循環

DEFin="DEF:in_bytes_$p=$RRD_PATH:ifInOctets$p:AVERAGE"

DEFout="DEF:out_bytes_$p=$RRD_PATH:ifOutOctets$p:AVERAGE"

CDEF="CDEF:in_bits_$p=8,in_bytes_$p,* CDEF:out_bits_$p=8,out_bytes_$p,*"

ddate=`date` #取得目前日期

#以下流入

DRAW_IN="COMMENT:\"Last updated time : $ddate\c\"" #最後更新

DRAW_IN="${DRAW_IN} COMMENT:\"\n\"" #換行

DRAW_IN="${DRAW_IN} AREA:in_bits_$p#00cc00:\" Current In \n\" " #流入流量

DRAW_IN="${DRAW_IN} COMMENT:\" \" GPRINT:in_bits_$p:LAST:\"Last Current\:%.2lf%S bps\"" #流入目前流量文字提示

DRAW_IN="${DRAW_IN}GPRINT:in_bits_$p:AVERAGE:\"Average Current\:%.2lf%S bps\"" #流入平均流量文字提示

DRAW_IN="${DRAW_IN} GPRINT:in_bits_$p:MAX:\"Max Current\:%.2lf%S bps\n\""

#流入最大流量文字提示

#以下流出

DRAW_OUT="LINE1:out_bits_$p#0000ff:\" Current Out\n\" " #流出流量

DRAW_OUT="${DRAW_OUT}COMMENT:\" \" GPRINT:out_bits_$p:LAST:\"Last Current\:%.2lf%S bps\"" #流出目前流量文字提示

DRAW_OUT="${DRAW_OUT}GPRINT:out_bits_$p:AVERAGE:\"Average Current\:%.2lf%S bps\"" #流出平均流量文字提示

DRAW_OUT="${DRAW_OUT} GPRINT:out_bits_$p:MAX:\"Max Current\:%.2lf%S bps\n\"" #流出最大流量文字提示

ttime="d w m y" #時間清單;d日;w周;m月;y年

for t in $ttime #對每個時間循環

sec=`date -v-1$t +%s` #繪圖起始時間的确定

cmd="/usr/local/rrd/bin/rrdtool graph \

$image_path/FJNUNIC_7609_IF${p}_${t}.png \

--title '${ttitle}' \

-v ' Bits Per Second' \

-s $sec \

-l 0 -h 150 -w 500 $DEFin $DEFout $CDEF $DRAW_IN $DRAW_OUT

--color CANVAS#ffffff

--color BACK#ffffff \

--color FONT#000000 \

--color MGRID#80C080 \

--color GRID#808020 \

--color FRAME#808080 \

--color ARROW#ff0000 \

--color SHADEA#404040 \

--color SHADEB#404040"

eval $cmd # 執行畫圖

done #時間循環結束

done #端口循環結束

本文轉自 陳延宗 51CTO部落格,原文連結:http://blog.51cto.com/407711169/1222898,如需轉載請自行聯系原作者