2012年12月7日 星期五

rrdtool 用法與 cacti 設定對照 ( Part II )

延續 rrdtool 用法與 cacti 設定對照(Part I)
http://xrcd2.blogspot.tw/2012/11/rrdtool-cacti.html
簡單的說明關於 rrdtool 的使用方式(步驟).

(1)RRD檔案的產出,必需先經由 rrdtoo create filename.rrd ..
   過程產出 rrdtool的資料庫架構
(2)update RRD檔的資料,透過 rrdtool update filename.rrd ...
   方式將新增加的資料加入資料庫中.
(3)歷史軌跡的圖示資料,透過使用 rrdtool graph fileame.png ...
   將圖示產出.

Perl 範例程式

#!/usr/bin/perl -w
use RRDs;
$start=time;
$rrd="/srv/www/perl-lib/demo.rrd";
$log="/srv/www/perl-lib/demo.log";

#建立RRDs的基本資料庫的格式(只需執行一次即可)

print "Check RRD Files \n";
if(!(-e "$rrd")){
 print "start creating RRDs_Base \n";
 RRDs::create ($rrd, "--start",$start-1, "--step",300,
              "DS:a:COUNTER:600:U:U",
              "DS:b:COUNTER:600:U:U",
              "RRA:MIN:0.5:1:600",
              "RRA:MIN:0.5:6:700",
              "RRA:MIN:0.5:24:775",
              "RRA:MIN:0.5:288:797",
              "RRA:AVERAGE:0.5:1:600",
              "RRA:AVERAGE:0.5:6:700",
              "RRA:AVERAGE:0.5:24:775",
              "RRA:AVERAGE:0.5:288:797",
              "RRA:MAX:0.5:1:600",
              "RRA:MAX:0.5:6:700",
              "RRA:MAX:0.5:24:775",
              "RRA:MAX:0.5:288:797"
 );
 $ERROR = RRDs::error;
 die "$0: unable to create `$rrd': $ERROR\n" if $ERROR;
}

#當資料庫已存在的情況下,就開始新增歷史軌跡資料
# (不斷的累積該資料但受限RRDs的基本運作模式有一定存放筆數與循環)

else {
      print " RRDs File Exist \n";
      print " Update RRDs Data \n";
      $uptime=time;
      get_snmp_traffic();
      print "$uptime $traffic_in  $traffic_out \n";
      RRDs::update ("$rrd","$uptime:$traffic_in:$traffic_out");
      if ($ERROR = RRDs::error) {
         die "$0: unable to update `$rrd': $ERROR\n";
      }
}

#假設未建立RRDs檔,則歷史軌跡的圖示資料結束時間為現在時間加1,
#用於產出圖示時間區間用

if (!(-e "rrd")){
   $uptime=$start+1;
}

#產出圖示的 Last Updated 日期與時間資料

get_time();
print "Start_time $start \n";
print "Up_time $uptime \n";

#建立log檔,並將 TimeStamp 初始時間寫入log檔

if (!(-e "$log")){
 print "Write  RRDs time log file \n";
 open(write_log,"> $log");
 print write_log "$start";
 close(write_log);
}

#如果log檔案存在,就將 TimeStamp 初始時間讀出
if (-e "$log") {
  print "Open Log File\n";
  open (open_file,"$log");
  $start=<open_file>;
  close(open_file);
}
print "Start_time $start \n";
print "Up_time $uptime \n";

#建立圖示從log記錄時間直到當下時間.一直不間斷的繪製下去
#(受限RRDs的基本運作模式有一定存放筆數與循環)
#一般而言常見的類型為 每日.每週.每月.每年等等...有一定的圖示格式


print "Start Creating Graph \n";
RRDs::graph "/srv/www/htdocs/demo.png",
  "--title=Traffic Demo",
  "--start", $start,
  "--end", $uptime,
  "--interlace",
  "--imgformat","PNG",
  "--width=500",
  "--height=120",
  "--vertical-label=bps",
  "DEF:a=$rrd:a:AVERAGE",
  "DEF:b=$rrd:b:AVERAGE",
  "CDEF:ab=a,8,\*",
  "CDEF:bb=b,8,\*",
  "AREA:ab#00FF00: Traffic_In",
  "GPRINT:ab:MIN: min\\: %8.2lf %s",
  "GPRINT:ab:AVERAGE: avg\\: %8.2lf %s",
  "GPRINT:ab:MAX: max\\:  %8.2lf %s",
  "GPRINT:ab:LAST: last\\: %8.2lf %s",
  "LINE:bb#0000FF: Traffic_Out",
  "GPRINT:bb:MIN: min\\: %8.2lf %s",
  "GPRINT:bb:AVERAGE: avg\\: %8.2lf %s",
  "GPRINT:bb:MAX: max\\:  %8.2lf %s",
  "GPRINT:bb:LAST: last\\: %8.2lf %s",
  "COMMENT:\\n",
  "COMMENT:Last Updated $clock" ,
;
if ($ERROR = RRDs::error) {
   die "ERROR: $ERROR\n";
};
print "END \n";

#透過 snmpget 的方式將 eth0 的流量取出 (DS[Data Source]的資料來源)

sub get_snmp_traffic{
 use Net::SNMP;
 $traffic_eth0_in_oid = '1.3.6.1.2.1.2.2.1.10.2';
 $traffic_eth0_out_oid='1.3.6.1.2.1.2.2.1.16.2';
 ($session,$error) = Net::SNMP->session(Hostname => "localhost",Community => "public");
 die "session error: $error" unless ($session);
 $result_in = $session->get_request("$traffic_eth0_in_oid ");
 $result_out = $session->get_request("$traffic_eth0_out_oid ");
 die "request error: ".$session->error unless (defined $result_in);
 $session->close;
 $traffic_in=$result_in->{"$traffic_eth0_in_oid"};
 $traffic_out=$result_out->{"$traffic_eth0_out_oid"};
}

