2012年12月30日 星期日

Cacti JVM Monitoring template ( Part I )


在工作上其他的同事問我如何去查出 Java 程式中的 Thread ??
經由 google 可以查到 透過  JVM 的 SNMP 機制並結合 cacti 可做到這樣的監控功能.
Java snmp 的設定方式請參考下列 URL

http://docs.oracle.com/javase/6/docs/technotes/guides/management/snmp.html

重要詞彙:

Java Virtual Machine (JVM)
Java Management Extensions (JMX)
Remote Method Invocation (RMI)

以下為本 LAB 的設定方式:

[root@centos management]# pwd
/usr/java/jre/lib/management

[root@centos management]# ls -la
total 40
drwxr-xr-x  2 root root  4096 Dec 28 23:27 .
drwxr-xr-x 18 root root  4096 Dec 28 21:55 ..
-rw-r--r--  1 root root  3998 Nov 14 18:19 jmxremote.access
-r--r--r--  1 root root  2856 Nov 14 18:19 jmxremote.password.template
-rw-r--r--  1 root root 14097 Nov 14 18:19 management.properties
-r--------  1 root root  3355 Dec 28 23:16 snmp.acl
-r--r--r--  1 root root  3376 Nov 14 18:19 snmp.acl.template

[root@centos management]# cat snmp.acl
acl = {
  {
   communities = public
   access = read-only
   managers = localhost
  }
}


下方的 java profile 設定分為三段
(1)啟用 jvm  snmp  使用設定
(2)設定 jvm  RAM 使用設定
(3)啟用 jmx 使用設定 (透過 jconsole 去 monitor jvm )

[root@centos profile.d]# pwd
/etc/profile.d
[root@centos profile.d]# cat java.sh

JAVA_HOME=/usr/java

ANT_HOME=/usr/local/ant

CLASSPATH=.:$JAVA_HOME/lib/tools.jar:/usr/java/jre/lib/management-agent.jar:/usr/local/ant/lib/ant.jar

PATH=$JAVA_HOME/bin:$PATH:$ANT_HOME/bin

export JAVA_HOME CLASSPATH PATH ANT_HOME

export JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.snmp.port=1610 -Dcom.sun.management.snmp.acl.file=/usr/java/jre/lib/management/snmp.acl -Dcom.sun.management.snmp.interface=0.0.0.0 -Xms1024m -Xmx1024m  -XX:PermSize=128m -XX:MaxPermSize=256m -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=192.168.100.101 -Dcom.sun.management.jmxremote.port=9012 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

檢查 jvm snmp & jmx 是否正常 Listen

[root@centos snmp_queries]# netstat -anp | grep java
tcp        0      0 ::ffff:127.0.0.1:8005       :::*                        LISTEN      1477/java
tcp        0      0 :::50023                    :::*                        LISTEN      1477/java
tcp        0      0 :::8009                     :::*                        LISTEN      1477/java
tcp        0      0 :::8080                     :::*                        LISTEN      1477/java
tcp        0      0 :::49043                    :::*                        LISTEN      1477/java
tcp        0      0 :::9012                     :::*                        LISTEN      1477/java
udp        0      0 :::1610                     :::*                                    1477/java


驗證 snmp 的服務是否正常

[root@centos snmp_queries]#snmpwalk -v2c -c public localhost system

SNMPv2-MIB::sysDescr.0 = STRING: Linux centos 2.6.32-279.19.1.el6.i686 #1 SMP Wed Dec 19 04:30:58 UTC 2012 i686
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (117485) 0:19:34.85
SNMPv2-MIB::sysContact.0 = STRING: Root <root@localhost> (configure /etc/snmp/snmp.local.conf)
SNMPv2-MIB::sysName.0 = STRING: centos
SNMPv2-MIB::sysLocation.0 = STRING: Unknown (edit /etc/snmp/snmpd.conf)
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (6) 0:00:00.06
SNMPv2-MIB::sysORID.1 = OID: SNMP-MPD-MIB::snmpMPDMIBObjects.3.1.1
SNMPv2-MIB::sysORID.2 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORID.3 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.5 = OID: TCP-MIB::tcpMIB
SNMPv2-MIB::sysORID.6 = OID: IP-MIB::ip
SNMPv2-MIB::sysORID.7 = OID: UDP-MIB::udpMIB
SNMPv2-MIB::sysORID.8 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
SNMPv2-MIB::sysORDescr.1 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.3 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORUpTime.1 = Timeticks: (5) 0:00:00.05
SNMPv2-MIB::sysORUpTime.2 = Timeticks: (5) 0:00:00.05
SNMPv2-MIB::sysORUpTime.3 = Timeticks: (5) 0:00:00.05
SNMPv2-MIB::sysORUpTime.4 = Timeticks: (5) 0:00:00.05
SNMPv2-MIB::sysORUpTime.5 = Timeticks: (5) 0:00:00.05
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (5) 0:00:00.05
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (5) 0:00:00.05
SNMPv2-MIB::sysORUpTime.8 = Timeticks: (6) 0:00:00.06


