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.ow...@gmail.com> wrote:

> On Fri, Aug 13, 2010 at 05:23, Chaitanya Yanamadala
> <dr.virus.in...@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 $@ 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.in...@gmail.com';
> my $from_email = 'cha...@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 @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 @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 (@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) = @_;
>        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.
>

Reply via email to