fix error message when an action isn't selected
[freeside.git] / bin / monitor
1 #!/usr/bin/perl -w
2
3 use strict;
4 use vars qw( $DEBUG );
5 use Getopt::Std;
6 use FS::Daemon qw(daemonize1 daemonize2 logfile sigint sigterm);
7 use FS::Yori qw(report);
8 use Email::Send;
9
10 $DEBUG = 0;
11
12 &untaint_argv;  #what it sounds like  (eww)
13
14 use vars qw(%opt);
15 getopts('m:p:', \%opt );
16
17 my ($machine, @emails) = @ARGV;
18 die &usage unless @emails;
19
20 warn "starting daemonization (forking)\n" if $DEBUG;
21 daemonize1('freeside-monitor');
22 #logfile( "%%%FREESIDE_LOG%%%/monitorlog.$machine" );
23 logfile( "/usr/local/etc/freeside/monitorlog.$machine" );
24
25 warn "completing daemonization (detaching))\n" if $DEBUG;
26 daemonize2();
27
28 my $wantfree = $opt{m} || 1048576;
29 my $wantload = $opt{p} || 5;
30
31 die 'bogus memory requirement: $wantfree'
32    unless $wantfree && $wantfree =~ /^\d+$/;
33
34 die 'bogus load requirement: $wantload'
35    unless $wantload && $wantload =~ /^[\d.]+$/;
36
37 my $alerts = 0;
38 my $last = time();
39 while (1) {
40
41   my(undef, $load, undef) = report('load');
42   my($free) = report('freememory');
43   
44   warn "free is $free and wantfree is $wantfree\n" if $DEBUG > 1;
45   warn "load is $load and wantload is $wantload\n" if $DEBUG > 1;
46   warn "last is $last\n" if $DEBUG > 1;
47   
48   unless( defined($load) && $load < $wantload
49        && defined($free) && $free > $wantfree
50        || ( time() < $last + 1800 && $alerts > 2 ) )
51   {
52     warn localtime(). ": $machine has load of $load and $free kB free memory\n";
53     $alerts++;
54     $alerts = 0 if time() > $last + 1800;
55     $last = time();
56     foreach my $email ( @emails ) {
57
58       my $message = <<"__MESSAGE__";
59 From: support\@freeside.biz
60 To: $email
61 Subject: ALERT - $machine
62
63 ALERT: $machine has a load of $load and only $free kB free..
64
65 __MESSAGE__
66
67     my $sender = Email::Send->new({mailer => 'SMTP'});
68     $sender->mailer_args([Host => 'mail.freeside.biz']);
69     $sender->send($message);
70
71     }
72
73   }
74
75
76
77   if ( sigterm() ) {
78     warn "received TERM signal; exiting\n";
79     exit;
80   }
81   if ( sigint() ) {
82     warn "received INT signal; exiting\n";
83     exit;
84   }
85
86   sleep 30; #too long?  too short?
87
88 }
89
90 sub untaint_argv {
91   foreach $_ ( $[ .. $#ARGV ) { #untaint @ARGV
92     $ARGV[$_] =~ /^([\w\-\/\@\.]*)$/ || die "Illegal arguement \"$ARGV[$_]\"";
93     $ARGV[$_]=$1;
94   }
95 }
96
97 sub usage {
98   die "Usage:\n\n  freeside-monitor [ -pm ] machine email\n";
99 }
100
101 =head1 NAME
102
103 freeside-monitor - Perform some basic load monitoring
104
105 =head1 SYNOPSIS
106
107   freeside-monitor [ -p MAXLOAD ] [ -m REQUIRED_FRERMEM ] machine email [ ... ]
108
109 =head1 DESCRIPTION
110
111 Load monitoring daemon.  Should be running at all times.
112
113 -p: maximum permitted 5 minute load
114
115 -m: minimum free vmem in kB
116
117 machine: a unique name to be used in alert messages
118 email: address(es) to which alerts should be sent
119
120 =head1 VERSION
121
122 =head1 BUGS
123
124 =head1 SEE ALSO
125
126 =cut
127