root/resmon

Revision d710bcb9b19ab354fa6cbab08cbe91dcee175e86, 4.5 kB (checked in by Mark Harrison <mark@omniti.com>, 4 years ago)

Support wildcard modules (fixes #7)

This is done using a wildcard_handler method in addition to the normal handler
method. The wildcard_handler method is called if * is in the config file as
the check name, and the handler module is called for normal checks. By
default, both methods will die with "Not implemented", meaning modules can
implement one or both of the methods, depending on whether they support normal
checks, wildcard checks, or some combination of both.

git-svn-id: https://labs.omniti.com/resmon/branches/resmon2@386 8c0face9-b7db-6ec6-c4b3-d5f7145c7d55

  • Property mode set to 100755
Line 
1 #!/usr/bin/perl
2
3 BEGIN {
4     (my $dir = $0) =~ s/\/?[^\/]+$//;
5     eval "use lib '$dir/lib';";
6     die $@ if($@);
7 };
8
9 use strict;
10 use warnings;
11 use Time::HiRes qw( gettimeofday tv_interval sleep );
12 use POSIX qw( :sys_wait_h setsid );
13 use Getopt::Long;
14 use Data::Dumper;
15 use vars qw($config_file $debug $status_file $interface $port $config
16 $status $update);
17
18 use Resmon::Config;
19 use Resmon::ExtComm;
20 use Resmon::Status;
21
22 GetOptions(
23     "i=s" => \$interface,
24     "p=i" => \$port,
25     "c=s" => \$config_file,
26     "d"   => \$debug,
27     "f=s" => \$status_file,
28     "u"   => \$update,
29 );
30
31 if ($update) {
32     use Resmon::Updater;
33     (my $resmondir = $0) =~ s/\/?[^\/]+$//;
34     exit(Resmon::Updater::update($debug, $resmondir));
35 }
36
37 $config_file ||= "$0.conf";
38 die "Cannot open configuration file: $config_file" unless (-r $config_file);
39
40 sub configure {
41     $config = Resmon::Config->new($config_file);
42     $config->{statusfile} = $status_file if($status_file);
43     $config->{port} = $port if($port);
44     $config->{interface} = $interface if($interface);
45 }
46
47 configure();
48
49 my $sighup = 0;
50 sub sighup_handler { $sighup = 1; }
51 $SIG{'HUP'} = \&sighup_handler;
52
53 my $sigint = 0;
54 sub sigint_handler { $sigint = 1; }
55 $SIG{'INT'} = \&sigint_handler;
56
57 my $rmlast = undef;
58 sub wait_interval {
59     $rmlast = [gettimeofday] unless defined($rmlast);
60     my $elapsed = $config->{interval} - tv_interval($rmlast);
61     if($elapsed > 0) {
62         sleep($elapsed);
63     }
64     $rmlast = [gettimeofday];
65 }
66
67 sub reap_zombies {
68     my $kid;
69     do {
70         $kid = waitpid(-1, WNOHANG);
71     } while $kid > 0;
72 }
73
74 unless($debug) {
75     fork && exit;
76     setsid;
77     open(STDIN, "</dev/null");
78     open(STDOUT, ">/dev/null");
79     open(STDERR, ">/dev/null");
80     fork && exit;
81 }
82
83 my $list = [];
84 $status = Resmon::Status->new($config->{statusfile});
85 $status->open();
86 $status->serve_http_on($config->{interface}, $config->{port},
87         $config->{authuser}, $config->{authpass})
88     if($config->{port});
89
90 while(1) {
91     while(my($module_name, $mod_configs) = each %{$config->{Module}}) {
92         while(my($check_name, $monitor_obj) = each %$mod_configs) {
93             my $check_metrics = {};
94             my $starttime = [gettimeofday];
95             # Get old status if it hasn't expired
96             $check_metrics = $monitor_obj->get_cached_metrics();
97             # Otherwise, run the check
98             if (!$check_metrics) {
99                 my $timeout = $monitor_obj->{'check_timeout'} ||
100                     $config->{'timeout'};
101                 alarm($timeout);
102                 my $handler;
103                 eval {
104                     local $SIG{ALRM} = sub { die "alarm\n" };
105                     if ($check_name eq "*") {
106                         $check_metrics = $monitor_obj->wildcard_handler;
107                     } else {
108                         $check_metrics = {
109                             $check_name => $monitor_obj->handler
110                         };
111                     }
112                 };
113                 alarm 0;
114                 # Store the last metrics for use by fresh_status_msg later
115                 $monitor_obj->cache_metrics($check_metrics);
116             };
117             my $checkproblem = $@;
118             if($checkproblem) {
119                 chomp $checkproblem;
120                 if ($checkproblem eq "alarm") {
121                     $checkproblem = "Check timeout";
122                 }
123                 $check_metrics = {
124                     $check_name => {"error" => ["$checkproblem", "s"]}
125                 };
126                 Resmon::ExtComm::clean_up;
127             }
128             foreach my $name (keys %$check_metrics) {
129                 my $results = {
130                     last_runtime_seconds => sprintf("%.6f",
131                         tv_interval($starttime)),
132                     metric => $check_metrics->{$name}
133                 };
134                 $status->store($module_name,$name, $results);
135                 $status->write($module_name,$name, $results->{'metric'},
136                     $debug);
137             }
138         }
139     }
140     $status->close();
141     die "Exiting.\n" if($sigint);
142     if ($sighup) {
143         # Reload configuration (and modules) on SIGHUP
144         $sighup = 0;
145         print STDERR "Reloading modules\n";
146         $config = Resmon::Config->new($config_file);
147         # Needed to ensure any removed modules do not continue to show in the
148         # web interface
149         $status->clear();
150     } else {
151         reap_zombies();
152         wait_interval();
153         reap_zombies();
154     }
155     die "Exiting.\n" if($sigint);
156     print "\n---- ".localtime(time)."----------\n"
157     unless $status->open();
158 }
Note: See TracBrowser for help on using the browser.