I needed a test for latency in a mail queue, where a monitor script
would send an email to the server under test, wait for the
mail to end up in the appropriate mailbox, and complain if the mail
delay was too great.  The mailloop.monitor in the Mon archive sort of
did what I wanted, but in a very Mon-unfriendly way and with lots of
limitations.

So I've heavily modified that script to make it play better with
Mon and added a bunch of features at the same time.  It now
polls multiple hosts in a hostgroup by hostname, rather
than by email address, and multiple running copies on the
same host can share a POP mailbox (the old version insisted
on a separate mailbox for each hostgroup).  There are other
new features - this script won't be fooled by outdated mail,
has a tunable poll interval, and it also prints out the response
times for viewing in the Mon "service details" page.

The script has changed so much I've given it a new name: mail2pop3.monitor.

Andrew, please add this to the mon contrib site.  The monitor is attached,
and the comments from the top are below.  Enjoy.

# mail2pop3.monitor - sends email to mailboxes and then polls the mailbox
# via POP3 to see if the mail arrives within the timeout period.

# Operation: For each host in the hostgroup, a message is sent via port 25
# on that host.  Then, a POP3 mailbox is polled every <poll-interval>
# seconds, looking for the emails to arrive, until the maximum timeout
# period.  Messages that don't arrive from a particular host will be
# printed on stdout, mon-style.

# The monitor will delete all mail in the POP3 mailbox that it recognizes
# as being from itself, as well as any mail that does not appear to be
# from another copy of the monitor.  There are one or two scenarios,
# like when you disable a monitor or change your local hostname, that
# might leave a few messages sitting in the mailbox forever - you
# might want to manually check the box once a month to see if there's
# any cruft lying around.

# Be sure to give the monitor its own mailbox not used for anything else -
# ALL mail in the box will be deleted when the monitor is done.

# Based on mailloop.monitor by Bill Smargiassi.  Modifed by Ed Ravin
# ([EMAIL PROTECTED]) to use Mon's host model, to allow more than
# one hostgroup to share a POP3 mailbox, and to print out response
# times after a successful run.

# Setup: if you don't mind sending your password remotely, poll a POP3
# mailbox on the destination mail server.  Otherwise, send mail to an
# alias which is forwarded back to your local Mon server, and fetch
# the mail with a local popserver.

Sample setup:

    service mailloop
    description mail loop back testing
    MAIL2POP3_PASSWORD=<mumble>
    interval 15m
    monitor mail2pop3.monitor -w 5 -t 300 -F [EMAIL PROTECTED] -T [EMAIL PROTECTED]

#!/usr/bin/perl 

# 
# mail2pop3.monitor - sends email to mailboxes and then polls the mailbox
# via POP3 to see if the mail arrives within the timeout period.

# Operation: For each host in the hostgroup, a message is sent via port 25
# on that host.  Then, a POP3 mailbox is polled every <poll-interval>
# seconds, looking for the emails to arrive, until the maximum timeout
# period.  Messages that don't arrive from a particular host will be
# printed on stdout, mon-style.

# The monitor will delete all mail in the POP3 mailbox that it recognizes
# as being from itself, as well as any mail that does not appear to be
# from another copy of the monitor.  There are one or two scenarios,
# like when you disable a monitor or change your local hostname, that
# might leave a few messages sitting in the mailbox forever - you
# might want to manually check the box once a month to see if there's
# any cruft lying around.

# Be sure to give the monitor its own mailbox not used for anything else -
# ALL mail in the box will be deleted when the monitor is done.

# Based on mailloop.monitor by Bill Smargiassi.  Modifed by Ed Ravin
# ([EMAIL PROTECTED]) to use Mon's host model, to allow more than
# one hostgroup to share a POP3 mailbox, and to print out response
# times after a successful run.

# Setup: if you don't mind sending your password remotely, poll a POP3
# mailbox on the destination mail server.  Otherwise, send mail to an
# alias which is forwarded back to your local Mon server, and fetch
# the mail with a local popserver.

# Original code copyright notice:
# Copyright 2000 Shared Medical Systems, Inc. 
# Author: Bill Smargiassi 
# Email: [EMAIL PROTECTED] 


# options: 
# -d Debug Mode. Not really compatible with normal mon scheduling, 
# because it doesn't log to syslog or anything, just print to STDOUT. 
# You'll have to call the monitor by hand to use this option. 
# Mostly helpful to debug your POP/SMTP setup. 
# 
# -F Set the From: address, this option will also set the POP user to 
# all the bits before the '@'. So, don't do any wild aliasing...   Required.
#
# -T Set the To: address.  Required.
# 
# -p Set the POP password. Defaults to null password .  Can be passed
# in via the environment variable MAIL2POP3_PASSWORD, which is recommended,
# since otherwise your Mon users will be able to see the password via the
# service details in the Mon interface.
# 
# -s Set the POP server. Defaults to localhost. 
# 
# -t Standard monitor timeout option.  (default 900 seconds (15 minutes))
# 
# -w how many seconds to wait in between polls of the POP mailbox (default 30)

# $Id: mail2pop3.monitor,v 1.1 2003/07/25 02:08:48 root Exp root $

# This program is free software; you can redistribute it and/or modify 
# it under the terms of the GNU General Public License as published by 
# the Free Software Foundation; either version 2 of the License, or 
# (at your option) any later version. 
# 
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
# GNU General Public License for more details. 
# 
# You should have received a copy of the GNU General Public License 
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
# 

