| 1 |
package Resmon::Module; |
|---|
| 2 |
|
|---|
| 3 |
use strict; |
|---|
| 4 |
use Data::Dumper; |
|---|
| 5 |
use FileHandle; |
|---|
| 6 |
use UNIVERSAL qw/isa/; |
|---|
| 7 |
my %coderefs; |
|---|
| 8 |
|
|---|
| 9 |
my $rmloading = "Registering"; |
|---|
| 10 |
|
|---|
| 11 |
sub fetch_monitor { |
|---|
| 12 |
my $type = shift; |
|---|
| 13 |
my $coderef = $coderefs{$type}; |
|---|
| 14 |
return $coderef if ($coderef); |
|---|
| 15 |
|
|---|
| 16 |
# First if the monitor name is raw and looks right: |
|---|
| 17 |
# is a subclass of Resmon::Module and can 'handler' |
|---|
| 18 |
# then we will promote it into the Resmon::Module namespace |
|---|
| 19 |
# and use this one. |
|---|
| 20 |
eval "use $type;"; |
|---|
| 21 |
if($type->isa(__PACKAGE__) && $type->can('handler')) { |
|---|
| 22 |
eval " |
|---|
| 23 |
package Resmon::Module::$type; |
|---|
| 24 |
use vars qw/\@ISA/; |
|---|
| 25 |
\@ISA = qw($type); |
|---|
| 26 |
1; |
|---|
| 27 |
"; |
|---|
| 28 |
if($@) { |
|---|
| 29 |
die "Could not repackage $type as Resmon::Module::$type\n"; |
|---|
| 30 |
} |
|---|
| 31 |
return undef; |
|---|
| 32 |
} |
|---|
| 33 |
eval "use Resmon::Module::$type;"; |
|---|
| 34 |
return undef; |
|---|
| 35 |
} |
|---|
| 36 |
|
|---|
| 37 |
sub register_monitor { |
|---|
| 38 |
my ($type, $ref) = @_; |
|---|
| 39 |
if(ref $ref eq 'CODE') { |
|---|
| 40 |
$coderefs{$type} = $ref; |
|---|
| 41 |
} |
|---|
| 42 |
print STDERR "$rmloading $type monitor\n"; |
|---|
| 43 |
} |
|---|
| 44 |
sub fresh_status { |
|---|
| 45 |
my $arg = shift; |
|---|
| 46 |
return undef unless $arg->{interval}; |
|---|
| 47 |
my $now = time; |
|---|
| 48 |
if(($arg->{lastupdate} + $arg->{interval}) >= $now) { |
|---|
| 49 |
return $arg->{laststatus}; |
|---|
| 50 |
} |
|---|
| 51 |
return undef; |
|---|
| 52 |
} |
|---|
| 53 |
sub set_status { |
|---|
| 54 |
my $arg = shift; |
|---|
| 55 |
$arg->{laststatus} = shift; |
|---|
| 56 |
$arg->{lastmessage} = shift; |
|---|
| 57 |
$arg->{lastupdate} = time; |
|---|
| 58 |
if($arg->{laststatus} =~ /^([A-Z]+)\((.*)\)$/s) { |
|---|
| 59 |
# This handles old-style modules that return just set status as |
|---|
| 60 |
# STATE(message) |
|---|
| 61 |
$arg->{laststatus} = $1; |
|---|
| 62 |
$arg->{lastmessage} = $2; |
|---|
| 63 |
} |
|---|
| 64 |
return ($arg->{laststatus}, $arg->{lastmessage}); |
|---|
| 65 |
} |
|---|
| 66 |
sub config_as_hash { |
|---|
| 67 |
my $self = shift; |
|---|
| 68 |
my $conf = {}; |
|---|
| 69 |
while(my ($key, $value) = each %$self) { |
|---|
| 70 |
if(! ref $value) { |
|---|
| 71 |
# only stash scalars here. |
|---|
| 72 |
$conf->{$key} = $value; |
|---|
| 73 |
} |
|---|
| 74 |
} |
|---|
| 75 |
return $conf; |
|---|
| 76 |
} |
|---|
| 77 |
|
|---|
| 78 |
sub reload_module { |
|---|
| 79 |
my $self = shift; |
|---|
| 80 |
my $class = ref($self) || $self; |
|---|
| 81 |
$class =~ s/::/\//g; |
|---|
| 82 |
my $file = $INC{"$class.pm"}; |
|---|
| 83 |
print STDERR "Reloading module: $class\n"; |
|---|
| 84 |
# my $fh = FileHandle->new($file); |
|---|
| 85 |
# local($/); |
|---|
| 86 |
my $redef = 0; |
|---|
| 87 |
local($SIG{__WARN__}) = sub { |
|---|
| 88 |
if($_[0] =~ /[Ss]ubroutine ([\w:]+) redefined/ ) { |
|---|
| 89 |
$redef++; |
|---|
| 90 |
return; |
|---|
| 91 |
} |
|---|
| 92 |
warn @_; |
|---|
| 93 |
}; |
|---|
| 94 |
# eval <$fh>; |
|---|
| 95 |
eval {do($file); die $@ if $@}; |
|---|
| 96 |
return $@ if $@; |
|---|
| 97 |
return $redef; |
|---|
| 98 |
} |
|---|
| 99 |
|
|---|
| 100 |
$rmloading = "Demand loading"; |
|---|
| 101 |
1; |
|---|