[root@centos snmp_queries]#  snmpget -v2c -c public localhost SNMPv2-MIB::sysDescr.0

SNMPv2-MIB::sysDescr.0 = STRING: Linux centos 2.6.32-279.19.1.el6.i686 #1 SMP Wed Dec 19 04:30:58 UTC 2012 i686

[root@centos snmp_queries]#

JVM SNMP MIB 參考的 URL
http://ipmsupport.solarwinds.com/mibs/JVM-MANAGEMENT-MIB/oids.aspx
http://support.ipmonitor.com/mibs/JVM-MANAGEMENT-MIB/oids.aspx

JVM Thread Count MIB
1.3.6.1.4.1.42.2.145.3.163.1.1.3.1.0


透過使用 snmp proxy 的方式

[root@centos snmp_queries]#  snmpget -v2c -c public localhost 1.3.6.1.4.1.42.2.145.3.163.1.1.3.1.0

SNMPv2-SMI::enterprises.42.2.145.3.163.1.1.3.1.0 = Gauge32: 19

vi /etc/snmp/snmpd.conf
mibs +JVM-MANAGEMENT-MIB
proxy -v 2c -c public localhost:1610 .1.3.6.1.4.1.42

修改必須重啟 snmpd

不透過使用 snmp proxy 的方式

[root@centos snmp_queries]
#snmpget -v2c -c public localhost:1610 1.3.6.1.4.1.42.2.145.3.163.1.1.3.1.0

SNMPv2-SMI::enterprises.42.2.145.3.163.1.1.3.1.0 = Gauge32: 19


需修改 Data Templates snmp port 為 1610

Another JVM Monitoring template

http://forums.cacti.net/post-112268.html






修改 Data Templates snmp port 為 1610
jconsole test demo


jconsole test demo


cacti monitor 與 jconsole 實際運作時的對照如下




2012年12月22日 星期六

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


延續 rrdtool 用法與 cacti 設定對照( Part II )
http://xrcd2.blogspot.tw/2012/12/rrdtool-cacti-part-ii.html
經過前二篇的介紹我們已經知道 cacti & rrdtool 的設定方式(原理)
與 rrdtool 的關連性,接下來我要介紹的是如何利用既有 cacti 的
 rrd 檔,再轉成如 MRTG 般的圖示,
如下圖示我們可以透過 Cacti Turn On Graph Debug Mode 將 圖檔
的 rrdtool 構成語法,顯示在 WEB 上



rrdtool graph 產出語法如下:

/usr/bin/rrdtool graph - \
--imgformat=PNG \
--start=-86400 \
--end=-300 \
--title='cacti - Traffic - eth0' \
--rigid \
--base=1000 \
--height=120 \
--width=500 \
--alt-autoscale-max \
--lower-limit='0' \
--vertical-label='bits per second' \
--slope-mode \
--font TITLE:10: \
--font AXIS:7: \
--font LEGEND:8: \
--font UNIT:7: \
DEF:a="/var/www/html/cacti/rra/cacti_traffic_in_21.rrd":'traffic_in':AVERAGE \
DEF:b="/var/www/html/cacti/rra/cacti_traffic_in_21.rrd":'traffic_out':AVERAGE \
CDEF:cdefa='a,8,*' \
CDEF:cdefe='b,8,*' \
AREA:cdefa#00CF00FF:"Inbound"  \
GPRINT:cdefa:LAST:" Current\:%8.2lf %s"  \
GPRINT:cdefa:AVERAGE:"Average\:%8.2lf %s"  \
GPRINT:cdefa:MAX:"Maximum\:%8.2lf %s\n"  \
LINE1:cdefe#002A97FF:"Outbound"  \
GPRINT:cdefe:LAST:"Current\:%8.2lf %s"  \
GPRINT:cdefe:AVERAGE:"Average\:%8.2lf %s"  \
GPRINT:cdefe:MAX:"Maximum\:%8.2lf %s\n"   



