|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /usr/local/src/munin-1.2.6/server/ |
Upload File : |
package Munin;
# -*- perl -*-
#
# Copyright (C) 2003-2004 Jimmy Olsen, Audun Ytterdal
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
#
# $Id: Munin.pm.in 1599 2008-04-26 20:56:24Z matthias $
#
use Exporter;
@ISA = ('Exporter');
@EXPORT = ('munin_trend',
'munin_fetch',
'munin_nscasend',
'munin_createlock',
'munin_removelock',
'munin_runlock',
'munin_getlock',
'munin_readconfig',
'munin_writeconfig',
'munin_delete',
'munin_overwrite',
'munin_config',
'munin_draw_field',
'munin_get_bool',
'munin_get_bool_val',
'munin_get',
'munin_field_status',
'munin_service_status',
'munin_node_status',
'munin_category_status',
'munin_get_picture_filename',
'munin_get_filename',
'munin_graph_column_headers',
'munin_get_max_label_length',
'munin_get_field_order',
'munin_get_rrd_filename'
);
use strict;
use RRDs;
use Fcntl qw(:DEFAULT :flock);
use IO::Handle;
use Symbol 'gensym';
my $VERSION = "@@VERSION@@";
my $nsca = new IO::Handle;
my $config = undef;
my $DEBUG=0;
my $configfile="@@CONFDIR@@/munin.conf";
my @legal = ("tmpldir", "ncsa", "ncsa_server", "ncsa_config", "rundir",
"dbdir", "logdir", "htmldir", "include", "domain_order", "node_order",
"graph_order", "graph_sources", "fork", "graph_title", "create_args",
"graph_args", "graph_vlabel", "graph_vtitle", "graph_total",
"graph_scale", "graph", "update", "host_name", "label", "cdef", "draw",
"graph", "max", "min", "negative", "skipdraw", "type", "warning",
"critical", "special_stack", "special_sum", "stack", "sum", "address",
"htaccess", "warn", "use_default_name", "use_node_name", "port",
"graph_noscale", "nsca", "nsca_server", "nsca_config", "extinfo",
"fetch_data", "filename", "max_processes", "nagios", "info",
"graph_info", "graph_category", "graph_strategy", "graph_width",
"graph_height", "graph_sums", "local_address", "compare",
"text", "command", "contact", "contacts", "max_messages",
"always_send", "notify_alias", "line", "state", "graph_period",
"cgiurl_graph", "cgiurl", "service_order", "category_order",
"version", "colour", "ok", "unknown"
);
my %legal_expanded = map { $_ => 1 } @legal;
# Fields to copy when "aliasing" a field
my @copy_fields = ("label", "draw", "type", "rrdfile", "fieldname", "info");
sub munin_trend {
my (@array) = @_;
return ($array[$#array] - $array[0]);
}
sub munin_fetch {
my ($file,$last,$type) = @_;
my ($start,$step,$names,$data) = RRDs::fetch $file,$type || "AVERAGE";
unless (defined $data)
{
::logger ("Could not fetch data from $file(".($type||"AVERAGE")."): ". RRDs::error);
return undef;
}
my @array = map { @$_[0] } splice(@$data, $#$data - ($last || 1));
return $array[0] if (!$last);
return @array;
}
sub munin_draw_field {
my $node = shift;
my $service = shift;
my $field = shift;
$field =~ s/=.*//;
print "DEBUG: munin_draw_field: Checking $service -> $field: " . &munin_get_bool_val ($node->{client}->{$service}->{$field.".graph"}, 1) . ".\n" if $DEBUG;;
return 0 if (exists $node->{client}->{$service}->{$field.".skipdraw"});
return (&munin_get_bool_val ($node->{client}->{$service}->{$field.".graph"}, 1));
}
sub munin_nscasend {
my ($name,$service,$label,$level,$comment) = @_;
if (!$nsca->opened)
{
open ($nsca ,"|$config->{nsca} $config->{nsca_server} -c $config->{nsca_config} -to 60");
}
if ($label)
{
print $nsca "$name\t$service: $label\t$level\t$comment\n";
print ("$name;$service: $label;$level;$comment\n") if $DEBUG;
}
else
{
print $nsca "$name\t$service\t$level\t$comment\n";
print ("$name;$service;$level;$comment\n") if $DEBUG;
}
}
sub munin_createlock {
# Create lock file, fail and die if not possible.
my ($lockname) = @_;
if (sysopen (LOCK,$lockname,O_WRONLY | O_CREAT | O_EXCL)) {
print "Creating lock : $lockname succeded\n" if $DEBUG;
print LOCK $$; # we want the pid inside for later use
close LOCK;
return 1;
} else {
die "Creating lock $lockname failed: $!\n";
}
}
sub munin_removelock {
# Remove lock or die trying.
my ($lockname) = @_;
unlink $lockname or
die "Error deleting lock $lockname: $!\n";
}
sub munin_runlock {
my ($lockname) = @_;
unless (&munin_getlock($lockname)) {
print "Lock already exists: $lockname. Dying.\n";
exit 0;
}
return 1;
}
sub munin_getlock {
my ($lockname) = @_;
if (-f $lockname) {
# Is the lockpid alive?
# To check this is inteligent and so on. It also makes for a
# nice locking racing-condition. BUT, since munin-* runs from
# cron every 5 minutes this should not be a real threat. This
# ream of code should complete in less than 5 minutes.
open LOCK,$lockname or
die "Could not open $lockname for reading: $!\n";
my $pid = <LOCK>;
close(LOCK) or die "Could not close $lockname: $!\n";
# Make sure it's a proper pid
if (defined($pid) and $pid =~ /^(\d+)$/ and $1 != 1) {
$pid = $1;
if (kill(0, $pid)) {
return 0;
}
}
&munin_removelock($lockname);
}
&munin_createlock($lockname);
return 1;
}
sub munin_delete {
my ($config,$data) = @_;
for my $domain (keys %{$data->{domain}}) {
unless ($config->{domain}->{$domain}) {
::logger("Removing domain: $domain");
delete ($data->{domain}->{$domain});
next;
}
for my $node (keys %{$data->{domain}->{$domain}->{node}}) {
unless ($config->{domain}->{$domain}->{node}->{$node}) {
::logger("Removing node from $domain: $node");
delete ($data->{domain}->{$domain}->{node}->{$node});
}
}
}
return ($data);
}
sub munin_overwrite {
my ($configfile,$overwrite) = @_;
for my $key (keys %$overwrite) {
if (ref $overwrite->{$key}) {
&munin_overwrite($overwrite->{$key},$configfile->{$key});
}
$configfile->{$key} = $overwrite->{$key};
}
return ($configfile);
}
sub munin_readconfig {
my ($conf, $missingok, $corruptok) = @_;
my $config = undef;
my @contents = undef;
$conf ||= $configfile;
if (! -r $conf and ! $missingok) {
::logger ("munin_readconfig: cannot open '$conf'");
return undef;
}
if (open (CFG, $conf))
{
@contents = <CFG>;
close (CFG);
}
$config = &munin_parse_config (\@contents);
# Some important defaults before we return...
$config->{'rundir'} ||= "/tmp/";
$config->{'dbdir'} ||= "/var/lib/munin/";
$config->{'logdir'} ||= "/var/log/";
$config->{'tmpldir'}||= "/etc/munin/templates/";
$config->{'htmldir'}||= "@@HTMLDIR@@/";
return ($config);
}
sub munin_parse_config
{
my $lines = shift;
my $hash = undef;
my $prefix = "";
my $prevline = "";
foreach my $line (@{$lines})
{
chomp $line;
#$line =~ s/(^|[^\\])#.*/$1/g if $line =~ /#/; # Skip comments...
if ($line =~ /#/)
{
next if ($line =~ /^#/);
$line =~ s/(^|[^\\])#.*/$1/g;
}
next unless ($line =~ /\S/); # And empty lines...
if (length $prevline)
{
$line = $prevline . $line;
$prevline = "";
}
if ($line =~ /\\\\$/)
{
$line =~ s/\\\\$/\\/;
}
elsif ($line =~ /\\$/)
{
($prevline = $line) =~ s/\\$//;
next;
}
$line =~ s/\s+$//g; # And trailing whitespace...
$line =~ s/^\s+//g; # And heading whitespace...
if ($line =~ /^\.(\S+)\s+(.+)\s*$/)
{
my ($var, $val) = ($1, $2);
$hash = &munin_set_var_path ($hash, $var, $val);
}
elsif ($line =~ /^\s*\[([^\]]*)]\s*$/)
{
$prefix = $1;
if ($prefix =~ /^([^:;]+);([^:;]+)$/)
{
$prefix .= ":";
}
elsif ($prefix =~ /^([^:;]+);$/)
{
$prefix .= "";
}
elsif ($prefix =~ /^([^:;]+);([^:;]+):(.*)$/)
{
$prefix .= ".";
}
elsif ($prefix =~ /^([^:;]+)$/)
{
(my $domain = $prefix) =~ s/^[^\.]+\.//;
$prefix = "$domain;$prefix:";
}
elsif ($prefix =~ /^([^:;]+):(.*)$/)
{
(my $domain = $prefix) =~ s/^[^\.]+\.//;
$prefix = "$domain;$prefix.";
}
}
elsif ($line =~ /^\s*(\S+)\s+(.+)\s*$/)
{
my ($var, $val) = ($1, $2);
$hash = &munin_set_var_path ($hash, "$prefix$var", $val);
}
else
{
warn "Malformed configuration line \"$line\".";
}
}
return $hash;
}
sub munin_get_var_path
{
my $hash = shift;
my $var = shift;
my $val = shift;
print "DEBUG: Getting var \"$var\" = \"$val\"\n" if $DEBUG;
if ($var =~ /^\s*([^;:]+);([^;:]+):(\S+)\s*$/)
{
my ($dom, $host, $rest) = ($1, $2, $3);
my @sp = split (/\./, $rest);
if (@sp == 3)
{
return $hash->{domain}->{$dom}->{node}->{$host}->{client}->{$sp[0]}->{"$sp[1].$sp[2]"};
}
elsif (@sp == 2)
{
return $hash->{domain}->{$dom}->{node}->{$host}->{client}->{$sp[0]}->{$sp[1]};
}
elsif (@sp == 1)
{
return $hash->{domain}->{$dom}->{node}->{$host}->{$sp[0]};
}
else
{
warn "munin_set_var: Malformatted variable path \"$var\".";
}
}
elsif ($var =~ /^\s*([^;:]+);([^;:]+)\s*$/)
{
my ($dom, $rest) = ($1, $2);
my @sp = split (/\./, $rest);
if (@sp == 1)
{
return $hash->{domain}->{$dom}->{$sp[0]};
}
else
{
warn "munin_set_var: Malformatted variable path \"$var\".";
}
}
elsif ($var =~ /^\s*([^;:\.]+)\s*$/)
{
return $hash->{$1};
}
else
{
warn "munin_set_var: Malformatted variable path \"$var\".";
}
return undef;
}
sub munin_set_var_path
{
my $hash = shift;
my $var = shift;
my $val = shift;
print "DEBUG: Setting var \"$var\" = \"$val\"\n" if $DEBUG;
if ($var =~ /^\s*([^;:]+);([^:]+):(\S+)\s*$/)
{
my ($dom, $host, $rest) = ($1, $2, $3);
my @sp = split (/\./, $rest);
if (@sp == 3)
{
::logger ("Warning: Unknown option \"$sp[2]\" in \"$dom;$host:$sp[0].$sp[1].$sp[2]\".")
unless defined $legal_expanded{$sp[2]};
$hash->{domain}->{$dom}->{node}->{$host}->{client}->{$sp[0]}->{"$sp[1].$sp[2]"} = $val;
}
elsif (@sp == 2)
{
::logger ("Warning: Unknown option \"$sp[1]\" in \"$dom;$host:$sp[0].$sp[1]\".")
unless defined $legal_expanded{$sp[1]};
$hash->{domain}->{$dom}->{node}->{$host}->{client}->{$sp[0]}->{$sp[1]} = $val;
}
elsif (@sp == 1)
{
::logger ("Warning: Unknown option \"$sp[0]\" in \"$dom;$host:$sp[0]\".")
unless defined $legal_expanded{$sp[0]};
$hash->{domain}->{$dom}->{node}->{$host}->{$sp[0]} = $val;
}
else
{
warn "munin_set_var: Malformatted variable path \"$var\".";
}
}
elsif ($var =~ /^\s*([^;:]+);([^;:]+)\s*$/)
{
my ($dom, $rest) = ($1, $2);
my @sp = split (/\./, $rest);
if (@sp == 1)
{
::logger ("Warning: Unknown option \"$sp[0]\" in \"$dom;$sp[0]\".")
unless defined $legal_expanded{$sp[0]};
$hash->{domain}->{$dom}->{$sp[0]} = $val;
}
else
{
warn "munin_set_var: Malformatted variable path \"$var\".";
}
}
elsif ($var =~ /^\s*([^;:\.]+)\s*$/)
{
::logger ("Warning: Unknown option \"$1\" in \"$1\".")
unless defined $legal_expanded{$1};
$hash->{$1} = $val;
}
elsif ($var =~ /^\s*([^\.]+)\.([^\.]+)\.([^\.]+)$/)
{
::logger ("Warning: Unknown option \"$1\" in \"$var\".")
unless defined $legal_expanded{$1};
::logger ("Warning: Unknown option \"$3\" in \"$var\".")
unless defined $legal_expanded{$3};
$hash->{$1}->{$2}->{$3} = $val;
}
else
{
warn "munin_set_var: Malformatted variable path \"$var\".";
}
return $hash;
}
sub munin_writeconfig_loop {
my ($data,$fh,$pre) = @_;
$pre |= "";
# Write datafile
foreach my $a (keys %{$data})
{
if (ref ($data->{$a}) eq "HASH")
{
if ($a eq "domain" or $a eq "node" or $a eq "client")
{
&munin_writeconfig_loop ($data->{$a}, $fh, "$pre");
}
elsif ($a eq "contact" and $pre eq "")
{
&munin_writeconfig_loop ($data->{$a}, $fh, "contact.");
}
else
{
my $lpre = $pre;
if ($lpre eq "")
{
$lpre = $a.";";
}
elsif ($lpre =~ /;$/)
{
$lpre .= $a.":";
}
else
{
$lpre .= $a.".";
}
&munin_writeconfig_loop ($data->{$a}, $fh, "$lpre");
}
}
elsif (defined $data->{$a} and length $data->{$a})
{
next if "$pre$a" eq "version"; # Handled separately
print "Writing: $pre$a $data->{$a}\n" if $DEBUG;
if ($data->{$a} =~ /\\$/)
{ # Backslash as last char has special meaning. Avoid it.
print $fh "$pre$a $data->{$a}\\\n";
} else {
print $fh "$pre$a $data->{$a}\n";
}
}
}
}
sub munin_writeconfig {
my ($datafilename,$data,$fh) = @_;
# my $datafile = new Config::General();
# $datafile->save_file($datafilename,$data);
if (!defined $fh)
{
$fh = gensym();
unless (open ($fh, ">$datafilename"))
{
die "Fatal error: Could not open \"$datafilename\" for writing: $!";
}
}
# Write version
print $fh "version $VERSION\n";
# Write datafile
&munin_writeconfig_loop ($data, $fh, "");
if (defined $fh)
{
print "DEBUG: Closing filehandle \"$datafilename\"...\n" if $DEBUG;
close ($fh);
}
}
sub munin_config {
my $conffile = shift;
$config = shift;
$conffile ||= $configfile;
$config = &munin_readconfig ($conffile);
::logger_open ($config->{logdir});
my $data = &munin_readconfig("$config->{dbdir}/datafile", 1, 1);
$data = &munin_overwrite($data,$config);
return ($data);
}
sub munin_get_picture_filename {
my $config = shift;
my $domain = shift;
my $name = shift;
my $service = shift;
my $scale = shift;
my $sum = shift;
my $dir = $config->{'htmldir'};
# Sanitise
$dir =~ s/[^\w_\/"'\[\]\(\)+=-]\./_/g;
$domain =~ s/[^\w_\/"'\[\]\(\)+=\.-]/_/g;
$name =~ s/[^\w_\/"'\[\]\(\)+=\.-]/_/g;
$service =~ s/[^\w_\/"'\[\]\(\)+=-]/_/g;
$scale =~ s/[^\w_\/"'\[\]\(\)+=-]/_/g;
if (defined $sum and $sum)
{
return "$dir/$domain/$name-$service-$scale-sum.png";
}
else
{
return "$dir/$domain/$name-$service-$scale.png";
}
}
sub munin_get_filename {
my ($config,$domain,$node,$service,$field) = @_;
return ($config->{'dbdir'} . "/$domain/$node-$service-$field-" . lc substr (($config->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{$field.".type"}||"GAUGE"), 0,1). ".rrd");
}
sub munin_get_bool
{
my $conf = shift;
my $field = shift;
my $default = shift;
my $domain = shift;
my $node = shift;
my $service = shift;
my $plot = shift;
return undef unless defined $field;
my $ans = &munin_get ($conf, $field, $default, $domain, $node, $service, $plot);
return undef if not defined $ans;
if ($ans =~ /^yes$/i or
$ans =~ /^true$/i or
$ans =~ /^on$/i or
$ans =~ /^enable$/i or
$ans =~ /^enabled$/i
)
{
return 1;
}
elsif ($ans =~ /^no$/i or
$ans =~ /^false$/i or
$ans =~ /^off$/i or
$ans =~ /^disable$/i or
$ans =~ /^disabled$/i
)
{
return 0;
}
elsif ($ans !~ /\D/)
{
return $ans;
}
else
{
return undef;
}
}
sub munin_get_bool_val
{
my $field = shift;
my $default = shift;
if (!defined $field)
{
if (!defined $default)
{
return 0;
}
else
{
return $default;
}
}
if ($field =~ /^yes$/i or
$field =~ /^true$/i or
$field =~ /^on$/i or
$field =~ /^enable$/i or
$field =~ /^enabled$/i
)
{
return 1;
}
elsif ($field =~ /^no$/i or
$field =~ /^false$/i or
$field =~ /^off$/i or
$field =~ /^disable$/i or
$field =~ /^disabled$/i
)
{
return 0;
}
elsif ($field !~ /\D/)
{
return $field;
}
else
{
return undef;
}
}
sub munin_get
{
my $conf = shift;
my $field = shift;
my $default = shift;
my $domain = shift;
my $node = shift;
my $service = shift;
my $plot = shift;
if (defined $field)
{
return $conf->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{"$plot.$field"}
if (defined $domain and defined $node and defined $service and defined $plot and
defined $conf->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{"$plot.$field"});
return $conf->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{$field}
if (defined $domain and defined $node and defined $service and
defined $conf->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{$field});
return $conf->{domain}->{$domain}->{node}->{$node}->{$field}
if (defined $domain and defined $node and
defined $conf->{domain}->{$domain}->{node}->{$node}->{$field});
return $conf->{domain}->{$domain}->{$field}
if (defined $domain and defined $conf->{domain}->{$domain}->{$field});
return $conf->{$field}
if (defined $conf->{$field});
return $default;
}
else
{
return $conf->{domain}->{$domain}->{node}->{$node}->{client}->{$service}
if (defined $domain and defined $node and defined $service and
defined $conf->{domain}->{$domain}->{node}->{$node}->{client}->{$service});
return $conf->{domain}->{$domain}->{node}->{$node}
if (defined $domain and defined $node and
defined $conf->{domain}->{$domain}->{node}->{$node});
return $conf->{domain}->{$domain}
if (defined $domain and defined $conf->{domain}->{$domain});
return $conf
if (defined $conf);
return $default;
}
}
sub munin_node_status
{
my ($config, $limits, $domain, $node, $check_draw) = @_;
my $state = "ok";
return undef unless defined $config->{domain}->{$domain}->{node}->{$node};
my $snode = $config->{domain}->{$domain}->{node}->{$node};
foreach my $service (keys %{$snode})
{
my $fres = &munin_service_status ($config, $limits, $domain, $node, $service, $check_draw);
if (defined $fres)
{
if ($fres eq "critical")
{
$state = $fres;
last;
}
elsif ($fres eq "warning")
{
$state = $fres;
}
}
}
return $state;
}
sub munin_category_status
{
my ($config, $limits, $domain, $node, $category, $check_draw) = @_;
my $state = "ok";
return undef unless defined $config->{domain}->{$domain}->{node}->{$node};
my $snode = $config->{domain}->{$domain}->{node}->{$node};
foreach my $service (keys %{$snode->{client}})
{
next if ((not defined $snode->{client}->{$service}->{graph_category}) and
$category ne 'other');
next if ((defined $snode->{client}->{$service}->{graph_category}) and
($snode->{client}->{$service}->{graph_category} ne $category));
my $fres = &munin_service_status ($config, $limits, $domain, $node, $service, $check_draw);
if (defined $fres)
{
if ($fres eq "critical")
{
$state = $fres;
last;
}
elsif ($fres eq "warning")
{
$state = $fres;
}
}
}
return $state;
}
sub munin_service_status
{
my ($config, $limits, $domain, $node, $service, $check_draw) = @_;
my $state = "ok";
return undef unless defined $config->{domain}->{$domain}->{node}->{$node}->{client}->{$service};
foreach my $key (keys %{$config->{domain}->{$domain}->{node}->{$node}->{client}->{$service}})
{
next unless $key =~ /^([^\.]+)\.label$/;
my $field = $1;
my $fres = &munin_field_status ($config, $limits, $domain, $node, $service, $field, $check_draw);
if (defined $fres)
{
if ($fres eq "critical")
{
$state = $fres;
last;
}
elsif ($fres eq "warning")
{
$state = $fres;
}
}
}
return $state;
}
sub munin_field_status
{
my ($config, $limits, $domain, $node, $service, $field, $check_draw) = @_;
my $state = undef;
# Return undef if nagios is turned off, or the field doesn't have any limits
unless ((defined $config->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{"$field.warning"}) or
(defined $config->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{"$field.critical"}))
{
return undef;
}
if (defined $limits->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{"$field.critical"} and (!defined $check_draw or !$check_draw or
&munin_draw_field ($config->{domain}->{$domain}->{node}->{$node}, $service, $field)))
{
return "critical";
}
elsif (defined $limits->{domain}->{$domain}->{node}->{$node}->{client}->{$service}->{"$field.warning"} and (!defined $check_draw or !$check_draw or
&munin_draw_field ($config->{domain}->{$domain}->{node}->{$node}, $service, $field)))
{
return "warning";
}
else
{
return "ok";
}
}
sub munin_graph_column_headers
{
my ($config, $domain, $node, $serv) = @_;
my $ret = 0;
my @fields = ();
foreach my $field (keys %{$config->{domain}->{$domain}->{node}->{$node}->{client}->{$serv}})
{
if ($field =~ /^([^\.]+)\.negative$/ and munin_draw_field ($config->{domain}->{$domain}->{node}->{$node}, $serv, $1))
{
return 1;
}
elsif ($field =~ /^([^\.]+)\.label$/ and munin_draw_field ($config->{domain}->{$domain}->{node}->{$node}, $serv, $1))
{
push @fields, $1;
}
}
return 1 if (munin_get_max_label_length ($config->{'domain'}->{$domain}->{'node'}->{$node}, $config, $domain, $node, $serv, \@fields) > 20);
return $ret;
}
sub munin_get_max_label_length
{
my $node = shift;
my $config = shift;
my $domain = shift;
my $host = shift;
my $service = shift;
my $order = shift;
my $result = 0;
for my $field (@$order) {
my $path = undef;
(my $f = $field) =~ s/=.+//;
next if (exists $node->{client}->{$service}->{$f.".process"} and
$node->{client}->{$service}->{$f.".process"} ne "yes");
next if (exists $node->{client}->{$service}->{$f.".skipdraw"});
next unless (!exists $node->{client}->{$service}->{$f.".graph"} or
$node->{client}->{$service}->{$f.".graph"} eq "yes");
if ($result < length ($node->{client}->{$service}->{$f.".label"} || $f)) {
$result = length ($node->{client}->{$service}->{$f.".label"} || $f);
}
if (exists $node->{client}->{$service}->{graph_total} and
length $node->{client}->{$service}->{graph_total} > $result)
{
$result = length $node->{client}->{$service}->{graph_total};
}
}
return $result;
}
sub munin_get_field_order
{
my $node = shift;
my $config = shift;
my $domain = shift;
my $host = shift;
my $service = shift;
my $result = [];
if ($node->{client}->{$service}->{graph_sources})
{
foreach my $gs (split /\s+/, $node->{client}->{$service}->{'graph_sources'})
{
push (@$result, "-".$gs);
}
}
if ($node->{client}->{$service}->{graph_order})
{
push (@$result, split /\s+/, $node->{client}->{$service}->{'graph_order'});
}
for my $key (keys %{$node->{client}->{$service}})
{
my ($client,$type)="";
($client,$type) = split /\./,$key;
if (defined $type and $type eq "label")
{
push @$result,$client if !grep /^\Q$client\E(?:=|$)/, @$result;;
}
}
return $result;
}
sub munin_get_rrd_filename {
my $node = shift;
my $config = shift;
my $domain = shift;
my $name = shift;
my $service = shift;
my $field = shift;
my $path = shift;
my $result = "unknown";
if ($node->{client}->{$service}->{$field.".filename"})
{
$result = $node->{client}->{$service}->{$field.".filename"};
}
elsif ($path)
{
if (!defined ($node->{client}->{$service}->{$field.".label"}))
{
print "DEBUG: Setting label: $field\n" if $DEBUG;
$node->{client}->{$service}->{$field.".label"} = $field;
}
if ($path =~ /^\s*([^:;]+)[:;]([^:]+):([^:\.]+)[:\.]([^:\.]+)\s*$/)
{
$result = munin_get_filename ($config, $1, $2, $3, $4);
print "\nDEBUG1: Expanding $path...\n" if $DEBUG;
if (! defined $node->{client}->{$service}->{$field."label"})
{
for my $f (@copy_fields)
{
if (not exists $node->{client}->{$service}->{"$field.$f"} and
exists $config->{'domain'}->{$1}->{'node'}->{$2}->{'client'}->{$3}->{"$4.$f"})
{
$node->{client}->{$service}->{"$field.$f"} = $config->{'domain'}->{$1}->{'node'}->{$2}->{'client'}->{$3}->{"$4.$f"};
}
}
}
}
elsif ($path =~ /^\s*([^:]+):([^:\.]+)[:\.]([^:\.]+)\s*$/)
{
print "\nDEBUG2: Expanding $path...\n" if $DEBUG;
$result = munin_get_filename ($config, $domain, $1, $2, $3);
for my $f (@copy_fields)
{
if (not exists $node->{client}->{$service}->{"$field.$f"} and
exists $config->{'domain'}->{$domain}->{'node'}->{$1}->{'client'}->{$2}->{"$3.$f"})
{
print "DEBUG: Copying $f...\n" if $DEBUG;
$node->{client}->{$service}->{"$field.$f"} = $config->{'domain'}->{$domain}->{'node'}->{$1}->{'client'}->{$2}->{"$3.$f"};
}
}
}
elsif ($path =~ /^\s*([^:\.]+)[:\.]([^:\.]+)\s*$/)
{
print "\nDEBUG3: Expanding $path...\n" if $DEBUG;
$result = munin_get_filename ($config, $domain, $name, $1, $2);
for my $f (@copy_fields)
{
if (not exists $node->{client}->{$service}->{"$field.$f"} and
exists $node->{client}->{$1}->{"$2.$f"})
{
$node->{client}->{$service}->{"$field.$f"} = $node->{client}->{$1}->{"$2.$f"};
}
}
}
elsif ($path =~ /^\s*([^:\.]+)\s*$/)
{
print "\nDEBUG4: Expanding $path...\n" if $DEBUG;
$result = munin_get_filename ($config, $domain, $name, $service, $1);
for my $f (@copy_fields)
{
if (not exists $node->{client}->{$service}->{"$field.$f"} and
exists $node->{client}->{$service}->{"$1.$f"})
{
$node->{client}->{$service}->{"$field.$f"} = $node->{client}->{$service}->{"$1.$f"};
}
}
}
}
else
{
print "\nDEBUG5: Doing path...\n" if $DEBUG;
$result = munin_get_filename($config, $domain,$name,$service,$field);
}
return $result;
}
1;
# vim: syntax=perl ts=8