Changeset 1495

Show
Ignore:
Timestamp:
02/27/08 23:35:07 (4 years ago)
Author:
jo
Message:

Intermediate checkin of multilevel-groups. A lot better munin-limits, but still not working properly.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • people/jo/multilevel-groups-2/server/Munin.pm.in

    r1494 r1495  
    433433 
    434434    if (ref ($hash) eq "HASH") { 
    435         ::logger ("Debug: Searching for $field in " . join ('::', @{munin_get_node_loc ($hash)})); 
    436435        foreach my $key (keys %{$hash}) { 
    437436            next if $key =~ /^#%#/; 
  • people/jo/multilevel-groups-2/server/munin-limits.in

    r1494 r1495  
    106106} 
    107107 
    108 # Make array of what is probably to check for notifications 
     108# Make array of what needs to be checked 
     109my %work_hash_tmp; 
    109110my $work_array = []; 
    110 push @$work_array, map { munin_get_parent_node ($_) } @{munin_find_field($config, qr/^(critical|warning|crit|warn)$/)}; 
     111foreach my $workfield (@{munin_find_field ($config, qr/^(critical|warning|crit|warn)/)}) { 
     112    my $parent = munin_get_parent ($workfield); 
     113    if (!defined $work_hash_tmp{$parent}) { 
     114        $work_hash_tmp{$parent} = 1; 
     115        push @$work_array, $parent; 
     116    } 
     117
     118 
     119# Process array containing services we need to check 
     120foreach my $workservice (@$work_array) { 
     121    process_service ($workservice); 
     122
    111123 
    112124&munin_writeconfig ("$config->{dbdir}/limits", \%notes); 
     
    121133 
    122134sub process_service { 
    123     my $hash      = shift || return undef; 
    124     my $hostobj   = munin_get_parent ($hash); 
    125     my $domainobj = munin_get_parent (munin_get_parent ($hash)); 
    126     my $service   = munin_get_node_name ($hash); 
    127     my $host      = munin_get_node_name ($hostobj); 
    128     my $domain    = munin_get_node_name ($domainobj); 
    129     my $children  = munin_get_children ($hash); 
     135    my $hash      = shift || return undef; 
     136    my $parentobj  = munin_get_parent ($hash); 
     137    my $gparentobj = munin_get_parent (munin_get_parent ($hash)); 
     138    my $service    = munin_get_node_name ($hash); 
     139    my $parent     = munin_get_node_name ($parentobj); 
     140    my $gparent    = munin_get_node_name ($gparentobj); 
     141    my $children  = munin_get_children ($hash); 
    130142 
    131143    # Some fields that are nice to have in the plugin output 
     
    133145    $hash->{'plugin'} = $service; 
    134146    $hash->{'graph_title'} = $hash->{'notify_alias'} if defined $hash->{'notify_alias'}; 
    135     $hash->{'host'} = munin_get ($hostobj, "notify_alias", $host); 
    136     $hash->{'group'} = munin_get ($domainobj, "notify_alias", $domain); 
    137     $hash->{'worst'} = "OK"; 
     147    $hash->{'host'} = munin_get ($parentobj, "notify_alias", $parent); 
     148    $hash->{'group'} = munin_get ($gparentobj, "notify_alias", $gparent); 
     149    $hash->{'worst'} = "ok"; 
    138150    $hash->{'worstid'} = 0 unless defined $hash->{'worstid'}; 
    139151 
    140152    foreach my $field (@$children) { 
    141153        next if (!defined $field or ref ($field) ne "HASH"); 
    142         my $fname = munin_get_node_name ($field); 
    143         my $warn  = munin_get ($field, "warning", undef); 
    144         my $crit  = munin_get ($field, "critical", undef); 
     154        my $fname   = munin_get_node_name ($field); 
     155        my $warn    = munin_get ($field, "warning", undef); 
     156        my $crit    = munin_get ($field, "critical", undef); 
     157        my $path    = munin_get_node_loc ($field); 
     158        my $onfield = munin_get_node ($oldnotes, $path); 
    145159 
    146160        # Skip fields without warning/critical definitions 
     
    163177        # Some fields that are nice to have in the plugin output 
    164178        $field->{'value'} = $value; 
    165         $field->{'crange'} = (defined $critical->[0]?$critical->[0]:"").":".(defined $critical->[1]?$critical->[1]:""); 
    166         $field->{'wrange'} = (defined $warning->[0]?$warning->[0]:"").":".(defined $warning->[1]?$warning->[1]:""); 
    167  
    168         logger ("value: $domain -> $host -> $service -> $key : $value") if $DEBUG; 
    169             if ($value eq "unknown") { 
    170                 $critical->[0] ||= ""; 
    171                 $critical->[1] ||= ""; 
    172                 $hash->{'worst'} = "UNKNOWN" if $hash->{"worst"} eq "OK"; 
    173                 $hash->{'worstid'} = 3 if $hash->{"worstid"} == 0; 
    174                 $notes{$domain}{$name}{$clientname}{"$key.state"} = "unknown"; 
    175                 $notes{$domain}{$name}{$clientname}{"$key.unknown"} =  
    176                 (defined $client->{"$key.extinfo"} ? "unknown: " . $client->{"$key.extinfo"} : "Value is unknown."); 
    177                 if (!defined ($oldnotes->{'domain'}->{$domain}->{'node'}->{$name}->{'client'}->{$clientname}->{"$key.state"}) or  
    178                         $oldnotes->{'domain'}->{$domain}->{'node'}->{$name}->{'client'}->{$clientname}->{"$key.state"} ne "unknown") 
    179                 { 
    180                     $client->{'state_changed'} = 1; 
    181                 } 
     179        $field->{'crange'} = (defined $crit->[0]?$crit->[0]:"").":".(defined $crit->[1]?$crit->[1]:""); 
     180        $field->{'wrange'} = (defined $warn->[0]?$warn->[0]:"").":".(defined $warn->[1]?$warn->[1]:""); 
     181 
     182        logger ("value: ". join ('::', @{munin_get_node_loc ($hash)})) if $DEBUG; 
     183        if ($value eq "unknown") { 
     184            $crit->[0] ||= ""; 
     185            $crit->[1] ||= ""; 
     186            $hash->{'worst'} = "UNKNOWN" if $hash->{"worst"} eq "OK"; 
     187            $hash->{'worstid'} = 3 if $hash->{"worstid"} == 0; 
     188            munin_set_var_loc (\%notes, [$path, "state"], "unknown"); 
     189            munin_set_var_loc (\%notes, [$path, "unknown"], (defined $field->{"extinfo"} ? "unknown: " . $field->{"extinfo"} : "Value is unknown.")); 
     190 
     191            if (!defined $onfield or !defined $onfield->{"state"} or $onfield->{"state"} ne "unknown") { 
     192                $field->{'state_changed'} = 1; 
    182193            } 
    183             elsif ((defined ($critical->[0]) and $value < $critical->[0]) or 
    184             (defined ($critical->[1]) and $value > $critical->[1])) { 
    185                 $critical->[0] ||= ""; 
    186                 $critical->[1] ||= ""; 
    187                 $client->{'worst'} = "CRITICAL"; 
    188                 $client->{'worstid'} = 2; 
    189                 $notes{$domain}{$name}{$clientname}{"$key.state"} = "critical"; 
    190                 $notes{$domain}{$name}{$clientname}{"$key.critical"} =  
    191                 (defined $client->{"$key.extinfo"}? 
    192                 "$value (not in $critical->[0]:$critical->[1]): ". 
    193                 $client->{"$key.extinfo"}: 
    194                 "Value is $value. Critical range ($critical->[0]:$critical->[1]) exceeded"); 
    195                 if (!defined ($oldnotes->{'domain'}->{$domain}->{'node'}->{$name}->{'client'}->{$clientname}->{"$key.state"}) or  
    196                         $oldnotes->{'domain'}->{$domain}->{'node'}->{$name}->{'client'}->{$clientname}->{"$key.state"} ne "critical") 
    197                 { 
    198                     $client->{'state_changed'} = 1; 
    199                 } 
     194        } elsif ((defined ($crit->[0]) and $value < $crit->[0]) or 
     195                (defined ($crit->[1]) and $value > $crit->[1])) { 
     196            $crit->[0] ||= ""; 
     197            $crit->[1] ||= ""; 
     198            $hash->{'worst'} = "CRITICAL"; 
     199            $hash->{'worstid'} = 2; 
     200            munin_set_var_loc (\%notes, [$path, "state"], "critical"); 
     201            munin_set_var_loc (\%notes, [$path, "critical"],  
     202                (defined $field->{"extinfo"}?  
     203                "$value (not in $crit->[0]:$crit->[1]): ". 
     204                $field->{"extinfo"}: 
     205                "Value is $value. Critical range ($crit->[0]:$crit->[1]) exceeded")); 
     206 
     207            if (!defined $onfield or !defined $onfield->{"state"} or $onfield->{"state"} ne "critical") { 
     208                $field->{'state_changed'} = 1; 
    200209            } 
    201             elsif ((defined ($warning->[0]) and $value < $warning->[0]) or  
    202                 (defined ($warning->[1]) and $value > $warning->[1]))  
    203             { 
    204                 $warning->[0] ||= ""; 
    205                 $warning->[1] ||= ""; 
    206                 $client->{'worst'} = "WARNING" if $client->{"worst"} ne "CRITICAL"; 
    207                 $client->{'worstid'} = 1 if $client->{"worstid"} != 2; 
    208                 $notes{$domain}{$name}{$clientname}{"$key.state"} = "warning"; 
    209                 $notes{$domain}{$name}{$clientname}{"$key.warning"} =  
    210                 (defined $client->{"$key.extinfo"}? 
    211                 "$value (not in $warning->[0]:$warning->[1]): ". 
    212                 $client->{"$key.extinfo"}: 
    213                 "Value is $value. Warning range ($warning->[0]:$warning->[1]) exceeded"); 
    214                 if (!defined ($oldnotes->{'domain'}->{$domain}->{'node'}->{$name}->{'client'}->{$clientname}->{"$key.state"}) or  
    215                         $oldnotes->{'domain'}->{$domain}->{'node'}->{$name}->{'client'}->{$clientname}->{"$key.state"} ne "warning") 
    216                 { 
    217                     $client->{'state_changed'} = 1; 
    218                 } 
    219             }  
    220             elsif (defined ($oldnotes->{'domain'}->{$domain}->{'node'}->{$name}->{'client'}->{$clientname}->{"$key.state"}) or 
    221                     $force) 
    222             { 
    223                 $notes{$domain}{$name}{$clientname}{"$key.ok"} = "OK"; 
    224                 $client->{'state_changed'} = 1; 
     210        } elsif ((defined ($warn->[0]) and $value < $warn->[0]) or  
     211                (defined ($warn->[1]) and $value > $warn->[1]))  
     212        { 
     213            $warn->[0] ||= ""; 
     214            $warn->[1] ||= ""; 
     215            $hash->{'worst'} = "WARNING" if $hash->{"worst"} ne "CRITICAL"; 
     216            $hash->{'worstid'} = 1 if $hash->{"worstid"} != 2; 
     217            munin_set_var_loc (\%notes, [$path, "state"], "warning"); 
     218            munin_set_var_loc (\%notes, [$path, "warning"],  
     219                (defined $field->{"extinfo"}? 
     220                "$value (not in $warn->[0]:$warn->[1]): ". 
     221                $field->{"extinfo"}: 
     222                "Value is $value. Warning range ($warn->[0]:$warn->[1]) exceeded")); 
     223 
     224            if (!defined $onfield or !defined $onfield->{"state"} or $onfield->{"state"} ne "warning") { 
     225                $hash->{'state_changed'} = 1; 
    225226            } 
    226         } 
    227     } 
    228     generate_service_message ($domain, $name, $clientname, $client); 
     227        } elsif (defined $onfield and defined $onfield->{"state"} or $force) { 
     228            munin_set_var_loc (\%notes, [$path, "state"], "ok"); 
     229            munin_set_var_loc (\%notes, [$path, "warning"], "OK"); 
     230            $hash->{'state_changed'} = 1; 
     231        } 
     232    } 
     233    generate_service_message ($hash); 
    229234} 
    230235 
     
    237242    my $name = munin_get_node_name ($hash); 
    238243 
    239     if (defined $critical and $critical =~ /^\s*([-+\d.]*):([-+\d.]*)\s*$/) { 
     244    if (defined $crit and $crit =~ /^\s*([-+\d.]*):([-+\d.]*)\s*$/) { 
    240245        $critical[0] = $1 if length $1; 
    241246        $critical[1] = $2 if length $2; 
     
    264269 
    265270sub generate_service_message { 
    266     my $critical= undef; 
    267     my ($domain, $name,$clientname,$client) = @_; 
    268     return unless $client; 
    269     my $worst = ""; 
    270     my %stats = ('critical' => [], 'warning' => [], 'unknown' => [], 'foks' => [], 'ok' => []); 
    271  
    272     logger ("generating service message: $domain -> $name -> $clientname") if $DEBUG; 
    273     foreach my $key (keys %{$notes{$domain}{$name}{$clientname}}) 
    274     { 
    275         if ($key =~ /^([^\.]+)\.critical$/) 
    276         { 
    277             $worst = "critical"; 
    278             push @{$stats{'critical'}}, $1; 
    279         } 
    280         elsif ($key =~ /^([^\.]+)\.warning$/) 
    281         { 
    282             $worst = "warning" if $worst ne "critical"; 
    283             push @{$stats{'warning'}}, $1; 
    284         } 
    285         elsif ($key =~ /^([^\.]+)\.unknown$/) 
    286         { 
    287             $worst = "unknown" if (!$worst or $worst eq "ok"); 
    288             push @{$stats{'unknown'}}, $1; 
    289         } 
    290         elsif ($key =~ /^([^\.]+)\.ok$/) 
    291         { 
    292             $worst = "ok" unless $worst; 
    293             push @{$stats{'ok'}}, $1; 
    294             push @{$stats{'foks'}}, $1; 
    295         } 
    296         else 
    297         { 
    298             push @{$stats{'ok'}}, $1; 
    299         } 
    300     } 
    301     $client->{'cfields'}  = join " ", @{$stats{'critical'}}; 
    302     $client->{'wfields'}  = join " ", @{$stats{'warning'}}; 
    303     $client->{'ufields'}  = join " ", @{$stats{'unknown'}}; 
    304     $client->{'fofields'} = join " ", @{$stats{'foks'}}; 
    305     $client->{'ofields'}  = join " ", @{$stats{'ok'}}; 
    306     $client->{'numcfields'}  = scalar @{$stats{'critical'}}; 
    307     $client->{'numwfields'}  = scalar @{$stats{'warning'}}; 
    308     $client->{'numufields'}  = scalar @{$stats{'unknown'}}; 
    309     $client->{'numfofields'} = scalar @{$stats{'foks'}}; 
    310     $client->{'numofields'}  = scalar @{$stats{'ok'}}; 
    311  
    312     if ($worst) 
    313     { 
    314         foreach my $c (split (/\s+/, munin_get ($config, "contacts", join (' ', keys %{$config->{'contact'}}), $domain, $name, $clientname))) 
    315         { 
    316             next if $c eq "none"; 
    317             next unless defined $config->{'contact'}->{$c}->{'command'}; 
    318             if (@limit_contacts and !grep (/^$c$/, @limit_contacts)) 
    319             { 
    320                 next; 
     271    my $hash       = shift || return undef; 
     272    my $critical   = undef; 
     273    my $worst      = $hash->{"worst"}; 
     274    my %stats      = ('critical' => [], 'warning' => [], 'unknown' => [], 'foks' => [], 'ok' => []); 
     275    my $contacts   = munin_get_children (munin_get_node ($config, ["contacts"])); 
     276 
     277    logger ("generating service message: ". join ('::', @{munin_get_node_loc ($hash)})) if $DEBUG; 
     278    foreach my $field (@{munin_get_children ($hash)}) { 
     279        if (defined $field->{"state"}) { 
     280            push @{$stats{$field->{"state"}}}, munin_get_node_name ($field); 
     281            if ($field->{"state"} eq "ok") { 
     282                push @{$stats{"foks"}}, munin_get_node_name ($field); 
    321283            } 
    322             my $obsess = 0; 
    323             if (defined ($config->{'contact'}->{$c}->{'always_send'})) 
    324             { 
    325                 $obsess = grep {scalar(@{$stats{$_}})} (split (/\s+/, lc $config->{'contact'}->{$c}->{'always_send'})); 
     284        } 
     285    } 
     286    $hash->{'cfields'}  = join " ", @{$stats{'critical'}}; 
     287    $hash->{'wfields'}  = join " ", @{$stats{'warning'}}; 
     288    $hash->{'ufields'}  = join " ", @{$stats{'unknown'}}; 
     289    $hash->{'fofields'} = join " ", @{$stats{'foks'}}; 
     290    $hash->{'ofields'}  = join " ", @{$stats{'ok'}}; 
     291    $hash->{'numcfields'}  = scalar @{$stats{'critical'}}; 
     292    $hash->{'numwfields'}  = scalar @{$stats{'warning'}}; 
     293    $hash->{'numufields'}  = scalar @{$stats{'unknown'}}; 
     294    $hash->{'numfofields'} = scalar @{$stats{'foks'}}; 
     295    $hash->{'numofields'}  = scalar @{$stats{'ok'}}; 
     296 
     297    my $defaultcontacts = join (' ', map { munin_get_node_name ($_) } @$contacts); 
     298    foreach my $c (split (/\s+/, munin_get ($hash, "contacts", $defaultcontacts))) { 
     299        next if $c eq "none"; 
     300        my $contactobj = munin_get_node ($config, ["contact", $c]); 
     301        next unless defined $contactobj; 
     302        next unless defined munin_get ($contactobj, "command", undef); 
     303        if (@limit_contacts and !grep (/^$c$/, @limit_contacts)) { 
     304            next; 
     305        } 
     306        my $obsess = 0; 
     307        my $cas = munin_get ($contactobj, "always_send"); 
     308        if (defined $cas) { 
     309            $obsess = grep {scalar(@{$stats{$_}})} (split (/\s+/, lc $cas)); 
     310        } 
     311        if (!$hash->{'state_changed'} and !$obsess) { 
     312            next; # No need to send notification 
     313        } 
     314        my $precmd = munin_get ($contactobj, "command"); 
     315        my $pretxt = munin_get ($contactobj, "text", munin_get (munin_get_node ($config, ["contact", "default"]), "text", $default_text{$c} || $default_text{"default"})); 
     316        my $txt = message_expand ($pretxt, $hash, ""); 
     317        my $cmd = message_expand ($precmd, $hash, ""); 
     318        $txt =~ s/\\n/\n/g; 
     319        $txt =~ s/\\t/\t/g; 
     320 
     321        # In some cases we want to reopen the command 
     322        my $maxmess = munin_get ($contactobj, "max_messages", 0); 
     323        my $curmess = munin_get ($contactobj, "num_messages", 0); 
     324        my $curcmd  = munin_get ($contactobj, "pipe_command", undef); 
     325        my $pipe    = munin_get ($contactobj, "pipe", undef); 
     326        if ($maxmess and $curmess >= $maxmess ) { 
     327            close ($pipe); 
     328            $pipe = undef; 
     329            munin_set_var ($contactobj, "pipe", undef); 
     330        } elsif ($curcmd and $curcmd ne $cmd) { 
     331            close ($pipe); 
     332            $pipe = undef; 
     333            munin_set_var ($contactobj, "pipe", undef); 
     334        } 
     335     
     336        if (!defined $pipe) { 
     337            my @cmd = extract_multiple ( 
     338                    message_expand ($cmd), 
     339                    [ sub { extract_delimited ($_[0], q{"'})}, 
     340                      qr/\S+/ 
     341                    ], 
     342                    undef, 1); 
     343            @cmd = map { s/['"]$//; s/^['"]//; $_ } @cmd; 
     344            munin_set_var ($contactobj, "num_messages", 0); 
     345            if ($cmd[0] eq "|") { 
     346                $cmd[0] = "|-"; 
     347            } elsif ($cmd[0] !~ /^[|>]/) { 
     348                unshift (@cmd, "|-"); 
    326349            } 
    327             if (!$client->{'state_changed'} and !$obsess) 
    328             { 
    329                 next; 
    330             } 
    331             my $precmd = $config->{'contact'}->{$c}->{'command'}; 
    332             my $pretxt = ($config->{'contact'}->{$c}->{'text'} || $config->{'contact'}->{'default'}->{'text'} || $default_text{$c} || $default_text{'default'}); 
    333             my $txt = message_expand ($pretxt, $client, ""); 
    334             my $cmd = message_expand ($precmd, $client, ""); 
    335             $txt =~ s/\\n/\n/g; 
    336             $txt =~ s/\\t/\t/g; 
    337  
    338             # In some cases we want to reopen the command 
    339             if ($config->{'contact'}->{$c}->{'max_messages'} and defined ($config->{'contact'}->{$c}->{'num_messages'}) and 
    340                     $config->{'contact'}->{$c}->{'num_messages'} >= $config->{'contact'}->{$c}->{'max_messages'}) 
    341             { 
    342                 close ($config->{'contact'}->{$c}->{'pipe'}); 
    343                 $config->{'contact'}->{$c}->{'pipe'} = undef; 
    344             } 
    345             elsif (defined ($config->{'contact'}->{$c}->{'pipe_command'}) and  
    346                     $config->{'contact'}->{$c}->{'pipe_command'} ne $cmd) 
    347             { 
    348                 close ($config->{'contact'}->{$c}->{'pipe'}); 
    349                 $config->{'contact'}->{$c}->{'pipe'} = undef; 
    350             } 
    351          
    352             my $pipe; 
    353             if (!defined $config->{'contact'}->{$c}->{'pipe'}) 
    354             { 
    355                 my @cmd = extract_multiple ( 
    356                         message_expand ($cmd), 
    357                         [ sub { extract_delimited ($_[0], q{"'})}, 
    358                           qr/\S+/ 
    359                         ], 
    360                         undef, 1); 
    361                 @cmd = map { s/['"]$//; s/^['"]//; $_ } @cmd; 
    362                 $config->{'contact'}->{$c}->{'num_messages'} = 0; 
    363                 if ($cmd[0] eq "|") 
    364                 { 
    365                     $cmd[0] = "|-"; 
    366                 }  
    367                 elsif ($cmd[0] !~ /^[|>]/) 
    368                 { 
    369                     unshift (@cmd, "|-"); 
     350            logger ("Debug: opening for writing: \"" . join('" "',@cmd) . "\".") if $DEBUG; 
     351            if ($cmd[0] eq ">") { 
     352                if (! open ($pipe, join (' ', @cmd))) { 
     353                    logger ("Fatal: Could not open " . join (' ', @cmd[1 .. $#cmd]) . " for writing: $!"); 
     354                    exit 3; 
    370355                } 
    371                 logger ("Debug: opening for writing: \"" . join('" "',@cmd) . "\".") if $DEBUG; 
    372                 if ($cmd[0] eq ">") 
    373                 { 
    374                     if (! open ($pipe, join (' ', @cmd))) 
    375                     { 
    376                         logger ("Fatal: Could not open " . join (' ', @cmd[1 .. $#cmd]) . " for writing: $!"); 
     356            } else { 
     357                my $pid = open ($pipe, "|-"); 
     358                if (!defined $pid) { 
     359                    logger ("Fatal: Unable to  fork: $!"); 
     360                    exit 3; 
     361                } if (!$pid) { # Child 
     362                    # Fork of stdout-to-log filter 
     363                    my $logstdout; 
     364                    my $logstderr; 
     365                    my $logpid = open ($logstdout, "|-"); 
     366                    if (!defined $logpid) { 
     367                        logger ("Fatal: Unable to  fork: $!"); 
    377368                        exit 3; 
     369                    } if (!$logpid) { # Child 
     370                        while (<STDIN>) { 
     371                            chomp; 
     372                            logger ("Command \"$c\" stdout: $_"); 
     373                        } 
     374                        exit 0; 
    378375                    } 
    379                 } 
    380                 else 
    381                 { 
    382                     my $pid = open ($pipe, "|-"); 
    383                     if (!defined $pid) 
    384                     { 
     376                    close (STDOUT); 
     377                    *STDOUT = \$logstdout; 
     378                    my $logpid = open ($logstderr, "|-"); 
     379                    if (!defined $logpid) { 
    385380                        logger ("Fatal: Unable to  fork: $!"); 
    386381                        exit 3; 
    387382                    } 
    388                     if (!$pid) # Child 
    389                     { 
    390                         # Fork of stdout-to-log filter 
    391                         my $logstdout; 
    392                         my $logstderr; 
    393                         my $logpid = open ($logstdout, "|-"); 
    394                         if (!defined $logpid) 
    395                         { 
    396                             logger ("Fatal: Unable to  fork: $!"); 
    397                             exit 3; 
     383                    if (!$logpid) { # Child 
     384                        while (<STDIN>) { 
     385                            chomp; 
     386                            logger ("Command \"$c\" stderr: $_"); 
    398387                        } 
    399                         if (!$logpid) # Child 
    400                         { 
    401                             while (<STDIN>) 
    402                             { 
    403                                 chomp; 
    404                                 logger ("Command \"$c\" stdout: $_"); 
    405                             } 
    406                             exit 0; 
    407                         } 
    408                         close (STDOUT); 
    409                         *STDOUT = \$logstdout; 
    410                         my $logpid = open ($logstderr, "|-"); 
    411                         if (!defined $logpid) 
    412                         { 
    413                             logger ("Fatal: Unable to  fork: $!"); 
    414                             exit 3; 
    415                         } 
    416                         if (!$logpid) # Child 
    417                         { 
    418                             while (<STDIN>) 
    419                             { 
    420                                 chomp; 
    421                                 logger ("Command \"$c\" stderr: $_"); 
    422                             } 
    423                             exit 0; 
    424                         } 
    425                         close (STDERR); 
    426                         *STDERR = \$logstderr; 
    427  
    428                         exec (@cmd[1 .. $#cmd]) or logger ("Warning: Could not run command \"" . join(' ',@cmd[1 .. $#cmd]) . "\": $!"); 
    429                         exit 5; 
    430                         # NOTREACHED 
     388                        exit 0; 
    431389                    } 
    432                 } 
    433                 $config->{'contact'}->{$c}->{'pipe_command'} = $cmd; 
    434                 $config->{'contact'}->{$c}->{'pipe'} = $pipe; 
    435             }  
    436             $pipe = $config->{'contact'}->{$c}->{'pipe'}; 
    437             logger ("sending message: \"$txt\"") if ($DEBUG); 
    438             print $pipe $txt, "\n" if (defined $pipe); 
    439             $config->{'contact'}->{$c}->{'num_messages'}++; 
    440         } 
     390                    close (STDERR); 
     391                    *STDERR = \$logstderr; 
     392 
     393                    exec (@cmd[1 .. $#cmd]) or logger ("Warning: Could not run command \"" . join(' ',@cmd[1 .. $#cmd]) . "\": $!"); 
     394                    exit 5; 
     395                    # NOTREACHED 
     396                } 
     397            } 
     398            munin_set_var ($contactobj, "pipe_command", $cmd); 
     399            munin_set_var ($contactobj, "pipe", $pipe); 
     400        }  
     401        logger ("sending message: \"$txt\"") if ($DEBUG); 
     402        print $pipe $txt, "\n" if (defined $pipe); 
     403        munin_set_var ($contactobj, "num_messages", 1 + munin_get ($contactobj, "num_messages", 0)); # $num_messages++ 
    441404    } 
    442405} 
     
    444407 
    445408sub message_expand { 
     409    my $hash   = shift; 
    446410    my $text   = shift; 
    447     my $client = shift; 
    448     my $prefix = shift || ""; 
    449411    my @res    = (); 
    450412 
    451413     
    452     while (length ($text)) 
    453     {    
    454         if ($text =~ /^([^\$]+|)(?:\$(\{.*)|)$/) 
    455         { 
     414    while (length ($text)) {    
     415        if ($text =~ /^([^\$]+|)(?:\$(\{.*)|)$/) { 
    456416            push @res, $1; 
    457417            $text = $2; 
    458418        }    
    459419        my @a = extract_bracketed ($text, '{}'); 
    460         if ($a[0] =~ /^\{var:(\S+)\}$/) 
    461         { 
    462             $a[0] = (defined $client->{$prefix.$1} ? $client->{$prefix.$1} : ""); 
    463         } 
    464         elsif ($a[0] =~ /^\{loop<([^>]+)>:\s*(\S+)\s(.+)\}$/) 
    465         { 
     420        if ($a[0] =~ /^\{var:(\S+)\}$/) { 
     421            $a[0] = munin_get ($hash, $1, ""); 
     422        } elsif ($a[0] =~ /^\{loop<([^>]+)>:\s*(\S+)\s(.+)\}$/) { 
    466423            my $d = $1; 
    467424            my $f = $2; 
    468425            my $t = $3; 
     426            my $fields = munin_get ($hash, $f, ""); 
    469427            my @res  = (); 
    470             if (defined $client->{$f}) 
    471            
    472                 foreach my $sub (split /\s+/, $client->{$f}) 
    473                 { 
    474                     push @res, message_expand ($t, $client, $sub."."); 
     428            if ($fields) { 
     429               foreach my $sub (split /\s+/, $fields)
     430                    if (defined $hash->{$sub}) { 
     431                       push @res, message_expand ($hash->{$sub}, $t); 
     432                    } 
    475433                } 
    476434            }  
    477435            $a[0] = join ($d, @res); 
    478         } 
    479         elsif ($a[0] =~ /^\{loop:\s*(\S+)\s(.+)\}$/) 
    480         { 
     436        } elsif ($a[0] =~ /^\{loop:\s*(\S+)\s(.+)\}$/) { 
    481437            my $f = $1; 
    482438            my $t = $2; 
     439            my $fields = munin_get ($hash, $f, ""); 
    483440            my $res  = ""; 
    484             if (defined $client->{$f}) 
    485            
    486                 foreach my $sub (split /\s+/, $client->{$f}) 
    487                 { 
    488                     $res .= message_expand ($t, $client, $sub."."); 
     441            if ($fields) { 
     442               foreach my $sub (split /\s+/, $fields)
     443                    if (defined $hash->{$sub}) { 
     444                       push @res, message_expand ($hash->{$sub}, $t); 
     445                    } 
    489446                } 
    490447            }  
    491448            $a[0] = $res; 
    492         } 
    493         elsif ($a[0] =~ /^\{strtrunc:\s*(\S+)\s(.+)\}$/) 
    494         { 
     449        } elsif ($a[0] =~ /^\{strtrunc:\s*(\S+)\s(.+)\}$/) { 
    495450            my $f = "%.".$1."s"; 
    496451            my $t = $2; 
    497             $a[0] = sprintf ($f, message_expand ($t, $client, $prefix)); 
    498         } 
    499         elsif ($a[0] =~ /^\{if:\s*(\!)?(\S+)\s(.+)\}$/) 
    500         { 
     452            $a[0] = sprintf ($f, message_expand ($hash, $t)); 
     453        } elsif ($a[0] =~ /^\{if:\s*(\!)?(\S+)\s(.+)\}$/) { 
    501454            my $n = $1; 
    502455            my $f = $2; 
    503456            my $t = $3; 
    504457            my $res  = ""; 
    505             my $check = (defined $client->{$prefix.$f} and length($client->{$prefix.$f}) and $client->{$prefix.$f} ne "0"); 
    506  
    507             $check = (!defined $client->{$prefix.$f} or !length($client->{$prefix.$f}) or $client->{$prefix.$f} eq "0") 
    508                 if $n; 
    509  
    510             if ($check) 
    511             { 
    512                 $res .= message_expand ($t, $client, $prefix); 
     458            my $field = munin_get ($hash, $f, 0); 
     459            my $check = ($field ne "0" and length ($field)); 
     460            $check = (!length ($field) or $field eq "0") if $n; 
     461 
     462            if ($check) { 
     463                $res .= message_expand ($hash, $t); 
    513464            }  
    514465            $a[0] = $res; 
     
    524475    my $dirname = shift; 
    525476 
    526     if (!$log->opened) 
    527     { 
    528           unless (open ($log, ">>$dirname/munin-limits.log")) 
    529           { 
    530                   print STDERR "Warning: Could not open log file \"$dirname/munin-limits.log\" for writing: $!"; 
    531           } 
    532           else 
    533           { 
    534                   close (STDERR); 
    535                   *STDERR = \$log; 
    536                  
    537           } 
     477    if (!$log->opened) { 
     478        unless (open ($log, ">>$dirname/munin-limits.log")) { 
     479            print STDERR "Warning: Could not open log file \"$dirname/munin-limits.log\" for writing: $!"; 
     480        } else { 
     481            close (STDERR); 
     482            *STDERR = \$log; 
     483        } 
    538484    } 
    539485} 
     
    544490 
    545491  print "$now - $comment\n" if $stdout; 
    546   if ($log->opened) 
    547   { 
    548           print $log "$now - $comment\n"; 
    549   } 
    550   else 
    551   { 
    552           if (defined $config->{logdir}) 
    553           { 
    554                   if (open ($log, ">>$config->{logdir}/munin-graph.log")) 
    555                   { 
    556                           print $log "$now - $comment\n"; 
    557                           $log->flush; 
    558                           close (STDERR); 
    559                           open (STDERR, ">&", $log); 
    560                   } 
    561                   else 
    562                   { 
    563                           print STDERR "Warning: Could not open log file \"$config->{logdir}/munin-graph.log\" for writing: $!"; 
    564                           print STDERR "$now - $comment\n"; 
    565                   } 
    566           } 
    567           else 
    568           { 
    569                   print STDERR "$now - $comment\n"; 
    570           } 
     492  if ($log->opened) { 
     493      print $log "$now - $comment\n"; 
     494  } else { 
     495      if (defined $config->{logdir}) { 
     496          if (open ($log, ">>$config->{logdir}/munin-graph.log")) { 
     497              print $log "$now - $comment\n"; 
     498              $log->flush; 
     499              close (STDERR); 
     500              open (STDERR, ">&", $log); 
     501            } else { 
     502              print STDERR "Warning: Could not open log file \"$config->{logdir}/munin-graph.log\" for writing: $!"; 
     503              print STDERR "$now - $comment\n"; 
     504            } 
     505        } else { 
     506              print STDERR "$now - $comment\n"; 
     507        } 
    571508    } 
    572509}