接下來依樣 山寨 為  perl rrdtool 的語法,產出如 cacti 中的 web 圖示

#!/usr/bin/perl -w
use RRDs;
$rrd='/var/www/html/cacti/rra/cacti_traffic_in_21.rrd';
print "Start Creating Graph \n";
RRDs::graph "/var/www/html/eth0.png",
  "--imgformat","PNG",
  "--start", -86400,
  "--end", -300,
  "--title=cacti - Traffic - eth0",
  "--rigid",
  "--base=1000",
  "--height=120",
  "--width=500",
  "--alt-autoscale-max",
  "--lower-limit=0",
  "--vertical-label=bits per second",
  "--slope-mode",
  "--font","TITLE:10",
  "--font","AXIS:7",
  "--font","LEGEND:8:",
  "--font","UNIT:7",
  "DEF:a=$rrd:traffic_in:AVERAGE",
  "DEF:b=$rrd:traffic_out:AVERAGE",
  "CDEF:ab=a,8,\*",
  "CDEF:bb=b,8,\*",
  "AREA:ab#00FF00:Inbound ",
  "GPRINT:ab:LAST:Current\\:%8.2lf %s ",
  "GPRINT:ab:AVERAGE:avg\\:%8.2lf %s",
  "GPRINT:ab:MAX:max\\:%8.2lf %s \\n",
  "LINE:bb#0000FF:Outbound",
  "GPRINT:bb:LAST:Current\\:%8.2lf %s ",
  "GPRINT:bb:AVERAGE:avg\\:%8.2lf %s",
  "GPRINT:bb:MAX:max\\:%8.2lf %s \\n",
  "COMMENT:Designer XRCD2" ,
;
if ($ERROR = RRDs::error) {
   die "ERROR: $ERROR\n";
};
print "END \n";

















當然也可以按照自己的想法加以變化如



















或者


#!/usr/bin/perl -w
use RRDs;
$rrd='/var/www/html/cacti/rra/cacti_traffic_in_21.rrd';
print "Start Creating Graph \n";
RRDs::graph "/var/www/html/before4hour.png",
  "--imgformat","PNG",
  "--start", -14700, # 4*60*60+300 (換算成秒數的算法)
  "--end", -300,
  "--title=cacti - Traffic - eth0 (before4hour)",
  "--rigid",
  "--base=1000",
  "--height=120",
  "--width=500",
  "--alt-autoscale-max",
  "--lower-limit=0",
  "--vertical-label=bits per second",
  "--slope-mode",
  "--font","TITLE:10",
  "--font","AXIS:7",
  "--font","LEGEND:8:",
  "--font","UNIT:7",
  "DEF:a=$rrd:traffic_in:AVERAGE",
  "DEF:b=$rrd:traffic_out:AVERAGE",
  "CDEF:ab=a,8,\*",
  "CDEF:bb=b,8,\*",
  "AREA:ab#00FF00:Inbound ",
  "GPRINT:ab:LAST:Current\\:%8.2lf %s ",
  "GPRINT:ab:AVERAGE:avg\\:%8.2lf %s",
  "GPRINT:ab:MAX:max\\:%8.2lf %s \\n",
  "LINE:bb#0000FF:Outbound",
  "GPRINT:bb:LAST:Current\\:%8.2lf %s ",
  "GPRINT:bb:AVERAGE:avg\\:%8.2lf %s",
  "GPRINT:bb:MAX:max\\:%8.2lf %s \\n",
  "COMMENT:Designer XRCD2" ,
;
if ($ERROR = RRDs::error) {
   die "ERROR: $ERROR\n";
};
print "END \n";




再看一次 cacti rrdtool command





接下來就是自由變化的型態了,都已經變成圖檔了.要放在 web 變 mrtg 也行.
