use Getopt::Std; 
use Mail::Sendmail; 
use POSIX; 
use Mail::POP3Client; 

sub dbgprint { 
    my ($str) = @_; 

    print $str, "\n" if $DEBUG; 
} 

# "check sum of tests left", not to be confused with a checksum :) 
sub checksum { 
    my $sum; 

    $sum = 0; 
    foreach $id (keys %check) { 
     $sum += $check{$id} > 0 ? 1 : 0; 
    } 
    dbgprint "sum is " . $sum; 
    return $sum; 
} 

sub showtimes
{
        foreach $host (keys %responsetime)
        {
                print "$host responded in $responsetime{$host} seconds\n";
        }
}

sub diefailures { 
    my @hosts= ();

    foreach $id (keys %check) { 
     if ($check{$id}) { 
                unshift(@hosts, $id);
     } 
    } 
    print join(' ', @hosts) . "\n"; 
        print "\n";
        print "Mail was sent but not received within $Timeout seconds\n";
        print "Successful returns, if any, shown below.\n";
        print "\n";
        showtimes;
    exit 1; 
} 

$usage="mail2pop3.monitor [-d] [-p <pw>] [-s popserver] [-t timeout] [-w poll] -F 
[EMAIL PROTECTED] -T [EMAIL PROTECTED] host [...]\n";

getopts("dF:T:p:s:t:w:"); 
$Timeout = $opt_t || 900; 

$hostname = `hostname`; 
chomp $hostname;

$popname = 'mailloop'; 
if (defined($opt_F)) { 
    $fromaddr = $opt_F; 
    @parts = split(/\@/, $opt_F); 
    $popname = $parts[0]; 
}  else { die $usage; };

if (defined($opt_T)) {
        $toaddr= $opt_T;
}  else { die $usage; };

$poppass = $opt_p || $ENV{'MAIL2POP3_PASSWORD'} || "";

$popserv = $opt_s || 'localhost'; 

$poppoll = $opt_w || 30;

$smtpserv = $opt_S || 'localhost';

$DEBUG = $opt_d || 0; 

dbgprint "Testing from $hostname, sender $fromaddr, to dest $toaddr";
dbgprint "Will send mail to port 25 on hosts " . join(' ', @ARGV);
dbgprint "Timeout = $Timeout    Poll = $poppoll"; 

$failures = ""; 
%responsetime= ();

foreach $smtpserver (@ARGV) { 
        $now= time;
    # Send some mail via the host being monitored
    $id= "$hostname->$smtpserver " . $now;
    dbgprint "Sending mail: $id"; 
    %mail = ( To => $toaddr, 
           From => $fromaddr, 
           Message => "REFL: $id" ,
                   SMTP => $smtpserver,
           ); 

    # remember the id for later POP retrieval 
    $check{$smtpserver} = $now; 

    if (sendmail %mail) { } 
    else { $failures .= "Error sending mail: $Mail::Sendmail::error " } 
} 

dbgprint "Done sending mail"; 

if ($failures) {die $failures} 

local $SIG{TERM} = \&diefailures; 

$starttime = time; 

# look for replies 

while(checksum()) { 
    if ((time - $starttime) > $Timeout) {
     diefailures(); 
    } 
    sleep($poppoll); 
    dbgprint "Logging in..."; 
        $pop = new Mail::POP3Client( USER => $popname, 
                                                PASSWORD => $poppass, 
                                                HOST => $popserv, 
                                                AUTH_MODE => 'PASS',
                                                DEBUG => $DEBUG); 
    dbgprint "There are " . $pop->Count . " messages"; 
        for ($i = 1; $i <= $pop->Count; $i++) { 
                $id = ""; 
                $someotherid= 0;
                @lines = split(/\n/, $pop->Body($i)); 
                foreach $line (@lines) { 
                        dbgprint $line; 
        #  $id= "$hostname->$smtpserver " . strftime("%Y%m%d%H%M%S", localtime(time)); 
                        if ($line =~ m/^REFL: $hostname->(\S+) (\d+)/g) { 
                        $id = $1; 
                        $ctimesent= $2;
                        dbgprint "* Rcvd mail from host $id, sent $datesent - 
$ctimesent"; 
                        } 
                } 
        
                if ($id ne "") # we found something
                {
                        if (exists($check{$id}))  # something we sent?
                        {
                                if ($check{$id} == $ctimesent) {
                                        $responsetime{$id}= time() - $ctimesent;
                                        dbgprint "deleting recognized mail from $id 
sent at $ctimesent";
                                        $check{$id}= 0;
                                        $pop->Delete($i); 
                                } else {
                                        dbgprint "ignoring and deleting outdated mail 
from $id sent at $ctimesent";
                                        $pop->Delete($i); 
                                }
                        }  else 
                        { # another mon on this host sent it, ignore
                                dbgprint "ignoring mail for a different monitor from 
$id sent at $ctimesent";
                        }
                } else
                {
                        dbgprint "deleting unrecognized mail: $i";
                        $pop->Delete($i);  # unrecognized mail, trash it.
                }
        }
        dbgprint "Logging out"; 
        $pop->Close; 
        } 

print "\n";
showtimes;

exit 0;
_______________________________________________
mon mailing list
[EMAIL PROTECTED]
http://linux.kernel.org/mailman/listinfo/mon

Reply via email to