Changeset b4a01ee848c6689e508db6c683e95fd59cb17f28

Show
Ignore:
Timestamp:
03/20/10 02:37:44 (4 years ago)
Author:
Mark Harrison <mark@omniti.com>
git-committer:
Mark Harrison <mark@omniti.com> 1269052664 +0000
git-parent:

[84fa9ac85ea06f95b5b8fb73360ff441d536e056]

git-author:
Mark Harrison <mark@omniti.com> 1269052664 +0000
Message:

Changes to how modules are loaded:

Each module is an object inheriting from Resmon::Module as before, but the
code to support coderefs and raw packages with a handler function is all gone.
In addition, a lot of redundant code was removed, and some small changes made
to the modules themselves:

  • The check name is stored in $self->{check_name} (instead of
    $self->{object} as in the past)
  • The check configuration is stored in $self->{config} and not just as
    instance variables.
  • All modules must have fully qualified names in the config file. In other
    words - Resmon::Module::Resmon instead of just RESMON. In keeping with
    other perl module names, I've gone with Title Case instead of ALL CAPS
    for the sample module (Resmon). This is simple to change back if desired
    however.

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • lib/Resmon/Config.pm

    rf51cc7c rb4a01ee  
    2222        if($current) { 
    2323            if(/^\s*([^:\s](?:[^:]*[^:\s])?)\s*:\s*(.+)\s*$/) { 
    24                 my %kvs; 
    25                 $kvs{'type'} = $current; 
    26                 $kvs{'object'} = $1; 
     24                my $kvs = {}; 
     25                my $check_name = $1; 
    2726                my @params = split(/,/, $2); 
    28                 grep { $kvs{$1} = $2 if /^\s*(\S+)\s*=>\s*(\S(?:.*\S)?)\s*$/ } 
     27                grep { $kvs->{$1} = $2 if /^\s*(\S+)\s*=>\s*(\S(?:.*\S)?)\s*$/ } 
    2928                    @params; 
    30                 my $object = bless \%kvs, "Resmon::Module::$current"; 
     29                my $object; 
     30                eval "use $current; 
     31                    \$object = $current->new(\$check_name, \$kvs);"; 
     32                if ($@) { 
     33                    print STDERR "Problem loading monitor $current:\n"; 
     34                    print STDERR "$@\n"; 
     35                    print STDERR "This module will not be available\n"; 
     36                    next; 
     37                } 
     38                if (!$object->isa("Resmon::Module")) { 
     39                    print STDERR "Module $current isn't of type "; 
     40                    print STDERR "Resmon::Module. This monitor will not be "; 
     41                    print STDERR "available\n"; 
     42                } 
    3143                push(@{$self->{Module}->{$current}}, $object); 
    32  
    33                 # Test to make sure the module actually works 
    34                 my $coderef; 
    35                 eval { $coderef = Resmon::Module::fetch_monitor($current); }; 
    36                 if (!$coderef) { 
    37                     # Try to execute the config_as_hash method. If it fails, 
    38                     # then the module didn't load properly (e.g. syntax 
    39                     # error). 
    40                     eval { $object->config_as_hash; }; 
    41                     if ($@) { 
    42                         # Module failed to load, print error and add to failed 
    43                         # modules list. 
    44                         print STDERR "Problem loading module $current\n"; 
    45                         print STDERR "This module will not be available\n"; 
    46                         $self->{'modstatus'} .= "$current "; 
    47                     } 
    48                 } 
    49  
    5044            } elsif (/^\s*\}\s*$/) { 
    5145                $current = undef; 
  • lib/Resmon/Module.pm

    • Property mode changed from 100755 to 100644
    r4dec1ca rb4a01ee  
    11package Resmon::Module; 
     2use strict; 
    23 
    3 use strict; 
    4 use Data::Dumper; 
    5 use FileHandle; 
    6 use UNIVERSAL qw/isa/; 
    7 my %coderefs; 
     4sub new { 
     5    my ($class, $check_name, $config) = @_; 
     6    my $self = {}; 
     7    $self->{config} = $config; 
     8    $self->{check_name} = $check_name; 
     9    bless ($self, $class); 
     10    return $self; 
     11
    812 
    9 my $rmloading = "Registering"; 
     13sub handler { 
     14    return { 
     15        'error_message' => ["Monitor not implemented", "s"] 
     16    } 
     17
    1018 
    11 sub fetch_monitor { 
    12     my $type = shift; 
    13     my $coderef = $coderefs{$type}; 
    14     return $coderef if ($coderef); 
     19sub cache_metrics { 
     20    # Simple method to cache the results of a check 
     21    my $self = shift; 
     22    $self->{lastmetrics} = shift; 
     23    $self->{lastupdate} = time; 
     24
    1525 
    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; 
     26sub get_cached_metrics { 
     27    my $self = shift; 
     28    return undef unless $self->{check_interval}; 
     29    my $now = time; 
     30    if(($self->{lastupdate} + $self->{check_interval}) >= $now) { 
     31        return $self->{lastmetrics}; 
    3232    } 
    33     eval "use Resmon::Module::$type;"; 
    3433    return undef; 
    3534} 
    3635 
    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  
    45 sub fresh_status { 
    46     my $arg = shift; 
    47     print STDERR $arg->{type} . 
    48         ": Warning: fresh_status() is deprecated, and no longer required.\n"; 
    49     return undef; 
    50 } 
    51  
    52 sub fresh_status_msg { 
    53     # Deal with result caching if an 'interval' entry is placed in the config 
    54     # for that module 
    55     my $arg = shift; 
    56     return undef unless $arg->{interval}; 
    57     my $now = time; 
    58     if(($arg->{lastupdate} + $arg->{interval}) >= $now) { 
    59         return $arg->{laststatus}, $arg->{lastmessage}; 
    60     } 
    61     return undef; 
    62 } 
    63 sub cache_metrics { 
    64     my $arg = shift; 
    65     $arg->{lastmetrics} = shift; 
    66     $arg->{lastupdate} = time; 
    67 } 
    68 sub config_as_hash { 
    69     my $self = shift; 
    70     my $conf = {}; 
    71     while(my ($key, $value) = each %$self) { 
    72         if(! ref $value) { 
    73             # only stash scalars here. 
    74             $conf->{$key} = $value; 
    75         } 
    76     } 
    77     return $conf; 
    78 } 
    79  
    80 sub reload_module { 
    81     my $self = shift; 
    82     my $class = ref($self) || $self; 
    83     $class =~ s/::/\//g; 
    84     my $file = $INC{"$class.pm"}; 
    85     # Deal with modules loaded from a LIB directory and not in 
    86     # lib/Resmon/Module: try MODNAME.pm instead of Resmon/Module/MODNAME.pm 
    87     unless ($file) { 
    88         $class =~ s/^.*\/([^\/]+)$/\1/; 
    89         $file = $INC{"$class.pm"}; 
    90     } 
    91     print STDERR "Reloading module: $class\n"; 
    92 #    my $fh = FileHandle->new($file); 
    93 #    local($/); 
    94     my $redef = 0; 
    95     local($SIG{__WARN__}) = sub { 
    96         if($_[0] =~ /[Ss]ubroutine ([\w:]+) redefined/ ) { 
    97             $redef++; 
    98             return; 
    99         } 
    100         warn @_; 
    101     }; 
    102 #    eval <$fh>; 
    103     eval {do($file); die $@ if $@}; 
    104     return $@ if $@; 
    105     return $redef; 
    106 } 
    107  
    108 $rmloading = "Demand loading"; 
    109361; 
  • lib/Resmon/Status.pm

    r84fa9ac rb4a01ee  
    493493        $loaded{$type} = (); 
    494494        foreach (@$mods) { 
    495             $loaded{$type}{$_->{'object'}} = 1; 
     495            $loaded{$type}{$_->{'check_name'}} = 1; 
    496496        } 
    497497    } 
  • resmon

    radc4557 rb4a01ee  
    1818use Resmon::ExtComm; 
    1919use Resmon::Status; 
    20 use Resmon::Module; 
    2120 
    2221GetOptions( 
     
    124123while(1) { 
    125124    while(my($module_name, $mod_configs) = each %{$config->{Module}}) { 
    126         my $coderef = undef; 
    127         eval { $coderef = Resmon::Module::fetch_monitor($module_name); }; 
    128         foreach my $monobj (@$mod_configs) { 
    129             my $check_metric = 'no data'; 
     125        foreach my $monitor_obj (@$mod_configs) { 
     126            my $check_metric = {}; 
    130127            my $starttime = [gettimeofday]; 
    131128            # Get old status if it hasn't expired 
    132             my $check_metric = Resmon::Module::fresh_status_msg($monobj); 
     129            my $check_metric = $monitor_obj->get_cached_metrics(); 
    133130            # Otherwise, run the check 
    134131            if (!$check_metric) { 
    135                 my $timeout = $monobj->{'check_timeout'} || 
     132                my $timeout = $monitor_obj->{'check_timeout'} || 
    136133                    $config->{'timeout'}; 
    137134                alarm($timeout); 
    138135                eval { 
    139136                    local $SIG{ALRM} = sub { die "alarm\n" }; 
    140                     if($coderef) { 
    141                         $check_metric = $coderef->($monobj); 
    142                     } else { 
    143                         $check_metric = $monobj->handler(); 
    144                     } 
     137                    $check_metric = $monitor_obj->handler(); 
    145138                }; 
    146139                alarm 0; 
    147140                # Store the last metrics for use by fresh_status_msg later 
    148                 Resmon::Module::cache_metrics($monobj, $check_metric); 
     141                $monitor_obj->cache_metrics($check_metric); 
    149142            }; 
    150143            my $checkproblem = $@; 
     
    162155                } 
    163156            } 
    164             $status->store($module_name,$monobj->{'object'}, $results); 
    165             $status->write($module_name,$monobj->{'object'}, 
     157            $status->store($module_name,$monitor_obj->{'check_name'}, $results); 
     158            $status->write($module_name,$monitor_obj->{'check_name'}, 
    166159                $results->{'metric'}, $debug); 
    167160        }