( 山寨 mrtg 示意畫面)


















































或者是更進階的自動產出 E-Mail 報表也行 (如日報 週報 月報 季報 年報...)也行





上面圖示中的 自動產出 E-Mail 報表 郵件程式抄改自

http://search.cpan.org/~teddy/Mail-Builder-Simple-0.16/lib/Mail/Builder/Simple.pm

#/usr/bin/perl
use Mail::Builder::Simple;
$png=' <img src="cid:logo" alt="logo"> ';
$mail = Mail::Builder::Simple->new;
 $mail->image->add('/var/www/html/eth0.png', 'logo');
 $mail->send(
  mail_client => { mailer => 'SMTP' ,mailer_args => {host => 'smtp.server.ip.address'}},
  from => ['cacti@xrcd2.com.tw', 'My Name'],
  to => ['mis@xrcd2.com.tw', 'Your Name'],
  subject => 'The subject with UTF-8 chars',
  plaintext => "Hello,\n\nHow are you?\n\n",
  htmltext => "<h1>Hello,</h1> <p>How are you?</p><p> 報表在下面看看吧 <p><p> $png </p>",
  #attachment => 'file.pdf',
  #image => 'demo.png',
  priority => 1,
  mailer => 'My Mailer 0.01',
 );


當然我們也可以透過玩 CDEF 的運算去玩變形的花樣



                                                                        正常版
變形版



















正常版部份程式範列 ( perl )
print "Start Creating Graph \n";
RRDs::graph "/srv/www/htdocs/demo-v2.png",
  "--title=Traffic Demo V2",
  "--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",
  "COMMENT:\\n",
  "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",
  "COMMENT:\\n",
  "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 ",
  "HRULE:100000#FF0000: value > 100000  Warning",
  "COMMENT:\\n",
  "COMMENT:Last Updated $clock" ,
;
if ($ERROR = RRDs::error) {
   die "ERROR: $ERROR\n";
};
print "END \n";


變形版部份程式範列 ( perl )

print "Start Creating Graph \n";
RRDs::graph "/srv/www/htdocs/demo-v3.png",
  "--title=Traffic Demo V3",
  "--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,\*",
  "CDEF:bc=b,8,\*",
  "AREA:ab#99FF99: Traffic_In",
  "LINE:ab#00DD00:Peak",
  "COMMENT:\\n",
  "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",
  "AREA:bb#00E5EE: Traffic_Out",
  "LINE:bb#0000FF:Peak",
  "COMMENT:\\n",
  "GPRINT:bc:MIN: min\\: %8.2lf %s",
  "GPRINT:bc:AVERAGE: avg\\: %8.2lf %s",
  "GPRINT:bc:MAX: max\\:  %8.2lf %s",
  "GPRINT:bc:LAST: last\\: %8.2lf %s ",
  "HRULE:100000#FF0000: value > 100000  Warning",
  "COMMENT:\\n",
  "COMMENT:Last Updated $clock" ,
;
if ($ERROR = RRDs::error) {
   die "ERROR: $ERROR\n";
};
print "END \n";


透過這一篇的介紹,應該可以透過 DIY 的小程式,將線上運行中的 cacti 產出如
  mrtg 的網頁, 也可以 DIY 出 簡單網管 E-Mail 報表!

最後再想想透過連續這三篇介紹,將基礎打好,觀念搞清楚,再去玩 cacti 會更
了解一些,最簡單的說 cacti 只是用來簡化 rrdtool 的操作與設定.

但 cacti 的功能與強大之處,不是三言兩語可以說介紹完的. rrdtool 也是如此!
接下來如有時間我會再介紹 cacti 的 安裝.操作與使用....待續....

本 LAB 使用 cacti + rrdtool + perl + Mail 這四個要素.缺一不可.
Base on ( LAMP +P+R) 
Linux Apache Mysql PHP Perl rrdtool !

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


2012年11月30日 星期五

vlab 上多年Po文記念

說真的以往 Po 在 www.vlab.com.tw 上的網管文章,因為該網站消失而不見.
損失慘重,我在上面至少貢獻出不少網管專文.主要是以撰寫 網管 這個主題為核心.
目前我個人僅有保留,以往所撰寫過的Po文PDF檔.
希望有時間,可以將它再寫回目前這個 blog上.
 

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

