root/lib/Resmon/Module.pm

Revision d1c88304cad0718a35367b4e5068e687459d1665, 4.7 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 7 years ago)

auto adapt external referenced modules into the Resmon::Module name space for execution

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

  • Property mode set to 100755
Line 
1 package Resmon::Module;
2
3 use strict;
4 use Data::Dumper;
5 use UNIVERSAL qw/isa/;
6 my %coderefs;
7
8 my $rmloading = "Registering";
9
10 sub fetch_monitor {
11   my $type = shift;
12   my $coderef = $coderefs{$type};
13   return $coderef if ($coderef);
14
15   # First if the monitor name is raw and looks right:
16   #   is a subclass of Resmon::Module and can 'handler'
17   # then we will promote it into the Resmon::Module namespace
18   # and use this one.
19   eval "use $type;";
20   if($type->isa(__PACKAGE__) && $type->can('handler')) {
21     eval "
22       package Resmon::Module::$type;
23       use vars qw/\@ISA/;
24       \@ISA = qw($type);
25       1;
26     ";
27     if($@) {
28       die "Could not repackage $type as Resmon::Module::$type\n";
29     }
30     return undef;
31   }
32   eval "use Resmon::Module::$type;";
33   return undef;
34 }
35
36 sub register_monitor {
37   my ($type, $ref) = @_;
38   if(ref $ref eq 'CODE') {
39     $coderefs{$type} = $ref;
40   }
41   print STDERR "$rmloading $type monitor\n";
42 }
43 sub fresh_status {
44   my $arg = shift;
45   return undef unless $arg->{interval};
46   my $now = time;
47   if(($arg->{lastupdate} + $arg->{interval}) >= $now) {
48     return $arg->{laststatus};
49   }
50   return undef;
51 }
52 sub set_status {
53   my $arg = shift;
54   $arg->{laststatus} = shift;
55   $arg->{lastmessage} = shift;
56   $arg->{lastupdate} = time;
57   if($arg->{laststatus} =~ /^([A-Z]+)\((.*)\)$/s) {
58     # This handles old-style modules that return just set status as
59     #     STATE(message)
60     $arg->{laststatus} = $1;
61     $arg->{lastmessage} = $2;
62   }
63   return ($arg->{laststatus}, $arg->{lastmessage});
64 }
65 #### Begin actual monitor functions ####
66
67 package Resmon::Module::DATE;
68 use vars qw/@ISA/;
69 @ISA = qw/Resmon::Module/;
70
71 sub handler {
72   my $arg = shift;
73   my $os = $arg->fresh_status();
74   return $arg->set_status("OK(".time().")");
75 }
76
77 package Resmon::Module::DISK;
78 use Resmon::ExtComm qw/cache_command/;
79 use vars qw/@ISA/;
80 @ISA = qw/Resmon::Module/;
81
82 sub handler {
83   my $arg = shift;
84   my $os = $arg->fresh_status();
85   return $os if $os;
86   my $devorpart = $arg->{'object'};
87   my $output = cache_command("df -k", 120);
88   my ($line) = grep(/$devorpart\s*/, split(/\n/, $output));
89   if($line =~ /(\d+)%/) {
90     if($1 <= $arg->{'limit'}) {
91       return $arg->set_status("OK($1% full)");
92     }
93     return $arg->set_status("BAD($1% full)");
94   }
95   return $arg->set_status("BAD(no data)");
96 }
97
98 package Resmon::Module::LOGFILE;
99 use vars qw/@ISA/;
100 @ISA = qw/Resmon::Module/;
101
102 my %logfile_stats;
103 sub handler {
104   my $arg = shift;
105   my $os = $arg->fresh_status();
106   return $os if $os;
107   my $file = $arg->{'object'};
108   my $match = $arg->{'match'};
109   my $errors;
110   my $errorcount = 0;
111   my $start = 0;
112   my @statinfo = stat($file);
113   if($logfile_stats{$file}) {
114     my($dev, $ino, $size, $errs) = split(/-/, $logfile_stats{$file});
115     if(($dev == $statinfo[0]) && ($ino == $statinfo[1])) {
116       if($size == $statinfo[7]) {
117         return $arg->set_status("OK($errs)");
118       }
119       $start = $size;
120       $errorcount = $errs;
121     }
122   }
123   $logfile_stats{$file} = "$statinfo[0]-$statinfo[1]-$statinfo[7]-$errorcount";
124   if(!open(LOG, "<$file")) {
125     return $arg->set_status("BAD(ENOFILE)");
126   }
127   seek(LOG, $statinfo[7], 0);
128   while(<LOG>) {
129     chomp;
130     if(/$match/) {
131       $errors .= $_;
132       $errorcount++;
133     }
134   }
135   if($errors) {
136     return $arg->set_status("BAD($errors)");
137   }
138   return $arg->set_status("OK($errorcount)");
139 }
140
141 package Resmon::Module::FILEAGE;
142 use vars qw/@ISA/;
143 @ISA = qw/Resmon::Module/;
144
145 sub handler {
146   my $arg = shift;
147   my $os = $arg->fresh_status();
148   return $os if $os;
149   my $file = $arg->{'object'};
150   my @statinfo = stat($file);
151   my $age = time() - $statinfo[9];
152   return $arg->set_status("BAD(to old $age seconds)")
153         if($arg->{maximum} && ($age > $arg->{maximum}));
154   return $arg->set_status("BAD(to new $age seconds)")
155         if($arg->{minimum} && ($age > $arg->{minimum}));
156   return $arg->set_status("OK($age)");
157 }
158
159 package Resmon::Module::NETSTAT;
160 use Resmon::ExtComm qw/cache_command/;
161 use vars qw/@ISA/;
162 @ISA = qw/Resmon::Module/;
163
164 sub handler {
165   my $arg = shift;
166   my $os = $arg->fresh_status();
167   return $os if $os;
168   my $output = cache_command("netstat -an", 30);
169   my @lines = split(/\n/, $output);
170   @lines = grep(/\s$arg->{state}$/, @lines) if($arg->{state});
171   @lines = grep(/^$arg->{localip}/, @lines) if($arg->{localip});
172   @lines = grep(/^[\d\*\.]+\.$arg->{localport}/, @lines) if($arg->{localport});
173   @lines = grep(/^[\d\*\.]+\d+\s+$arg->{remoteip}/, @lines)
174         if($arg->{remoteip});
175   @lines = grep(/^[\d\*\.]+\s+[\d\*\.+]\.$arg->{remoteport}/, @lines)
176         if($arg->{remoteport});
177   my $count = scalar(@lines);
178   return $arg->set_status("BAD($count)")
179         if($arg->{limit} && ($count > $arg->{limit}));
180   return $arg->set_status("BAD($count)")
181         if($arg->{atleast} && ($count < $arg->{atleast}));
182   return $arg->set_status("OK($count)");
183 }
184
185 $rmloading = "Demand loading";
186 1;
Note: See TracBrowser for help on using the browser.