
Server check
--0016e648be4085cff1048db10910
Content-Type: text/plain; charset=UTF-8
Hai
After a lot of frustration i have build this code to check which of the
server is down and which is up.
These are the requirements needed to run this code.
1. Linux machine,
2. Perl >5.8
3. Sql server >5.1
4. XML::LibXML module in perl
5. DBI module
6. sendmail need to installed and service need to be running.
*What is the use of this Application:*
So what this will do is what ever servers you need to check for ping add
them to the servers.xml one by one.If a server is down it will send a mail
to the user stating that the server is down. Once that server comes online
it will send you a mail stating that the server is up and online. It will
make a log in the table when the server went OFFLINE and ONLINE for future
reference.
*INSTALLATION:*
I am giving a sample xml file along with this one.
Create a database in the localhost server. The db structure is also there
along with the code.
Now copy the ping.pl code to your local server and run it . U can run it as
a cron or can be run as a service in linux as well.
*CODE::*
*ping.pl::*
#for Linux Machines
use DBI;
use XML::LibXML;
$to_email = "dr.virus.india\ [at] gmail.com"; # \ should be given before the [at]
symbol
$from_email = "chaitu\ [at] server.com"; # \ should be given before the [at] symbol
$serverxml = "servers.xml";
print "XML NAME=> ".$serverxml."\n";
my $dsn = "dbi:mysql:ping:localhost:3306";
my $dbh = DBI->connect($dsn,"root","") or die ("Cannot connect to
database");
my [at] filearray;
my $parser = XML::LibXML->new();
eval{
my $doc= $parser->parse_file($serverxml);
my $root = $doc->getDocumentElement;
foreach my $file ($root->findnodes('/serverdetails/server')){
#print $file->findvalue('.')."\n";
push( [at] filearray,$file->findvalue('.'));
}
};
if($ [at] )
{
print "Cannot read XML\n";
}
else
{
foreach( [at] filearray){
$variable = "$_";
my [at] split = split(',',$variable);
$server_name = $split[0];
$server_ip = $split[1];
$q = "select sno from check_table where client_nme='".$server_name."' and
client_ip='".$server_ip."'";
$xt = $dbh->prepare($q);
$xt->execute();
$sno = $xt->fetchrow_array();
if($sno eq ''){
$qu = "insert into check_table(client_nme,client_ip,status_)
values('".$server_name."','".$server_ip."','0')";
$dbh->do($qu);
}
print "Server Name=> ".$server_name."\nServer Ip =>".$server_ip."\n";
$pingstats = `ping -c 4 $server_ip |grep received`;
#print "Grep Details=> ".$pingstats."\n";
my [at] pingvar = split(',',$pingstats);
$Received = $pingvar[1];
$Lost = $pingvar[2];
#print "Received=> ".$Received."\nLost=> ".$Lost."\n";
[at] receive = split(' ',$Received);
$re = $receive[0];
#print "\t\t".$re."\n";
[at] lo = split('%',$Lost);
$los = trim($lo[0]);
#print "\t\thh".$los."\n";
if($los >= '70'){
$r = "select status_ from check_table where client_nme='".$server_name."'
and client_ip='".$server_ip."'";
#print "R==> ".$r."\n";
$re = $dbh->prepare($r);
$re->execute();
$stat_vale = $re->fetchrow_array();
if($stat_vale eq '0'){
$dbh->do("update check_table set status_ = '1',stime=now() where
client_nme='".$server_name."' and client_ip='".$server_ip."'" );
my $message = "Server => ".$server_name." is Down. Check it out!!!";
sendEmail($to_email, $from_email, "SERVER DOWN.", $message);
}
else{
}
}
else{
$w = "select status_ from check_table where client_nme='".$server_name."'
and client_ip='".$server_ip."'";
#print "W==> ".$w."\n";
$we = $dbh->prepare($w);
$we->execute();
$st_val = $we->fetchrow_array();
#print "St_Value==> ".$st_val."\n";
if($st_val eq '1'){
$ty = "update check_table set status_ = '0',etime=now() where
client_nme='".$server_name."' and client_ip='".$server_ip."'";
#print "TY==> ".$ty."\n";
$dbh->do($ty);
$dbh->do("INSERT INTO
log_table(Check_id,client_nme,client_ip,stime,etime,status_) (SELECT
sno,client_nme,client_ip,stime,etime,status_ FROM check_table WHERE
client_nme='".$server_name."' and client_ip='".$server_ip."')");
my $message = "Server => ".$server_name." is Online Now. Check it out!!!";
sendEmail($to_email, $from_email, "SERVER ONLINE.", $message);
}
}
}
}
sub sendEmail
{
my ($to, $from, $subject, $message) = [at] _;
my $sendmail = '/usr/lib/sendmail';
open(MAIL, "|$sendmail -oi -t");
print MAIL "From: $from\n";
print MAIL "To: $to\n";
print MAIL "Subject: $subject\n\n";
print MAIL "$message\n";
close(MAIL);
}
sub trim()
{
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
*DB Structure::*
USE `ping`;
/*Table structure for table `check_table` */
CREATE TABLE `check_table` (
`sno` int(7) NOT NULL AUTO_INCREMENT,
`client_nme` varchar(100) NOT NULL,
`client_ip` varchar(40) NOT NULL,
`stime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`etime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`status_` enum('0','1') NOT NULL,
PRIMARY KEY (`sno`)
) ;
/*Table structure for table `log_table` */
CREATE TABLE `log_table` (
`sno` int(7) NOT NULL AUTO_INCREMENT,
`Check_id` int(7) DEFAULT NULL,
`client_nme` varchar(100) NOT NULL,
`client_ip` varchar(40) NOT NULL,
`stime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`etime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`status_` enum('0','1') NOT NULL,
PRIMARY KEY (`sno`)
)
*servers.xml::*
<?xml version="1.0" encoding="iso-8859-1"?>
<serverdetails>
<server>chaitu,10.43.32.12</server>
<server>Chaitanya,10.37.21.11</server>
<server>Anny,10.10.154.14</server>
</serverdetails>
*I need you opinion on this how to make it more useful by any other means...
*
--0016e648be4085cff1048db10910--
Re: Server check
before i (or anyone else) will delve into your code, please learn to use
white space and indenting. you can't read code that is all tightly
jumbled together like this. and don't use very short variable names as
they tell the reader nothing about the program. you need to learn to
write code the others can and will want to read. otherwise you will not
communicate your logic to them and they will not be able to help you nor
maintain your code.
uri
--
Uri Guttman ------ uri [at] stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Server check
With that being said, please do yourself a favour and get a copy of
"Perl Best Practises"
On 08/13/2010 09:25 PM, Uri Guttman wrote:
> before i (or anyone else) will delve into your code, please learn to use
> white space and indenting. you can't read code that is all tightly
> jumbled together like this. and don't use very short variable names as
> they tell the reader nothing about the program. you need to learn to
> write code the others can and will want to read. otherwise you will not
> communicate your logic to them and they will not be able to help you nor
> maintain your code.
>
> uri
>
>
--
Regards,
Vimal Kumar K
| vimalZworld.com * technomenace.com * twitter.com/vimal7370 |
| E: vimal7370 at gmail dot com P: +919947450760 |
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Server check
Congratulations. You have just (re)invented Nagios.
B
On Fri, Aug 13, 2010 at 9:05 AM, Vimal <vimal7370 [at] gmail.com> wrote:
> With that being said, please do yourself a favour and get a copy of "Perl
> Best Practises"
>
> On 08/13/2010 09:25 PM, Uri Guttman wrote:
>>
>> before i (or anyone else) will delve into your code, please learn to use
>> white space and indenting. you can't read code that is all tightly
>> jumbled together like this. and don't use very short variable names as
>> they tell the reader nothing about the program. you need to learn to
>> write code the others can and will want to read. otherwise you will not
>> communicate your logic to them and they will not be able to help you nor
>> maintain your code.
>>
>> uri
>>
>>
>
>
> --
> Regards,
> Vimal Kumar K
>
> | vimalZworld.com * technomenace.com * twitter.com/vimal7370 |
> | E: vimal7370 at gmail dot com =A0 =A0 =A0 =A0 =A0 =A0 P: +919947450760 =
|
>
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
> For additional commands, e-mail: beginners-help [at] perl.org
> http://learn.perl.org/
>
>
>
--
Bob Goolsby
bob.goolsby [at] gmail.com
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Server check
Bg> On Fri, Aug 13, 2010 at 9:05 AM, Vimal <vimal7370 [at] gmail.com> wrote:
>> With that being said, please do yourself a favour and get a copy of "Perl
>> Best Practises"
>>
>> On 08/13/2010 09:25 PM, Uri Guttman wrote:
>>>
>>> before i (or anyone else) will delve into your code, please learn to use
>>> white space and indenting. you can't read code that is all tightly
>>> jumbled together like this. and don't use very short variable names as
>>> they tell the reader nothing about the program. you need to learn to
>>> write code the others can and will want to read. otherwise you will not
>>> communicate your logic to them and they will not be able to help you nor
>>> maintain your code.
>>>>> "Bg" == Bob goolsby <bob.goolsby [at] gmail.com> writes:
Bg> Congratulations. You have just (re)invented Nagios.
who me? or vimal? please reply to the proper poster and not to other
repliers. i have not reinvented nagios (yet! :).
and also please learn to edit quoted emails. there is no need to see
redundant signatures and other text you are replying too. in fact
nothing in your email mentioned the network stuff the OP is doing so all
context was lost in your email.
finally this is the perl beginner's list and the question was about his
perl, not reinventing network monitoring. maybe installing and running
nagios is way beyond what he can do and he just needs to learn basic
network coding in perl?
uri
--
Uri Guttman ------ uri [at] stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Server check
On Fri, Aug 13, 2010 at 05:23, Chaitanya Yanamadala
<dr.virus.india [at] gmail.com> wrote:
> Hai
> After a lot of frustration i have build this code to check which of the
> server is down and which is up.
snip
Here is a major rewrite. In order of importance, here is a list of
changes I made:
* Use whitespace properly, when in doubt use [perltidy][0] on your
code and emulate that.
* Use placeholders instead of building SQL with with values, not only
is it more efficient and general, it will also protect you from
injection attacks.
* Don't trust $ [at] to have a value after an eval, and use Try::Tiny
instead of block eval
* Use the strict and warnings pragmas.
* Check the return value of system calls (e.g. open, print, close, etc.).
* Use the three argument version of open, not the two argument version.
* Move the preparation of SQL out of loops, there is no need to
prepare a statement more than once.
* Use the correct equality and relational operators ( == and the like
for numbers, eq and the like for strings).
* NULL values will be undef in Perl 5, not an empty string
* All user modifiable variables should be defined near the top to make
it easy to find them, but preferably the should be moved to a config
file or passed on the commandline.
* Use lexical filehandles instead of bareword filehandles.
* Use DBI->connect()'s options to make your life easier.
* Use flow control instead of deeply nesting if statements.
* Use constants to give confusing literals meaning to the reader.
* Don't use useless temporary variables.
* Don't use concatenation where you can use interpolation.
I have left several FIXMEs in the code. They are there because I
don't have enough information to fix them or they are suggesting a
module that will simplify code and I didn't want to force more
dependencies on you (but you really should be using them).
On a separate note, your database table and column names are very bad.
Misspelling client_name, having a floating _ after status, cryptic
names like etime and and stime, and adding table to every table name
are all confusing or silly. You might also want to store the IP
address as an integer and use to inet_aton and inet_ntoa to convert it
(this has many benefits including the ability to sort by IP address).
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use XML::LibXML;
use constant ONLINE => 0;
use constant OFFLINE => 1;
#FIXME: all of this should be in a config file
#or passed on the commandline, maybe in the XML file?
my $to_email = 'dr.virus.india [at] gmail.com';
my $from_email = 'chaitu [at] server.com';
my $serverxml = "servers.xml";
my $dsn = "dbi:mysql:ping:localhost:3306";
my $threshold = 70;
print "XML NAME => $serverxml\n";
my $dbh = DBI->connect(
$dsn,
"root",
"",
{
ChopBlanks => 1, #trim selected fields
PrintError => 0, #don't print errors
RaiseError => 1, #die instead
ShowErrorStatement => 1, #and print the SQL too
}
) or die "Cannot connect to database";
my [at] servers;
my $parser = XML::LibXML->new();
#FIXME: consider using Try::Tiny instead
#as this construct also has problems
eval {
my $root = $parser->parse_file($serverxml)->getDocumentElement;
for my $file ($root->findnodes('/serverdetails/server')) {
push [at] servers, $file->findvalue('.');
}
1;
} or die "Cannot read XML\n";
my $get_sno = $dbh->prepare("
SELECT sno
FROM check_table
WHERE client_nme = ?
AND client_ip = ?
");
my $insert_check_table = $dbh->prepare("
INSERT INTO check_table (client_nme, client_ip, status_)
VALUES (?, ?, 0)
");
my $get_status = $dbh->prepare("
SELECT status_
FROM check_table
WHERE client_nme = ?
AND client_ip = ?
");
my $update_status = $dbh->prepare("
UPDATE check_table
SET status_ = ?,
stime = now()
WHERE client_nme = ?
AND client_ip = ?
");
my $insert_log = $dbh->prepare("
INSERT INTO log_table (
Check_id, client_nme, client_ip, stime, etime, status_
)
SELECT sno, client_nme, client_ip, stime, etime, status_
FROM check_table
WHERE client_nme = ?
AND client_ip = ?
");
for my $server_record ( [at] servers) {
my ($server_name, $server_ip) = split ',', $server_record;
$get_sno->execute($server_name, $server_ip);
my $sno = $get_sno->fetchrow_array();
unless (defined $sno) {
$insert_check_table->execute($server_name, $server_ip);
}
print
"Server Name => $server_name\n",
"Server Ip => $server_ip\n";
#FIXME: this should probably be replaced with Net::Ping
my $pingstats = qx(ping -c 4 $server_ip | grep received);
my ($Received, $Lost) = (split ',', $pingstats)[1,2];
#FIXME: $received isn't used, why are we getting it?
my $received = (split ' ', $Received)[0];
my $lost = trim((split '%', $Lost)[0]);
$get_status->execute($server_name, $server_ip);
my $status = $get_status->fetchrow_array();
if ($lost >= $threshold and $status == ONLINE) {
$update_status->execute(1, $server_name, $server_ip);
sendEmail(
$to_email,
$from_email,
"SERVER DOWN.",
"Server => $server_name is Down. Check it out!!!"
);
next;
}
if ($lost < $threshold and $status == OFFLINE) {
$update_status->execute(0, $server_name, $server_ip);
$insert_log->execute($server_name, $server_ip);
sendEmail(
$to_email,
$from_email,
"SERVER ONLINE.",
"Server => $server_name is Online Now. Check it out!!!"
);
next;
}
}
#FIXME: consider replacing this with Email::Sender
sub sendEmail {
my ($to, $from, $subject, $message) = [at] _;
my $sendmail = '/usr/lib/sendmail';
open my $mail, "|-", $sendmail, "-oi", "-t"
or die "could not run sendmail: $!\n";
print $mail
"From: $from\n",
"To: $to\n",
"Subject: $subject\n\n",
"$message\n"
or die "could not talk to sendmail: $!\n";
close $mail
or die "could not finish talking to sendmail: $!\n";
}
sub trim {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
[0]: http://search.cpan.org/dist/Perl-Tidy/lib/Perl/Tidy.pm
--
Chas. Owens
wonkden.net
The most important skill a programmer can have is the ability to read.
--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Re: Server check
--000feaeebabef6196a048dc24341
Content-Type: text/plain; charset=UTF-8
Hai All
Thank you guys for your replies. I would note these points which you have
mentioned and try to use further in my coding.
Regards
Chaitanya
On Sat, Aug 14, 2010 at 5:45 AM, Chas. Owens <chas.owens [at] gmail.com> wrote:
> On Fri, Aug 13, 2010 at 05:23, Chaitanya Yanamadala
> <dr.virus.india [at] gmail.com> wrote:
> > Hai
> > After a lot of frustration i have build this code to check which of the
> > server is down and which is up.
> snip
>
> Here is a major rewrite. In order of importance, here is a list of
> changes I made:
>
> * Use whitespace properly, when in doubt use [perltidy][0] on your
> code and emulate that.
> * Use placeholders instead of building SQL with with values, not only
> is it more efficient and general, it will also protect you from
> injection attacks.
> * Don't trust $ [at] to have a value after an eval, and use Try::Tiny
> instead of block eval
> * Use the strict and warnings pragmas.
> * Check the return value of system calls (e.g. open, print, close, etc.).
> * Use the three argument version of open, not the two argument version.
> * Move the preparation of SQL out of loops, there is no need to
> prepare a statement more than once.
> * Use the correct equality and relational operators ( == and the like
> for numbers, eq and the like for strings).
> * NULL values will be undef in Perl 5, not an empty string
> * All user modifiable variables should be defined near the top to make
> it easy to find them, but preferably the should be moved to a config
> file or passed on the commandline.
> * Use lexical filehandles instead of bareword filehandles.
> * Use DBI->connect()'s options to make your life easier.
> * Use flow control instead of deeply nesting if statements.
> * Use constants to give confusing literals meaning to the reader.
> * Don't use useless temporary variables.
> * Don't use concatenation where you can use interpolation.
>
> I have left several FIXMEs in the code. They are there because I
> don't have enough information to fix them or they are suggesting a
> module that will simplify code and I didn't want to force more
> dependencies on you (but you really should be using them).
>
> On a separate note, your database table and column names are very bad.
> Misspelling client_name, having a floating _ after status, cryptic
> names like etime and and stime, and adding table to every table name
> are all confusing or silly. You might also want to store the IP
> address as an integer and use to inet_aton and inet_ntoa to convert it
> (this has many benefits including the ability to sort by IP address).
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use DBI;
> use XML::LibXML;
>
> use constant ONLINE => 0;
> use constant OFFLINE => 1;
>
> #FIXME: all of this should be in a config file
> #or passed on the commandline, maybe in the XML file?
> my $to_email = 'dr.virus.india [at] gmail.com';
> my $from_email = 'chaitu [at] server.com';
> my $serverxml = "servers.xml";
> my $dsn = "dbi:mysql:ping:localhost:3306";
> my $threshold = 70;
>
> print "XML NAME => $serverxml\n";
>
> my $dbh = DBI->connect(
> $dsn,
> "root",
> "",
> {
> ChopBlanks => 1, #trim selected fields
> PrintError => 0, #don't print errors
> RaiseError => 1, #die instead
> ShowErrorStatement => 1, #and print the SQL too
> }
> ) or die "Cannot connect to database";
>
> my [at] servers;
> my $parser = XML::LibXML->new();
>
> #FIXME: consider using Try::Tiny instead
> #as this construct also has problems
> eval {
> my $root = $parser->parse_file($serverxml)->getDocumentElement;
> for my $file ($root->findnodes('/serverdetails/server')) {
> push [at] servers, $file->findvalue('.');
> }
> 1;
> } or die "Cannot read XML\n";
>
> my $get_sno = $dbh->prepare("
> SELECT sno
> FROM check_table
> WHERE client_nme = ?
> AND client_ip = ?
> ");
>
> my $insert_check_table = $dbh->prepare("
> INSERT INTO check_table (client_nme, client_ip, status_)
> VALUES (?, ?, 0)
> ");
>
> my $get_status = $dbh->prepare("
> SELECT status_
> FROM check_table
> WHERE client_nme = ?
> AND client_ip = ?
> ");
>
> my $update_status = $dbh->prepare("
> UPDATE check_table
> SET status_ = ?,
> stime = now()
> WHERE client_nme = ?
> AND client_ip = ?
> ");
>
> my $insert_log = $dbh->prepare("
> INSERT INTO log_table (
> Check_id, client_nme, client_ip, stime, etime, status_
> )
> SELECT sno, client_nme, client_ip, stime, etime, status_
> FROM check_table
> WHERE client_nme = ?
> AND client_ip = ?
> ");
>
> for my $server_record ( [at] servers) {
> my ($server_name, $server_ip) = split ',', $server_record;
>
> $get_sno->execute($server_name, $server_ip);
> my $sno = $get_sno->fetchrow_array();
>
> unless (defined $sno) {
> $insert_check_table->execute($server_name, $server_ip);
> }
>
> print
> "Server Name => $server_name\n",
> "Server Ip => $server_ip\n";
>
> #FIXME: this should probably be replaced with Net::Ping
> my $pingstats = qx(ping -c 4 $server_ip | grep received);
> my ($Received, $Lost) = (split ',', $pingstats)[1,2];
> #FIXME: $received isn't used, why are we getting it?
> my $received = (split ' ', $Received)[0];
> my $lost = trim((split '%', $Lost)[0]);
>
> $get_status->execute($server_name, $server_ip);
> my $status = $get_status->fetchrow_array();
>
> if ($lost >= $threshold and $status == ONLINE) {
> $update_status->execute(1, $server_name, $server_ip);
> sendEmail(
> $to_email,
> $from_email,
> "SERVER DOWN.",
> "Server => $server_name is Down. Check it out!!!"
> );
> next;
> }
>
> if ($lost < $threshold and $status == OFFLINE) {
> $update_status->execute(0, $server_name, $server_ip);
> $insert_log->execute($server_name, $server_ip);
> sendEmail(
> $to_email,
> $from_email,
> "SERVER ONLINE.",
> "Server => $server_name is Online Now. Check it
> out!!!"
> );
> next;
> }
> }
>
> #FIXME: consider replacing this with Email::Sender
> sub sendEmail {
> my ($to, $from, $subject, $message) = [at] _;
> my $sendmail = '/usr/lib/sendmail';
> open my $mail, "|-", $sendmail, "-oi", "-t"
> or die "could not run sendmail: $!\n";
> print $mail
> "From: $from\n",
> "To: $to\n",
> "Subject: $subject\n\n",
> "$message\n"
> or die "could not talk to sendmail: $!\n";
> close $mail
> or die "could not finish talking to sendmail: $!\n";
> }
>
> sub trim {
> my $string = shift;
> $string =~ s/^\s+//;
> $string =~ s/\s+$//;
> return $string;
> }
>
> [0]: http://search.cpan.org/dist/Perl-Tidy/lib/Perl/Tidy.pm
>
> --
> Chas. Owens
> wonkden.net
> The most important skill a programmer can have is the ability to read.
>
--000feaeebabef6196a048dc24341--