http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html
rrdtool create filename [--start|-b start time]
                        [--step|-s step]
                        [--no-overwrite]
                        [DS:ds-name:DST:dst arguments]
                        [RRA:CF:cf arguments]

http://cuddletech.com/articles/rrd/ar01s02.html

建立RRD檔 
RRDtool 建檔語法再詳項分解
rrdtool create filename
                        [--start|-b start time]             
                        [--step|-s step]                     
                        [DS:ds-name:DST:heartbeat:min:max]
                        [RRA:CF:xff:steps:rows]


重要字彙說明:

DS Data Sources (Field)
DST Data Source Type (GAUGE, COUNTER, DERIVE, ABSOLUTE )
RRA Round Robin Archives (Format: RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows)
CF Consolidation Function (AVERAGE, MIN, MAX, LAST)
XFF Defines XFiles Factor
DEF Definitions

簡單來說透過 rrdtool 的工具,可以建立特定區間(TimeStamp)為X軸,
Data Source為圖示的Y軸的圖示.
而 Data Source 可經由預設或自訂的計算方式[CDEFs function],
提供Y軸數值的單位大小.最大值.最小值.平均值等的運算.

example (rrdtool 1.4.7 版提供的範例 )
http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.7.tar.gz

[root@centos63-test examples]# pwd
/usr/local/rrdtool/share/rrdtool/examples

[root@centos63-test examples]# cat minmax.pl
#!/usr/bin/perl
use lib qw( /usr/local/rrdtool/lib/perl );
use RRDs;
my $start=time;
my $rrd="randome.rrd";
my $name = $0;
$name =~ s/.*\///g;
$name =~ s/\.pl.*//g;
RRDs::create ($rrd, "--start",$start-1, "--step",300,
              "DS:a:GAUGE:600:U:U",
              "RRA:AVERAGE:0.5:1:300",
              "RRA:MIN:0.5:12:300",  
              "RRA:MAX:0.5:12:300",
);


my $ERROR = RRDs::error;
die "$0: unable to create `$rrd': $ERROR\n" if $ERROR;
# dropt some data into the rrd
my $t;
for ($t=$start; $t<$start+300*300; $t+=300){
  RRDs::update $rrd, "$t:".(sin($t/3000)*50+50);
  if ($ERROR = RRDs::error) {
    die "$0: unable to update `$rrd': $ERROR\n";
  }
}
RRDs::graph "$name.png",
  "--title", uc($name)." Demo",
  "--start", "now",
  "--end", "start+1d",
  "--lower-limit=0",
  "--interlace",
  "--imgformat","PNG",
  "--width=450",
  "DEF:a=$rrd:a:AVERAGE",
  "DEF:b=$rrd:a:MIN",
  "DEF:c=$rrd:a:MAX",
  "AREA:a#00b6e4:real",
  "LINE1:b#0022e9:min",
  "LINE1:c#00ee22:max",
;
if ($ERROR = RRDs::error) {
  die "ERROR: $ERROR\n";
};

print "This script has created $name.png in the current directory\n";
print "This demonstrates the use of MIN and MAX archives\n";

程式補充說明如下

#"--step",300, (300秒/5分鐘間隔區間)
#"RRA:AVERAGE:0.5:1:300",
#(XFF使用0.5,每隔五分鐘(1*5)存一次資料的平均值,資料保留300筆後自動覆蓋 [300 Rows])


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

抄改上述範例 1 用來簡單說明程式...

root@centos63-test perl]# cat ver1.pl
#!/usr/bin/perl
use RRDs;
$start=time;$rrd="random.rrd";
RRDs::create ($rrd, "--start",$start-1, "--step",1,
              "DS:a:GAUGE:12:U:U",
              "RRA:AVERAGE:0.5:1:12"
);
$ERROR = RRDs::error;
die "$0: unable to create `$rrd': $ERROR\n" if $ERROR;

for ($i=1;$i<=12;$i++){
 sleep 1;
 @time[$i] =time; $random_number = int(rand(9))+1;
 print "$i @time[$i] $random_number \n";
 RRDs::update $rrd,"@time[$i]:".$random_number.":".$i;
 if ($ERROR = RRDs::error) {
    die "$0: unable to update `$rrd': $ERROR\n";
 }
}