#將時間轉成 西元年月日 時:分:秒
sub get_time {
($sec,$min,$hour,$day,$mon,$year)=localtime(time);
$mon++;
if (length ($mon) == 1) {$mon = '0'.$mon;}
if (length ($day) == 1) {$day = '0'.$day;}
if (length ($hour) == 1) {$hour = '0'.$hour;}
if (length ($min) == 1) {$min = '0'.$min;}
if (length ($sec) == 1) {$sec = '0'.$sec;}
$year+=1900;
$clock="$year$mon$day $hour\\:$min\\:$sec";
}


每五分鐘執行一次即可

==============================================================

最後30分鐘的圖示產出程式範例

#!/usr/bin/perl -w
use RRDs;
$log="/srv/www/perl-lib/demo.log";
$rrd="/srv/www/perl-lib/demo.rrd";
print "Open Log File\n";
open (open_file,"$log");
$start=<open_file>;
close(open_file);
$now=time;
$start_date = localtime($start);
$begin=int($now-1800);#圖示開始時間:以30分鐘以前的時間取樣(1800秒)
$endtime=int($now+1);#圖示結束時間:現在時間+1的時間取樣
$begin_date= localtime($begin);
$end_date= localtime($endtime);
print " RRD記錄初始時間為 $start_date\n";
print "圖示記錄初始時間為 $begin_date\n";
print "圖示記錄結束時間為 $end_date\n";
print "Start_time $start \n";
print "Begin_time $begin \n";
print "   endtime $endtime \n";

get_time();
sleep 20;
print "Start Creating Graph \n";
RRDs::graph "/srv/www/htdocs/demo30min.png",
  "--title=Demo Traffic Last Half Hour ",
  "--start", $begin,
  "--end", $endtime,
  "--interlace",
  "--imgformat","PNG",
  "--width=500",
  "--height=120",
  "--vertical-label=bps",
  "DEF:a=$rrd:a:AVERAGE",
  "DEF:b=$rrd:b:AVERAGE",
  "CDEF:ab=a,8,\*",
  "CDEF:bb=b,8,\*",
  "AREA:ab#00FF00: Traffic_In   ",
  "GPRINT:ab:MIN: min\\: %8.2lf %s",
  "GPRINT:ab:AVERAGE: avg\\: %8.2lf %s",
  "GPRINT:ab:MAX: max\\:  %8.2lf %s",
  "GPRINT:ab:LAST: last\\: %8.2lf %s",
  "COMMENT:\\n",
  "LINE:bb#0000FF: Traffic_Out",
  "GPRINT:bb:MIN: min\\: %8.2lf %s",
  "GPRINT:bb:AVERAGE: avg\\: %8.2lf %s",
  "GPRINT:bb:MAX: max\\:  %8.2lf %s",
  "GPRINT:bb:LAST: last\\: %8.2lf %s",
  "COMMENT:\\n",
  "COMMENT:Last Updated $clock" ,
;
if ($ERROR = RRDs::error) {
   die "ERROR: $ERROR\n";
};
print "END \n";

sub get_time {
($sec,$min,$hour,$day,$mon,$year)=localtime(time);
$mon++;
if (length ($mon) == 1) {$mon = '0'.$mon;}
if (length ($day) == 1) {$day = '0'.$day;}
if (length ($hour) == 1) {$hour = '0'.$hour;}
if (length ($min) == 1) {$min = '0'.$min;}
if (length ($sec) == 1) {$sec = '0'.$sec;}
$year+=1900;
$clock="$year$mon$day $hour\\:$min\\:$sec";
}

每五分鐘執行一次即可  (30分鐘程式範列圖示如下)


=============================================
對照 cacti 程式作業分解

(1)選擇 DS(Data Source) 來源 (如某主機的網管流量)
(2)建立 rrd 資料庫
(3)更新歷史軌跡資料庫
(4)產出歷史軌跡的圖示

cacti 尚未建立 rrd 資料庫

 已建立 rrd 資料庫與圖示(但還沒有DS資料)

CDEFs



GPRINT


RRA



Data Source Type




Graph Traffic





cacti  [ Last Half Hour ] [DS資料來源為最後30分鐘的數據]



Perl code style  V.S cacti ( Perl 山寨版圖示 與 cacti 正版圖示    對照如下 )



其它圖示範例







區間對照表



未經 GPRINT 正規化(只顯示數值大小,沒自動換成以 K...為顯示單位)







透過這一篇的介紹,大家應該可以更清楚 cacti 的設定與 rrdtool 運用的關連性了吧!

DIY 的 簡易型網管程式  已經有 MRTG 的水平吧! (哈)

再次重申,我還是會推薦大家使用 OpenSource 的網管程式.如 cacti or  zabbix or opennms
Zenoss Core or Nagios

如果公司有錢的話.那就看看
HP OpenView or IBM Tivoli or Solarwinds or  WhatsUp or CiscoWorks .....
OpenSource 還是有一定的極限在...廢話不過也是實話....


關於 snmpget 的技法可參考下列文章
再論 SNMP OIDs
http://xrcd2.blogspot.tw/2012/10/snmp-oid.html
利用SNMP OIDs 加入 Zabbix 監控
http://xrcd2.blogspot.tw/2012/10/snmp-oids-zabbix.html

關於網管系統的建置可參考
Cacti + XSMS_API (SOAP) (自行客製化 Cacti + SMS )
http://xrcd2.blogspot.tw/2012/05/cacti-xsmsapi-soap-cacti-sms.html


沒有留言:

張貼留言