onomejiro has asked for the wisdom of the Perl Monks concerning the following question:

I have been working on a script in which the monks have helped me to sort out the immediate monitoring issue at hand. So far, I have written up the attached script while searching a lot of media including cpan which is very resourceful. I get the info if the web server is up and running but no absolute result in the case of the database server. However, I have this feeling that this can be done in a better way. I am just learning of the use of cron…Now can I please beg your divine indulgence to suggest a remedy? Thank you all for your wisdom. God bless you...

#!/usr/bin/perl -w use strict; use LWP::UserAgent; use DBI; use Net::Ping; use MIME::Lite; my $is_prsd_ok = &check_prsd('sample'); my $is_httpd_ok = &check_httpd(); my $is_db_ok = &check_database(); my $is_chat_ok = &check_chat(); my $is_prsd_ok = &check_prsd(); # if any one is not ok then send an email if ( (!$is_httpd_ok) || (!$is_db_ok) || (!$is_chat_ok) || (!$is_prsd_o +k) ) { # use MIME::Lite to send an email. my $msg = MIME::Lite->new( From =>'server@example.com', To =>'admin@example.com', Subject =>"Server error report", Type => 'text', Data =>"Server error report for scalar(localtime( +)), - " . time(), #timestamp?? ); # also add record to monitor.log that email was sent $msg->send(); open (FILE, ">>monitor.log"); print FILE "This is a test\n"; close (FILE); } exit(); # if httpd is up, then status return should be TRUE sub check_httpd { # use LWP to check www.catholicmatch.com my $ua = LWP::UserAgent->new(); my $request = HTTP::Request->new('GET', 'http://www.example.com'); my $response = $ua->request($request); if ($response->is_success()) { # This should eventually be logged - open FILE (">>monitor.lo +g") || die "some error"; print "Website is up and running\n"; return 1; } # This should eventually be logged - open FILE (">>monitor.log") +|| die "some error"; print "Website is down\n"; return 0; } #sub ping { # my($dbh) = @_; # my $ret = 0; # eval { # local $SIG{__DIE__} = sub { return (0); }; # local $SIG{__WARN__} = sub { return (0); }; # adapt the select statement to your database: # $ret = $dbh->do('select 1'); # }; # return ($@) ? 0 : $ret; # } sub check_database { # use dbi to check sample2 (DBI->ping()) my ($database,$user,$password) = @_; my $dbh = DBI->connect("DBI:mysql:sample2" , undef , undef , {PrintError => 1, RaiseError => 0} ) or db_err("Unable to connect to $database", $DBI::errstr); # return status of running database eval { alarm(5); # seconds before time out $dbh = DBI->ping("dbi:mysql:anne" ,"", ""); alarm(0); # cancel alarm (if connect worked fast) }; alarm(0); # cancel alarm (if eval failed) } sub db_err { my($msg, $errstr) = @_; open (FILE, ">>monitor.log"); print FILE "This is a test\n"; print FILE->$msg; print FILE->($errstr); close (FILE); } # if chat is up, then status return should be TRUE sub check_chat { # use net ping to check sample on port 5678 # my $dbh = ping(); my $pinghost = 'sample.example.com'; my $p = Net::Ping->new("tcp", 2); for (;;) { unless ($p->ping($pinghost)) { print "Fail: ", scalar(localtime), "\n"; return 1; } print "Success: ", scalar(localtime), "\n"; return 0; } } # a better way would be to send this, but ping is okay <message comman +d="login" cookie="ASDFASDF" /> sub check_prsd { # use net ping to check sample on port 5959 my ($host) = @_; my $p = Net::Ping->new("tcp", 2); $p->{'port_num'} = 5959; if ($p->ping($host, 2)) { print "$host is alive.\n"; return 1; } print "$host is not reachable.\n"; return 0; }

READMORE tags added by Arunbear

Replies are listed 'Best First'.
Re: Update on script
by McDarren (Abbot) on Apr 04, 2006 at 15:25 UTC
    It would appear that you are writing this script partly to learn some Perl, which I certainly wouldn't want to discourage :)

    However, in doing so you are re-inventing a wheel that you really don't need to. There are stacks of open source Network Management Systems already out there that will do exactly want you want, right out of the box.

    One in particular that I would recommend is Big Brother. It's extremely easy to install and configure, and includes ping and http tests as standard features (and much more). And the thing that I particularly like about Big Brother is that it's quite easy to write your own customised plug-in tests (in Perl, of course).

    I'd really encourage you to take a look at it.

    Cheers,
    Darren :)

    PS. No, I am in no way associated with BB, but I've been using it for several years and I really like it :)

Re: Update on script
by davidrw (Prior) on Apr 04, 2006 at 15:33 UTC
    If you're not using anything else from LWP::UserAgent, you can save a few lines by using LWP::Simple instead:
    use LWP::Simple; sub check_httpd { if( get 'http://www.example.com' ){ ... return 1; } ... return 0;