RRDs::graph "/var/www/html/1.png",
  "--title=Random_Number Demo",
  "--start", $start,
  "--end", $time[12],
  "--interlace",
  "--imgformat","PNG",
  "--width=500",
  "--height=120",
  "--vertical-label=value",
  "DEF:a=$rrd:a:AVERAGE",
  "AREA:a#FF0000:random_number",
  "GPRINT:a:MIN: min\\: %2.2lf",
  "GPRINT:a:AVERAGE: avg\\: %2.2lf",
  "GPRINT:a:MAX: max\\:  %2.2lf",
  "GPRINT:a:LAST: last\\: %2.2lf",
  "HRULE:8#0000FF: value > 8  Warning",
;
if ($ERROR = RRDs::error) {
  die "ERROR: $ERROR\n";
};

print "This script has created 1.png in the current directory\n";
print "This demonstrates the use of MIN and MAX archives\n";
[root@centos63-test perl]#

程式執行過程

[root@centos63-test perl]# perl ver1.pl
1 1354005047 6
2 1354005048 4
3 1354005049 1
4 1354005050 4
5 1354005051 9
6 1354005052 6
7 1354005053 3
8 1354005054 1
9 1354005055 6
10 1354005056 2
11 1354005057 5
12 1354005058 1
This script has created 1.png in the current directory
This demonstrates the use of MIN and MAX archives
[root@centos63-test perl]#

產出的圖型如下:
















範例 2 仿造 cacti 網路流量圖型 

[root@centos63-test perl]# cat traffic.pl
#!/usr/bin/perl
use RRDs;
$start=time;
$rrd="random.rrd";
RRDs::create ($rrd, "--start",$start-1, "--step",1,
              "DS:a:GAUGE:17:U:U",
              "DS:b:GAUGE:17:U:U",
              "RRA:AVERAGE:0.5:1:17"
);
$ERROR = RRDs::error;
die "$0: unable to create `$rrd': $ERROR\n" if $ERROR;

for ($i=1;$i<=17;$i++){
 sleep 1;
 @time[$i] =time;
 $random_number_a = int(rand(9))+1;
 $random_number_b = int(rand(9))+1;
 print "$i @time[$i] $random_number_a  $random_number_b \n";
 RRDs::update $rrd,"@time[$i]:".$random_number_a.":"."$random_number_b".":".$i;
 if ($ERROR = RRDs::error) {
    die "$0: unable to update `$rrd': $ERROR\n";
 }
}

RRDs::graph "/var/www/html/traffic.png",
  "--title=Random_Number Demo",
  "--start", $start,
  "--end", $time[17],
  "--interlace",
  "--imgformat","PNG",
  "--width=500",
  "--height=120",
  "--vertical-label=value",
  "DEF:a=$rrd:a:AVERAGE",
  "DEF:b=$rrd:b:AVERAGE",
  "AREA:a#00FF00:random_number_a",
  "GPRINT:a:MIN: min\\: %2.2lf",
  "GPRINT:a:AVERAGE: avg\\: %2.2lf",
  "GPRINT:a:MAX: max\\:  %2.2lf",
  "GPRINT:a:LAST: last\\: %2.2lf  ",
  "LINE:b#0000FF:random_number_b ",
  "GPRINT:b:MIN: min\\: %2.2lf",
  "GPRINT:b:AVERAGE: avg\\: %2.2lf",
  "GPRINT:b:MAX: max\\:  %2.2lf",
  "GPRINT:b:LAST: last\\: %2.2lf",
  "HRULE:8#FF0000: value > 8  Warning",
;
if ($ERROR = RRDs::error) {
  die "ERROR: $ERROR\n";
};

print "This script has created traffic.png in the current directory\n";
print "This demonstrates the use of MIN and MAX archives\n";

產出的圖型如下與 Traffic 對照:


最後仿造 cacti 以 每五分鐘 poller 一次 產出的圖型如下: ( 不滿 10 個小時 )



rrdtool 用法 與 cacti 設定對照


RRDtool Command ......

CF ....

Data Source ....

RRA ....




