Changeset 4dec1cad7b7b758eb26a27a13dad73fc8609af3f

Show
Ignore:
Timestamp:
03/18/10 22:03:35 (4 years ago)
Author:
Mark Harrison <mark@omniti.com>
git-committer:
Mark Harrison <mark@omniti.com> 1268949815 +0000
git-parent:

[4173e891c90a57ecfaeafa3db695d6d99db41285]

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

Change modules to return only metrics (no state).

The RESMON module is an example of how to do this (just return a hash).
However, the resmon module itself needs much improvement (it should eventually
be able to be little more than the return command itself).

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

Files:

Legend:

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

    rf51cc7c r4dec1ca  
    6161    return undef; 
    6262} 
    63  
    64 sub set_status { 
     63sub cache_metrics { 
    6564    my $arg = shift; 
    66     $arg->{laststatus} = shift; 
    67     $arg->{lastmessage} = shift; 
     65    $arg->{lastmetrics} = shift; 
    6866    $arg->{lastupdate} = time; 
    69     if($arg->{laststatus} =~ /^([A-Z]+)\((.*)\)$/s) { 
    70         # This handles old-style modules that return just set status as 
    71         #     STATE(message) 
    72         $arg->{laststatus} = $1; 
    73         $arg->{lastmessage} = $2; 
    74     } 
    75     return ($arg->{laststatus}, $arg->{lastmessage}); 
    7667} 
    7768sub config_as_hash { 
  • lib/Resmon/Module/RESMON.pm

    r95026f2 r4dec1ca  
    1919    # Get the global config object 
    2020    my $config = $main::config; 
    21     my $configstatus = $config->{'configstatus'} || ""
    22     my $modstatus = $config->{'modstatus'} || ""
     21    my $configstatus = $config->{'configstatus'}
     22    my $modstatus = $config->{'modstatus'}
    2323 
    2424    ## Current revision 
    2525    # Find location of subversion binary 
     26    # TODO - use svn keywords for this rather than running svn info 
    2627    my $svn = 'svn'; 
    2728    for my $path (qw(/usr/local/bin /opt/omni/bin /opt/csw/bin)) { 
     
    3435    my $revision = "svn revision unknown"; 
    3536    for (split(/\n/, $output)) { 
    36         if (/^Revision:\s*(\d*)$/) { $revision = "r$1"; } 
     37        if (/^Revision:\s*(\d*)$/) { $revision = "$1"; } 
    3738        if (/^svn: (.*) is not a working copy$/) { 
    3839            $revision = "not a working copy"; 
     
    4445    my $hostname = eval { hostname } || "Unknown"; 
    4546 
    46     my $status = "OK"; 
    47     my $statusmsg = "running"; 
    48     if ($configstatus) { 
    49         $statusmsg = "BAD config file, running on old configuration"; 
    50         $status = "BAD"; 
    51     } 
    52     if ($modstatus) { 
    53         $statusmsg .= " with failed modules: $modstatus"; 
    54         $status = "BAD"; 
    55     } 
    56  
    57     # Set 'config' variables so it shows up in the xml output 
    58     $arg->{'revision'} = $revision; 
    59     $arg->{'hostname'} = $hostname; 
    60     $arg->{'configstatus'} = $configstatus || "OK"; 
    61     $arg->{'modstatus'} = $modstatus || "OK"; 
    62  
    63     return $status, { 
    64         "message" => ["$hostname $statusmsg ($revision)", "s"] 
     47    return { 
     48        "revision" => [$revision, "i"], 
     49        "hostname" => [$hostname, "s"], 
     50        "configstatus" => [$configstatus ? "BAD" : "OK", "s"], 
     51        "modstatus" => [$modstatus ? "BAD" : "OK", "s"] 
    6552    }; 
    66 } 
     53}; 
    6754 
    68551; 
  • lib/Resmon/Status.pm

    rf51cc7c r4dec1ca  
    119119    return $rv; 
    120120} 
    121 sub dump_generic_state { 
    122     # Dumps only checks with a specific state 
    123     my $self = shift; 
    124     my $dumper = shift; 
    125     my $state = shift; 
    126     my $rv = ''; 
    127     while(my ($module, $services) = each %{$self->{store}}) { 
    128         while(my ($service, $info) = each %$services) { 
    129             if ($info->{state} eq $state) { 
    130                 $rv .= $dumper->($module,$service,$info); 
    131             } 
    132         } 
    133     } 
    134     return $rv; 
    135 } 
    136 sub dump_oldstyle { 
    137     my $self = shift; 
    138     my $response = $self->dump_generic(sub { 
    139             my($module,$service,$info) = @_; 
    140             my $message = $info->{metric}->{message}; 
    141             if (ref $message eq "ARRAY") { 
    142                 $message = $message->[0]; 
    143             } 
    144             return "$service($module) :: $info->{state}($message)\n"; 
    145         }); 
    146     return $response; 
    147 } 
    148121sub dump_xml { 
    149122    my $self = shift; 
     
    172145    <ul class="navbar"> 
    173146        <li><a href="/">List all checks</a></li> 
    174         <li><a href="/BAD">List all checks that are BAD</a></li> 
    175         <li><a href="/WARNING">List all checks that are WARNING</a></li> 
    176         <li><a href="/OK">List all checks that are OK</a></li> 
    177147    </ul> 
    178148    <p> 
     
    184154        <xsl:sort select="\@service" /> 
    185155        <div class="item"> 
    186                 <xsl:attribute name="class"> 
    187                     item <xsl:value-of select="state" /> 
    188                 </xsl:attribute> 
    189156            <div class="info"> 
    190157                Last check: <xsl:value-of select="last_runtime_seconds" /> 
     
    205172                    <xsl:value-of select="\@service" /> 
    206173                </a> 
    207                 - 
    208                 <xsl:value-of select="state"/>: 
    209                 <xsl:value-of select="metric[attribute::name='message']" /> 
    210174            </h1> 
    211             <xsl:if test="count(metric[attribute::name!='message']) > 0"> 
    212                 <ul> 
    213                     <xsl:for-each select="metric[attribute::name!='message']"> 
    214                         <xsl:sort select="\@name" /> 
    215                         <li><xsl:value-of select="\@name" /> =  
    216                         <xsl:value-of select="." /></li> 
    217                     </xsl:for-each> 
    218                 </ul> 
    219             </xsl:if> 
     175            <ul> 
     176                <xsl:for-each select="metric"> 
     177                    <xsl:sort select="\@name" /> 
     178                    <li><xsl:value-of select="\@name" /> =  
     179                    <xsl:value-of select="." /></li> 
     180                </xsl:for-each> 
     181            </ul> 
    220182        </div> 
    221183    </xsl:for-each> 
     
    257219    padding: 0; 
    258220    margin: 0; 
    259 } 
    260  
    261 .OK { 
    262     background-color: #afa; 
    263     border-left: 10px solid #393; 
    264 } 
    265  
    266 .WARNING { 
    267     background-color: #ffa; 
    268     border-left: 10px solid #993; 
    269 } 
    270  
    271 .BAD { 
    272     background-color: #faa; 
    273     border-left: 10px solid #933; 
    274221} 
    275222 
     
    344291        $client->print($response . "\r\n"); 
    345292        return; 
    346     } elsif($req eq '/' or $req eq '/status') { 
     293    } elsif($req eq '/') { 
    347294        my $response .= $self->dump_xml(); 
    348295        $client->print(http_header(200, length($response), 'text/xml', $snip)); 
    349         $client->print($response . "\r\n"); 
    350         return; 
    351     } elsif($req eq '/status.txt') { 
    352         my $response = $self->dump_oldstyle(); 
    353         $client->print(http_header(200, length($response), 'text/plain', $snip)); 
    354296        $client->print($response . "\r\n"); 
    355297        return; 
     
    378320        } 
    379321    } elsif($req =~ /^\/([^\/]+)$/) { 
    380         if ($1 eq "BAD" || $1 eq "OK" || $1 eq "WARNING") { 
    381             my $response = qq^<?xml version="1.0" encoding="UTF-8"?>\n^; 
    382             my $response .= qq^<?xml-stylesheet type="text/xsl" href="/resmon.xsl"?>^; 
    383             $response .= "<ResmonResults>\n". 
    384             $self->dump_generic_state(\&xml_info,$1) . 
    385             "</ResmonResults>\n"; 
    386             $client->print(http_header(200, length($response), 'text/xml', $snip)); 
    387             $client->print( $response . "\r\n"); 
    388             return; 
    389         } elsif(exists($self->{store}->{$1})) { 
     322        if(exists($self->{store}->{$1})) { 
    390323            my $response = qq^<?xml version="1.0" encoding="UTF-8"?>\n^; 
    391324            my $response .= qq^<?xml-stylesheet type="text/xsl" href="/resmon.xsl"?>^; 
     
    563496        $message = $message->[0]; 
    564497    } 
     498    # TODO - print metrics here insead of message 
    565499    if($self->{handle}) { 
    566         $self->{handle}->print("$name($type) :: $info->{state}($message)\n"); 
     500        $self->{handle}->print("$name($type) :: $message\n"); 
    567501    } else { 
    568         print "$name($type) :: $info->{state}($message)\n"; 
     502        print "$name($type) :: $message\n"; 
    569503    } 
    570504} 
  • resmon

    rf51cc7c r4dec1ca  
    127127        eval { $coderef = Resmon::Module::fetch_monitor($module_name); }; 
    128128        foreach my $monobj (@$mod_configs) { 
    129             my $check_rv = 'BAD', 
    130129            my $check_metric = 'no data'; 
    131130            my $starttime = [gettimeofday]; 
    132131            # Get old status if it hasn't expired 
    133             my ($check_rv, $check_metric) = Resmon::Module::fresh_status_msg( 
    134                 $monobj); 
     132            my $check_metric = Resmon::Module::fresh_status_msg($monobj); 
    135133            # Otherwise, run the check 
    136             if (!$check_rv) { 
     134            if (!$check_metric) { 
    137135                my $timeout = $monobj->{'check_timeout'} || 
    138136                    $config->{'timeout'}; 
     
    141139                    local $SIG{ALRM} = sub { die "alarm\n" }; 
    142140                    if($coderef) { 
    143                         ($check_rv, $check_metric) = $coderef->($monobj); 
     141                        $check_metric = $coderef->($monobj); 
    144142                    } else { 
    145                         ($check_rv, $check_metric) = $monobj->handler(); 
     143                        $check_metric = $monobj->handler(); 
    146144                    } 
    147145                }; 
    148146                alarm 0; 
    149                 # Store the last status for use by fresh_status_msg later 
    150                 # Also converts old style status messages 
    151                 ($check_rv, $check_metric) = 
    152                 Resmon::Module::set_status($monobj, $check_rv, $check_metric); 
    153             } 
    154             my $checkstat = $@; 
    155             my $confighash = {}; 
    156             eval { $confighash = $monobj->config_as_hash(); }; 
     147                # Store the last metrics for use by fresh_status_msg later 
     148                Resmon::Module::cache_metrics($monobj, $check_metric); 
     149            }; 
     150            my $checkproblem = $@; 
    157151            my $results = { 
    158                 #configuration => $confighash, 
    159                 last_runtime_seconds => sprintf("%.6f", tv_interval($starttime)) 
     152                last_runtime_seconds => sprintf("%.6f", 
     153                    tv_interval($starttime)), 
     154                metric => $check_metric 
    160155            }; 
    161             if($checkstat) { 
    162                 $results->{state} = 'BAD'; 
     156            if($checkproblem) { 
    163157                $results->{metric} = { "message" => 
    164158                    "Bad module or problem running handler code."}; 
    165                 if ($checkstat eq "alarm\n") { 
    166                     $results->{metric} = { "message" => 
    167                         "Check timeout"}; 
     159                if ($checkproblem eq "alarm\n") { 
     160                    $results->{metric} = { "message" => "Check timeout"}; 
    168161                    Resmon::ExtComm::clean_up; 
    169                 } 
    170             } else { 
    171                 $results->{state} = $check_rv; 
    172                 if (ref($check_metric) eq "HASH") { 
    173                     my $metric = {}; 
    174                     while(my ($k, $v) = each %$check_metric) { 
    175                         $metric->{$k} = $v; 
    176                     } 
    177                     $results->{metric} = $metric; 
    178                 } else { 
    179                     $results->{metric} = { "message" => $check_metric }; 
    180162                } 
    181163            } 
    182164            $status->store($module_name,$monobj->{'object'}, $results); 
    183             printf("%s: %s\n%s\n", $module_name, $monobj->{'object'}, 
    184                 Dumper($results)) if $debug; 
     165            my $metrics_output = ""; 
     166            while (my ($k, $v) = each (%$check_metric)) { 
     167                if (ref($v) eq "ARRAY") { 
     168                    $v = $v->[0]; 
     169                } 
     170                $metrics_output .= "    $k = $v\n"; 
     171            } 
     172            printf("%s`%s\n%s\n", $module_name, $monobj->{'object'}, 
     173                $metrics_output) if $debug; 
    185174        } 
    186175    }