root/lib/Resmon/Module.pm

Revision 3869a700db6ffc7c89dcad5a762def14e7877d7c, 6.5 kB (checked in by Sergey Ivanov <seriv@omniti.com>, 6 years ago)

two modules for checking filesize, local and remotes over ssh added

git-svn-id: https://labs.omniti.com/resmon/trunk@48 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 sub config_as_hash {
66   my $self = shift;
67   my $conf = {};
68   while(my ($key, $value) = each %$self) {
69     if(! ref $value) {
70       # only stash scalars here.
71       $conf->{$key} = $value;
72     }
73   }
74   return $conf;
75 }
76 #### Begin actual monitor functions ####
77
78 package Resmon::Module::DATE;
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 $arg->set_status("OK(".time().")");
86 }
87
88 package Resmon::Module::DISK;
89 use Resmon::ExtComm qw/cache_command/;
90 use vars qw/@ISA/;
91 @ISA = qw/Resmon::Module/;
92
93 sub handler {
94   my $arg = shift;
95   my $os = $arg->fresh_status();
96   return $os if $os;
97   my $devorpart = $arg->{'object'};
98   my $output = cache_command("df -k", 120);
99   my ($line) = grep(/$devorpart\s*/, split(/\n/, $output));
100   if($line =~ /(\d+)%/) {
101     if($1 <= $arg->{'limit'}) {
102       return $arg->set_status("OK($1% full)");
103     }
104     return $arg->set_status("BAD($1% full)");
105   }
106   return $arg->set_status("BAD(no data)");
107 }
108
109 package Resmon::Module::LOGFILE;
110 use vars qw/@ISA/;
111 @ISA = qw/Resmon::Module/;
112
113 my %logfile_stats;
114 sub handler {
115   my $arg = shift;
116   my $os = $arg->fresh_status();
117   return $os if $os;
118   my $file = $arg->{'object'};
119   my $match = $arg->{'match'};
120   my $max = $arg->{'max'} || 8;
121   my @statinfo = stat($file);
122   if(exists($arg->{file_dev})) {
123     if(($arg->{file_dev} == $statinfo[0]) &&
124        ($arg->{file_ino} == $statinfo[1])) {
125       if($arg->{lastsize} == $statinfo[7]) {
126         if($arg->{errors}) {
127           return $arg->set_status("BAD($arg->{nerrs}: $arg->{errors})");
128         }
129         return $arg->set_status("OK(0)");
130       }
131     } else {
132       # File is a different file now
133       $arg->{lastsize} = 0;
134       $arg->{nerrs} = 0;
135       $arg->{errors} = '';
136     }
137   }
138   if(!open(LOG, "<$file")) {
139     return $arg->set_status("BAD(ENOFILE)");
140   }
141   seek(LOG, $arg->{lastsize}, 0);
142
143   while(<LOG>) {
144     chomp;
145     if(/$match/) {
146       if($arg->{nerrs} < $max) {
147         $arg->{errors} .= " " if(length($arg->{errors}));
148         $arg->{errors} .= $_;
149       }
150       $arg->{nerrs}++;
151     }
152   }
153
154   # Remember where we were
155   $arg->{file_dev} = $statinfo[0];
156   $arg->{file_ino} = $statinfo[1];
157   $arg->{lastsize} = $statinfo[7];
158
159   if($arg->{nerrs}) {
160     return $arg->set_status("BAD($arg->{nerrs}: $arg->{errors})");
161   }
162   return $arg->set_status("OK(0)");
163 }
164
165 package Resmon::Module::FILESIZE;
166 use vars qw/@ISA/;
167 @ISA = qw/Resmon::Module/;
168
169 sub handler {
170   my $arg = shift;
171   my $os = $arg->fresh_status();
172   return $os if $os;
173   my $file = $arg->{'object'};
174   my @statinfo = stat($file);
175   my $size = $statinfo[7];
176   my $minsize = $arg->{minimum};
177   my $maxsize = $arg->{maximum};
178   return $arg->set_status("BAD(too big, $size > $maxsize)")
179         if($maxsize && ($size > $maxsize));
180   return $arg->set_status("BAD(too small, $size < $minsize)")
181         if($minsize && ($size > $minsize));
182   return $arg->set_status("OK($size)");
183 }
184
185 package Resmon::Module::REMOTEFILESIZE;
186 use vars qw/@ISA/;
187 use Resmon::ExtComm qw/cache_command/;
188 @ISA = qw/Resmon::Module/;
189
190 sub handler {
191   my $arg = shift;
192   my $os = $arg->fresh_status();
193   return $os if $os;
194   my $host = $arg->{'host'};
195   my $file = $arg->{'object'};
196   my $output = cache_command("ssh -i /root/.ssh/id_dsa $host du -b $file", 600);
197   $output =~ /^(\d+)\s/;
198   my $size = $1;
199   my $minsize = $arg->{minimum};
200   my $maxsize = $arg->{maximum};
201   return $arg->set_status("BAD(too big, $size > $maxsize)")
202         if($maxsize && ($size > $maxsize));
203   return $arg->set_status("BAD(too small, $size < $minsize)")
204         if($minsize && ($size > $minsize));
205   return $arg->set_status("OK($size)");
206 }
207
208 package Resmon::Module::FILEAGE;
209 use vars qw/@ISA/;
210 @ISA = qw/Resmon::Module/;
211
212 sub handler {
213   my $arg = shift;
214   my $os = $arg->fresh_status();
215   return $os if $os;
216   my $file = $arg->{'object'};
217   my @statinfo = stat($file);
218   my $age = time() - $statinfo[9];
219   return $arg->set_status("BAD(too old $age seconds)")
220         if($arg->{maximum} && ($age > $arg->{maximum}));
221   return $arg->set_status("BAD(too new $age seconds)")
222         if($arg->{minimum} && ($age > $arg->{minimum}));
223   return $arg->set_status("OK($age)");
224 }
225
226 package Resmon::Module::NETSTAT;
227 use Resmon::ExtComm qw/cache_command/;
228 use vars qw/@ISA/;
229 @ISA = qw/Resmon::Module/;
230
231 sub handler {
232   my $arg = shift;
233   my $os = $arg->fresh_status();
234   return $os if $os;
235   my $output = cache_command("netstat -an", 30);
236   my @lines = split(/\n/, $output);
237   @lines = grep(/\s$arg->{state}\s*$/, @lines) if($arg->{state});
238   @lines = grep(/^$arg->{localip}/, @lines) if($arg->{localip});
239   @lines = grep(/^[\w\d\*\.]+.*[\.\:]+$arg->{localport}/, @lines) if($arg->{localport});
240   @lines = grep(/[\d\*\.]+\d+\s+$arg->{remoteip}/, @lines)
241         if($arg->{remoteip});
242   @lines = grep(/[\d\*\.]+\s+[\d\*\.]+[\.\:]+$arg->{remoteport}\s+/, @lines)
243         if($arg->{remoteport});
244   my $count = scalar(@lines);
245   return $arg->set_status("BAD($count)")
246         if($arg->{limit} && ($count > $arg->{limit}));
247   return $arg->set_status("BAD($count)")
248         if($arg->{atleast} && ($count < $arg->{atleast}));
249   return $arg->set_status("OK($count)");
250 }
251
252 $rmloading = "Demand loading";
253 1;
Note: See TracBrowser for help on using the browser.