透過這一篇的介紹,我想說明的是 cacti 與 rrdtool 的重要繪圖技法及其關連性.
理論上要 DIY 出個人版的簡易網管程式應該是不難的.再配合snmpget的技法.
及其它 Alert 機制,如 MSN + SMS + E-Mail...配合那就是一套特製版的 
簡易型網管程式了.至少它應該擁有 MRTG 的水平還加上 Alert 機制! (哈)
但話又說回來,我還是會推薦大家使用 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

2012年11月23日 星期五

無法匯入 Cisco Interface Reliability Status Monitor.( 無法匯入 cacti Template )

依據 URL http://docs.cacti.net/howto:determine_cacti_template_version
How to determine a Cacti template version 一文中提及匯入(使用) cacti
官方論壇所下載的 Template,基於 cacti 版本不同可能導致某 Template 在匯入
時,出現 Error: XML: Hash version does not exist 的問題.

該問題出現的原因為該 Template hash_version_codes 不適用於當前的 cacti 版本.
舉例來說我在 cacti 0.8.8a 自行撰寫出的 Cisco Interface Reliability  Status Monitor.
( http://xrcd2.blogspot.tw/2012/11/cisco-router-interface-reliability.html or
http://forums.cacti.net/viewtopic.php?f=12&t=48912 )

相關的 Template ,在匯出相關檔案後,並不能在 cacti 0.8.7.g 匯入使用.
此時解法為在 cacti 運作的主機中.開啟 /cacti_dir/include/global_arrays.php
尋找 $hash_version_codes = array 的下方處,即可看到目前所使用的 cacti  hash
版本代碼,以 0.8.8 & 0.8.8.a 為例,"0.8.8"  => "0024","0.8.8a"  => "0024",
另依據該 URL 的說明:(如下)

Take the following example: <hash_040018258d1c9487a6c58dd804f4a012007664>
The first 2 digits are the type of the template.
The next 4 digits are the Cacti version it was created on.
The next 32 digits are a random number.

簡單的說.就是將要匯入的 Template 的 hash_xx"hash_version_codes"改成現行的
版本代碼即可.可使用慣用的編輯軟體,開該該 xml檔,並使用[尋找/取代]功能,
存檔後應使正常匯入才對!

利用修改 template XML hash code 的方式. 再行匯入 
Cisco Interface Reliability  Status Monitor Template 即可.
簡單的說 透過這個方式,可以避掉不同的 cacti 版本所制做的  Template
無法匯入的問題.


2012年11月16日 星期五

Cisco Router Interface Reliability Status Monitor ( DIY cacti template )


        延續 再論 SNMP OIDs http://xrcd2.blogspot.tw/2012/10/snmp-oid.html 這個主題,上次我已經提到如何將 Cisco Router Interface Reliability  加入 zabbix 的監控,這次我將同樣的SNMP OIDs 改成
cacti template 的方式,進行監控!

sample output



This will let you know reliability status of cisco router interface. (DIY the template)

Reference: http://forums.cacti.net/viewtopic.php?f=12&t=17722

vi /cacti_dir/resource/snmp_queries/interface.xml
                <ifReliability>
                        <name>Reliability</name>
                        <method>walk</method>
                        <source>value</source>
                        <direction>output</direction>
                        <oid>.1.3.6.1.4.1.9.2.2.1.1.22</oid>
                </ifReliability>

接下來就圖解說明:

 Create Data Templates

Create Graph Templates

Create Items



Create Data Queries
Create New Graphs
下圖為 Interface Reliability + Interface Status + Interface Traffic





以下的URL為本人自行製作的 template 使用前請務必先將
cacti_data_query_snmp_-_interface_statistics先行備份.

滙出方式 (略)

cacti/console/export templates/

滙入方式(略)

cacti/console/import templates/

cacti environment: Centos 6.3 + cacti 0.8.8.a

data_query:
 http://www.mason-arts.com/xrcd2/xml/cacti_data_query_snmp_-_interface_statistics_reliability.xml
data_template:
http://www.mason-arts.com/xrcd2/xml/cacti_data_template_interface_-_reliability.xml
graph_template:
http://www.mason-arts.com/xrcd2/xml/cacti_graph_template_interface_-_reliability.xml


上述的 Template 同步發表於 cacti 官方論壇內

http://forums.cacti.net/viewtopic.php?f=12&t=48912

reliability.zip http://forums.cacti.net/download/file.php?id=26813