I came up with this simple script to monitor my WAN links, and to notify me when a link goes down, and when it is available again. It does this by connecting to a port of a remote router. If the router responds, the link is alive. This script can be extended to support servers as well.
The script was tested on AIX 4.3.3 and ActiveState Perl for Windows on Windows 2000 server.
The data file is a text file, containing site information, and an IP address. They are seperated with the pipe symbol.
SITE-A|192.168.1.1 SITE-B|10.1.1.1
data=data.txt port=23 sleep=120 systemlog=system.log historylog=history.log statustxt=status.txt statushtml=c:\status.htm title=My own network monitor external=mailit.bat
The ini file is straight forward: which data file to use, which port to connect to, how long to sleep between intervals, the system log file name, the history log file name, the status log file name, the output HTML file name, a title, and the external application to call when the status changes.
One thing worth noting, is that all files will be stored in the local directory, all except the statushtml file, which have to be specified absolutely.
The external application will be called with the site, IP and status as parameters. You may use these in your email applications, etc.
Run the script as a daemon on Unix, or load it as a service with FireDaemon on Windows.
#!/usr/bin/perl use IO::Socket; $slash = &getslash; $curdir = substr($0,0,rindex($0,$slash)+1); if($curdir eq "") { $curdir = ".$slash"; } $ini = "siteping.ini"; open(INI,"$curdir$ini"); foreach $i (<INI>) { chomp($i); ($v,$a) = split(/\=/,$i); $inih{$v} = $a; } close INI; #====================================================== $data = $inih{data}; $port = $inih{port}; $sleep = $inih{sleep}; $systemlog = $inih{systemlog}; $historylog = $inih{historylog}; $statustxt = $inih{statustxt}; $statushtml = $inih{statushtml}; $title = $inih{title}; $external = $inih{external}; #====================================================== open(DAT,"$curdir$data"); foreach $i (<DAT>) { chomp($i); ($site,$ip) = split(/\|/,$i); $hashsite{$site} = $ip; $currentstatus{$site} = "Ok!"; } close DAT; while(1) { unlink "$curdir$systemlog"; &log("Starting scanning","$systemlog"); foreach $site (sort keys %hashsite) { $host = $hashsite{$site}; $alive = &check_port($host,$port); if($alive == 1) { $status = "Ok!"; } else { $status = "FAILED!!"; $error = 1; } &log("$site = $status","$systemlog"); if($currentstatus{$site} ne $status) { &log("$site => $status","$historylog"); `$external $site $host $status`; } $currentstatus{$site} = $status; } #write realtime status files #============================ $time = localtime(time); open(STATUS,">$curdir$statustxt"); print STATUS "$time\n"; foreach $site (sort keys %hashsite) { $status = $currentstatus{$site}; print STATUS "$site=$status\n"; } close STATUS; #write html file from status file #=================================== open(STATUS,"$curdir$statustxt"); open(HTML,">$statushtml"); print HTML "<html><title>$title</title><h1>$title</h1><meta HTTP-E +QUIV=\"Refresh\" CONTENT=\"$sleep;\">\n"; print HTML &style; print HTML <<HTML; <table border=1> HTML ; $date = <STATUS>; foreach $l (<STATUS>) { chomp($l); ($site,$status) = split(/\=/,$l); if($status eq "Ok!") { $st = &htmlcell($status,"GREEN"); } else { $st = &htmlcell($status,"RED"); } print HTML "<tr><th>$site</th>$st</tr>\n"; } print HTML "</table>\n"; $d = &timeformat(time,"dd MMM YYYY hh:mm:ss"); print HTML "<hr><i>Last updated on $d, and will refresh in $sl +eep seconds</i></html>"; close STATUS; close HTML; &log("Sleeping for $sleep seconds","$systemlog"); sleep($sleep); } #===================================================================== +============ sub log { $txt = $_[0]; $file = $_[1]; $time = localtime(time); open(FOO,">>$curdir$file"); print FOO "$time $txt\n"; close FOO; } ################################################# # Get name or IP, do lookup ################################################# sub name { my ($host) = @_; ($name,$alias,$addrtype,$length,$new_addr) = gethostbyaddr(inet_aton($host),AF_INET); $ipaddr = inet_ntoa(scalar($new_addr)); return $ipaddr; } ################################################# # Check to see if a port is open ################################################# sub check_port { my ($host,$port) = @_; $remote = IO::Socket::INET -> new ( Proto => "tcp", PeerAddr => $host, PeerPort => $port ) ; if ($remote) { close $remote; return 1; } else { return 0; } } sub cl2 { local $cl_var = $ARGV[$_[0]]; local $cl_default = $_[1]; if($cl_var eq "") { $cl_var = $cl_default; } return $cl_var; } sub cl { ################################################################## +################### # CL ################################################################## +################### # Input 0 : Command line variable (0,1,2,3, etc) # Input 1 : Default text to display (if the command line var is bl +ank) # Input 2 : Default answer to the question # # Similar to the ASK procedure, except this proc reads from the co +mmand line, eg. # # $myvar = &cl(0,"What is your name","Bob"); # ################################################################## +################### local $cl_var = $ARGV[$_[0]]; local $cl_txt = $_[1]; local $cl_default = $_[2]; if($cl_var eq "") { $cl_var = &ask($cl_txt,$cl_default); } return $cl_var; } sub ask { ################################################################## +################### # ASK ################################################################## +################### # Input 0 : Message to display # Input 1 : Default answer # # This procedure works a lot like the input keyword in BASIC. You + can specify # a default answer to the question, eg. # # $myvar = &ask("What is your name","Bob"); # ################################################################## +################### local $ask_msg = $_[0]; local $ask_default = $_[1]; if($ask_default eq "") { $ask_ifdefault = ""; } else { $ask_ifdefault = " [$ask_default] "; } local $ask_val = ""; while($ask_val eq "") { print "$ask_msg$ask_ifdefault --> "; $ask_val = <STDIN>; chomp($ask_val); if($ask_val eq "") { $ask_val = $ask_default; } } return $ask_val; } sub getslash { $r = $ENV{PATH}; if(index($r,"\\") != -1) { return "\\"; } if(index($r,"/") != -1) { return "/"; } return "UNKNOWN"; } sub style { return <<END; <style> .parent {font-family: Verdana; font-size: 8pt; margin-top: 5; text-indent: 0; margin-left: 0; cursor: hand;} .child {font-family: Verdana; font-size: 8pt; margin-left: 10; margin-bottom:20; font-weight: normal;} .image {} BODY { BACKGROUND-COLOR : white; COLOR : black; FONT-FAMILY : verdana, arial; FONT-SIZE : 8pt; } H1 { COLOR : #000363; FONT-SIZE : 14pt; font-family : Verdana; border-style : solid; border-color : #000363; border-width : 0pt; border-bottom-width : 1pt; font-weight : bold; } H2 { COLOR : #000363; FONT-SIZE : 13pt; font-weight : bold; font-family : Verdana, arial; } H5 { COLOR : #000363; FONT-SIZE : 9pt; font-family : Verdana, arial; } H6 { COLOR : #000363; FONT-SIZE : 8pt; font-family : Verdana, arial; } P { COLOR : black; FONT-FAMILY : verdana, arial; FONT-SIZE : 8pt; } TD { COLOR : black; FONT-FAMILY : verdana, arial; FONT-SIZE : 8pt; } TH { BACKGROUND-COLOR : #000363; COLOR : white; FONT-FAMILY : verdana, arial; FONT-SIZE : 8pt; FONT-WEIGHT : bold; } H3 { font-size : 11pt; font-family : Verdana, arial; color : #000363; font-weight : bold; } H4 { font-size : 10pt; font-family : Verdana, arial; color : #000363; } A:hover { background-color : #00FFFF; color : #000000; } </style> END ; } #================================================================= sub timeformat { $tf_timesent = $_[0]; $tf_format = $_[1]; $timeformat_longmonth[1] = "January"; $timeformat_longmonth[2] = "February"; $timeformat_longmonth[3] = "March"; $timeformat_longmonth[4] = "April"; $timeformat_longmonth[5] = "May"; $timeformat_longmonth[6] = "June"; $timeformat_longmonth[7] = "July"; $timeformat_longmonth[8] = "August"; $timeformat_longmonth[9] = "September"; $timeformat_longmonth[10] = "October"; $timeformat_longmonth[11] = "November"; $timeformat_longmonth[12] = "December"; $timeformat_shortmonth[1] = "Jan"; $timeformat_shortmonth[2] = "Feb"; $timeformat_shortmonth[3] = "Mar"; $timeformat_shortmonth[4] = "Apr"; $timeformat_shortmonth[5] = "May"; $timeformat_shortmonth[6] = "Jun"; $timeformat_shortmonth[7] = "Jul"; $timeformat_shortmonth[8] = "Aug"; $timeformat_shortmonth[9] = "Sep"; $timeformat_shortmonth[10] = "Oct"; $timeformat_shortmonth[11] = "Nov"; $timeformat_shortmonth[12] = "Dec"; #FORMAT KEYS # hh -- 24 hour, no leading zero -- Done # HH -- 24 hour, leading zero -- Done # mm -- minute, leading zero -- Done # ss -- seconds, leading zero -- Done # DD -- Day (leading zero) -- Done # dd -- Day (no leading zero) -- Done # m -- Month (no leading zero) -- Done # MM -- Month (01 - Jan, 12 - Dec) -- Done # MMM -- Month (Jan, Feb) -- Done # MMMM -- Month (January, February) -- Done # YY -- Year (Leading zero, eg. 02) -- Done # YYYY -- Year (full year, eg 2002) -- Done ($tf_sec,$tf_min,$tf_hour,$tf_mday,$tf_mon,$tf_year,$tf_wday,$ +tf_yday,$tf_isdst) = localtime($tf_timesent); $tf_HH = &timeformat_leadingzero($tf_hour); $tf_hh = $tf_hour; $tf_mm = &timeformat_leadingzero($tf_min); $tf_ss = &timeformat_leadingzero($tf_sec); $tf_DD = &timeformat_leadingzero($tf_mday); $tf_dd = $tf_mday; $tf_m = $tf_mon + 1; $tf_MM = &timeformat_leadingzero($tf_m); $tf_MMM = $timeformat_shortmonth[$tf_m]; $tf_MMMM = $timeformat_longmonth[$tf_m]; $tf_YYYY = $tf_year + 1900; $tf_YY = substr($tf_YYYY,2,2); $tf_format =~ s/HH/$tf_HH/g; $tf_format =~ s/hh/$tf_hh/g; $tf_format =~ s/mm/$tf_mm/g; $tf_format =~ s/ss/$tf_ss/g; $tf_format =~ s/DD/$tf_DD/g; $tf_format =~ s/dd/$tf_dd/g; $tf_format =~ s/MMMM/$tf_MMMM/g; $tf_format =~ s/MMM/$tf_MMM/g; $tf_format =~ s/MM/$tf_MM/g; $tf_format =~ s/m/$tf_m/g; $tf_format =~ s/YYYY/$tf_YYYY/g; $tf_format =~ s/YY/$tf_YY/g; return $tf_format; } sub timeformat_leadingzero { $tflz_var = $_[0]; if(length($tflz_var) == 1) { $tflz_var = "0$tflz_var"; } return $tflz_var; } sub htmlcell { $txt = @_[0]; $col = $_[1]; if($col eq "RED") { return "<td bgcolor=\"#FF0000\">$txt</td>\n"; } if($col eq "GREEN") { return "<td bgcolor=\"#00FF00\">$txt</td>\n"; } }
Edited by footpad, ~ Tue Jul 30 11:07:47 2002 (UTC): Added <READMORE> tag, per Consideration.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Simple Network Availability Monitor
by Tomte (Priest) on Jul 30, 2002 at 12:18 UTC | |
|
Re: Simple Network Availability Monitor
by cybear (Monk) on Aug 22, 2002 at 14:02 UTC |