Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 177568 Details for
Bug 253965
net-analyzer/munin-1.3.4-r1 cron "Pango-WARNING"
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Repaired munin-graph script
munin-graph (text/plain), 38.84 KB, created by
f1a989188a51186834a821708563800a
on 2009-01-06 12:25:42 UTC
(
hide
)
Description:
Repaired munin-graph script
Filename:
MIME Type:
Creator:
f1a989188a51186834a821708563800a
Created:
2009-01-06 12:25:42 UTC
Size:
38.84 KB
patch
obsolete
>#!/usr/bin/perl -w ># -*- cperl -*- ># ># Copyright (C) 2002-2008 Jimmy Olsen, Audun Ytterdal, Nicolai Langfeldt ># ># 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-graph.in 1525 2008-03-03 21:34:42Z jo $ > >$|=1; > >use strict; >use IO::Socket; >use RRDs; >use Munin; >use POSIX qw(strftime); >use Digest::MD5; >use Getopt::Long; >use Time::HiRes; > >if ($RRDs::VERSION >= 1.3) { use Encode; } > >my $graph_time= Time::HiRes::time; >my $DEBUG = 0; >my $VERSION = '1.3.4'; > ># Limit graphing to certain hosts and/or services >my @limit_hosts = (); >my @limit_services = (); > ># RRDtool 1.2 requires \\: in comments >my $RRDkludge = $RRDs::VERSION < 1.2 ? '' : '\\'; > ># And RRDtool 1.2 and later has draws lines with crayons so we hack ># the LINE* options a bit. >my $LINEkluge=0; >if ($RRDs::VERSION >= 1.2) { > $LINEkluge=1; >} > ># Force drawing of "graph no". >my $force_graphing = 0; >my $force_lazy = 1; >my $force_root = 0; >my $do_usage = 0; >my $do_version = 0; >my $cron = 0; >my $list_images = 0; >my $skip_locking = 0; >my $skip_stats = 0; >my $stdout = 0; >my $conffile = "/etc/munin/munin.conf"; >my %draw = ("day" => 1, "week" => 1, "month" => 1, "year" => 1, "sumyear" => 1, "sumweek" => 1); > >my $log = new IO::Handle; > ># Get options >$do_usage=1 unless >GetOptions ( "force!" => \$force_graphing, > "lazy!" => \$force_lazy, > "force-root!" => \$force_root, > "host=s" => \@limit_hosts, > "service=s" => \@limit_services, > "config=s" => \$conffile, > "stdout!" => \$stdout, > "day!" => \$draw{'day'}, > "week!" => \$draw{'week'}, > "month!" => \$draw{'month'}, > "year!" => \$draw{'year'}, > "sumweek!" => \$draw{'sumweek'}, > "sumyear!" => \$draw{'sumyear'}, > "list-images!" => \$list_images, > "skip-locking!"=> \$skip_locking, > "skip-stats!" => \$skip_stats, > "debug!" => \$DEBUG, > "version!" => \$do_version, > "cron!" => \$cron, > "help" => \$do_usage ); > >if ($do_usage) >{ > print "Usage: $0 [options] > >Options: > --[no]force Force drawing of graphs that are not usually > drawn due to options in the config file. [--noforce] > --[no]force-root Force running, even as root. [--noforce-root] > --[no]lazy Only redraw graphs when needed. [--lazy] > --help View this message. > --version View version information. > --debug View debug messages. > --[no]cron Behave as expected when run from cron. (Used internally > in Munin.) > --service <service> Limit graphed services to <service>. Multiple --service > options may be supplied. > --host <host> Limit graphed hosts to <host>. Multiple --host options > may be supplied. > --config <file> Use <file> as configuration file. [/etc/munin/munin.conf] > --[no]list-images List the filenames of the images created. > [--nolist-images] > --[no]day Create day-graphs. [--day] > --[no]week Create week-graphs. [--week] > --[no]month Create month-graphs. [--month] > --[no]year Create year-graphs. [--year] > --[no]sumweek Create summarised week-graphs. [--summweek] > --[no]sumyear Create summarised year-graphs. [--sumyear] > >"; > exit 0; >} > >if ($do_version) >{ >print <<"EOT"; >munin-graph version $VERSION. >Written by Audun Ytterdal, Jimmy Olsen, Tore Anderson / Linpro AS > >Copyright (C) 2002-2005 > >This is free software released under the GNU General Public License. There >is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR >PURPOSE. For details, please refer to the file COPYING that is included >with this software or refer to > http://www.fsf.org/licensing/licenses/gpl.txt >EOT > exit 0; >} > >if ($> == 0 and !$force_root) >{ > print "You are running this program as root, which is dumb and will >cause many problems later. Please run it as user 'munin'. >If you really want to run it as root, use the --force-root option. >Aborting.\n\n"; > exit (1); >} > >my $config= &munin_config ($conffile); > >if (&munin_get ($config, "graph_strategy", "cron") ne "cron" and $cron) >{ # We're run from cron, but munin.conf says we use dynamic graph generation > exit 0; >} > >munin_runlock("$config->{rundir}/munin-graph.lock") unless $skip_locking; > >unless ($skip_stats) { > open (STATS,">$config->{dbdir}/munin-graph.stats.tmp") or > logger("Unable to open $config->{dbdir}/munin-graph.stats.tmp"); >} > >logger("Starting munin-graph"); > >my %PALETTE; # Hash of available palettes >my @COLOUR; # Array of actuall colours to use > >{ > no warnings; > $PALETTE{'old'} = [ # This is the old munin palette. It lacks contrast. > qw(#22ff22 #0022ff #ff0000 #00aaaa #ff00ff > #ffa500 #cc0000 #0000cc #0080C0 #8080C0 #FF0080 > #800080 #688e23 #408080 #808000 #000000 #00FF00 > #0080FF #FF8000 #800000 #FB31FB > )]; > > $PALETTE{'default'} = [ # New default palette.Better contrast,more colours > #Greens Blues Oranges Dk yel Dk blu Purple lime Reds Gray > qw(#00CC00 #0066B3 #FF8000 #FFCC00 #330099 #990099 #CCFF00 #FF0000 #808080 > #008F00 #00487D #B35A00 #B38F00 #6B006B #8FB300 #B30000 #BEBEBE > #80FF80 #80C9FF #FFC080 #FFE680 #AA80FF #EE00CC #FF8080 > #666600 #FFBFFF #00FFCC #CC6699 #999900 > )]; # Line variations: Pure, earthy, dark pastel, misc colours >} > > >my $palette = &munin_get ($config, "palette", "default"); > >if (defined($PALETTE{$palette})) { > @COLOUR=@{$PALETTE{$palette}}; >} else { > die "Unknown palette named by 'palette' keyword: $palette\n"; >} > >my $range_colour = "#22ff22"; >my $single_colour = "#00aa00"; > >my %times = ( > "day" => "-30h", > "week" => "-8d", > "month" => "-33d", > "year" => "-400d"); > >my %resolutions = ( > "day" => "300", > "week" => "1500", > "month" => "7200", > "year" => "86400"); > >my %sumtimes = ( # time => [ label, seconds-in-period ] > "week" => ["hour", 12], > "year" => ["day", 288] > ); > >my $watermark = "Munin $VERSION"; > ># Make array of what is probably needed to graph >my $work_array = []; >if (@limit_hosts) { # Limit what to update if needed > foreach my $nodename (@limit_hosts) { > push @$work_array, map { @{munin_find_field ($_->{$nodename}, "graph_title")} } @{munin_find_field($config, $nodename)}; > } >} else { # ...else just search for all adresses to update > push @$work_array, @{munin_find_field($config, "graph_title")}; >} > > >for my $service (@$work_array) { > process_service ($service); >} > >$graph_time = sprintf ("%.2f",(Time::HiRes::time - $graph_time)); >logger("Munin-graph finished ($graph_time sec)"); >print STATS "GT|total|$graph_time\n" unless $skip_stats; >rename ("$config->{dbdir}/munin-graph.stats.tmp", "$config->{dbdir}/munin-graph.stats"); >close STATS unless $skip_stats; >close $log; > >munin_removelock("$config->{rundir}/munin-graph.lock") unless $skip_locking; > ># ### The End > >sub get_title { > my $service = shift; > my $scale = shift; > > return (munin_get ($service, "graph_title", $service) . " - by $scale"); >} > >sub get_custom_graph_args >{ > my $service = shift; > my $result = []; > > my $args = munin_get ($service, "graph_args"); > if (defined $args) { > push @$result, split /\s/,$args; > return $result; > } else { > return undef; > } >} > >sub get_vlabel >{ > my $service = shift; > my $scale = munin_get ($service, "graph_period", "second"); > my $res = munin_get ($service, "graph_vlabel", munin_get ($service, "graph_vtitle")); > > if (defined $res) { > $res =~ s/\$\{graph_period\}/$scale/g; > } > return $res; >} > >sub should_scale >{ > my $service = shift; > my $ret; > > if (!defined ($ret = munin_get_bool ($service, "graph_scale"))) { > $ret = !munin_get_bool ($service, "graph_noscale", 0); > } > > return $ret; >} > >sub get_header { > my $service = shift; > my $scale = shift; > my $sum = shift; > my $result = []; > my $tmp_field; > > # Picture filename > push @$result, munin_get_picture_filename ($service, $scale, $sum||undef); > > # Title > push @$result, ("--title", get_title ($service, $scale)); > > # When to start the graph > push @$result, "--start",$times{$scale}; > > # Custom graph args, vlabel and graph title > if (defined ($tmp_field = get_custom_graph_args ($service))) { > push (@$result, @{$tmp_field}); > } > if (defined ($tmp_field = get_vlabel ($service))) { > push @$result, ("--vertical-label", $tmp_field); > } > > push @$result,"--height", munin_get ($service, "graph_height", "175"); > push @$result,"--width", munin_get ($service, "graph_width", "400"); > push @$result,"--imgformat", "PNG"; > push @$result,"--lazy" if ($force_lazy); > > push (@$result, "--units-exponent", "0") if (! should_scale ($service)); > > return $result; >} > >sub get_sum_command >{ > my $field = shift; > > if (defined $field->{"special_sum"}) { # Deprecated > return $field->{"special_sum"}; > } > > return munin_get ($field, "sum"); >} > >sub get_stack_command >{ > my $field = shift; > > if (defined $field->{"special_stack"}) { # Deprecated > return $field->{"special_stack"}; > } > > return munin_get ($field, "stack"); >} > >sub expand_specials >{ > my $service = shift; > my $preproc = shift; > my $order = shift; > my $single = shift; > my $result = []; > > my $fieldnum = 0; > for my $field (@$order) { # Search for 'specials'... > my $tmp_field; > > if ($field =~ /^-(.+)$/) { # Invisible field > $field = $1; > munin_set_var_loc ($service, [$field, "graph"], "no"); > } > > $fieldnum++; > if ($field =~ /^([^=]+)=(.+)$/) { # Aliased in graph_order > my $fname = $1; > my $spath = $2; > my $src = munin_get_node_partialpath ($service, $spath); > my $sname = munin_get_node_name ($src); > > next unless defined $src; > logger ("Debug: Copying settings from $sname to $fname.") if $DEBUG; > > foreach my $foption ("draw", "type", "rrdfile", "fieldname", "info") { > if (!defined $service->{$fname}->{$foption}) { > if (defined $src->{$foption}) { > munin_set_var_loc ($service, [$fname, $foption], $src->{$foption}); > } > } > } > > # cdef is special... > if (!defined $service->{$fname}->{"cdef"}) { > if (defined $src->{"cdef"}) { > (my $tmpcdef = $src->{"cdef"}) =~ s/([,=])$sname([,=]|$)/$1$fname$2/g; > munin_set_var_loc ($service, [$fname, "cdef"], $tmpcdef); > } > } > > if (!defined $service->{$fname}->{"label"}) { > munin_set_var_loc ($service, [$fname, "label"], $fname); > } > munin_set_var_loc ($service, [$fname, "filename"], munin_get_rrd_filename ($src)); > > } elsif (defined ($tmp_field = get_stack_command ($service->{$field}))) { > logger ("DEBUG: expand_specials ($tmp_field): Doing stack...") if $DEBUG; > my @spc_stack = (); > foreach my $pre (split (/\s+/, $tmp_field)) { > (my $name = $pre) =~ s/=.+//; > if (!@spc_stack) { > munin_set_var_loc ($service, [$name, "draw"], munin_get ($service->{$field}, "draw", "LINE2")); > munin_set_var_loc ($service, [$field, "process"], "no"); > } else { > munin_set_var_loc ($service, [$name, "draw"], "STACK"); > } > push (@spc_stack, $name); > push (@$preproc, $pre); > push @$result, "$name.label"; > push @$result, "$name.draw"; > push @$result, "$name.cdef"; > > munin_set_var_loc ($service, [$name, "label"], $name); > munin_set_var_loc ($service, [$name, "cdef"], "$name,UN,0,$name,IF"); > if (munin_get ($service->{$field}, "cdef") and !munin_get_bool ($service->{$name}, "onlynullcdef", 0)) { > logger ("NotOnlynullcdef ($field)...") if $DEBUG; > $service->{$name}->{"cdef"} .= "," . $service->{$field}->{"cdef"}; > $service->{$name}->{"cdef"} =~ s/\b$field\b/$name/g; > } else { > logger ("Onlynullcdef ($field)...") if $DEBUG; > munin_set_var_loc ($service, [$name, "onlynullcdef"], 1); > push @$result, "$name.onlynullcdef"; > } > } > } elsif (defined ($tmp_field = get_sum_command ($service->{$field}))) { > my @spc_stack = (); > my $last_name = ""; > logger ("DEBUG: expand_specials ($tmp_field): Doing sum...") if $DEBUG; > > if (@$order == 1 or (@$order == 2 and munin_get {$field, "negative", 0})) { > $single = 1; > } > > foreach my $pre (split (/\s+/, $tmp_field)) { > (my $path = $pre) =~ s/.+=//; > my $name = "z".$fieldnum."_".scalar (@spc_stack); > $last_name = $name; > > munin_set_var_loc ($service, [$name, "cdef"], "$name,UN,0,$name,IF"); > munin_set_var_loc ($service, [$name, "graph"], "no"); > munin_set_var_loc ($service, [$name, "label"], $name); > push @$result, "$name.cdef"; > push @$result, "$name.graph"; > push @$result, "$name.label"; > > push (@spc_stack, $name); > push (@$preproc, "$name=$pre"); > } > $service->{$last_name}->{"cdef"} .= "," . join (',+,', @spc_stack[0 .. @spc_stack-2]) . ',+'; > > if (my $tc = munin_get ($service->{$field}, "cdef", 0)) { # Oh bugger... > print "Oh bugger...($field)...\n" if $DEBUG; > $tc =~ s/\b$field\b/$service->{$last_name}->{"cdef"}/; > $service->{$last_name}->{"cdef"} = $tc; > } > munin_set_var_loc ($service, [$field, "process"], "no"); > munin_set_var_loc ($service, [$last_name, "draw"], munin_get ($service->{$field}, "draw")); > munin_set_var_loc ($service, [$last_name, "label"], munin_get ($service->{$field}, "label")); > munin_set_var_loc ($service, [$last_name, "graph"], munin_get ($service->{$field}, "graph", "yes")); > > if (my $tmp = munin_get($service->{$field}, "negative")) { > munin_set_var_loc ($service, [$last_name, "negative"], $tmp); > } > > munin_set_var_loc ($service, [$field, "realname"], $last_name); > > } elsif (my $nf = munin_get ($service->{$field}, "negative", 0)) { > if (!munin_get_bool ($service->{$nf}, "graph", 1) or munin_get_bool ($service->{$nf}, "skipdraw", 0)) { > munin_set_var_loc ($service, [$nf, "graph"], "no"); > } > } > } > return $result; >} > >sub single_value >{ > my $service = shift; > > my $graphable = munin_get ($service, "graphable", 0);; > if (!$graphable) { > foreach my $field (@{munin_get_field_order ($service)}) { > logger ("DEBUG: single_value: Checking field \"$field\"."); > $graphable++ if munin_draw_field ($service->{$field}); > } > munin_set_var_loc ($service, ["graphable"], $graphable); > } > logger ("Debug: service ". join (' :: ', @{munin_get_node_loc ($service)}) ." has $graphable elements."); > return ($graphable == 1); >} > >sub get_field_name >{ > my $name = shift; > > $name = substr (Digest::MD5::md5_hex ($name), -15) > if (length $name > 15); > > return $name; >} > >sub process_field { > my $field = shift; > return munin_get_bool ($field, "process", 1); >} > >sub process_service { > my ($service) = @_; > > # Make my graphs > my $sname = munin_get_node_name ($service); > my $service_time= Time::HiRes::time; > my $lastupdate = 0; > my $now = time; > my $fnum = 0; > my @rrd; > my @added = (); > > # See if we should skip the service > return if (skip_service ($service)); > > my $field_count = 0; > my $max_field_len = 0; > my @field_order = (); > my $rrdname; > my $force_single_value; > > @field_order = @{munin_get_field_order($service)}; > > # Array to keep 'preprocess'ed fields. > my @rrd_preprocess = (); > logger ("Debug: Expanding specials for $sname: \"" . join("\",\"", @field_order) . "\".") if $DEBUG; > > @added = @{&expand_specials ($service, \@rrd_preprocess, \@field_order, \$force_single_value)}; > > @field_order = (@rrd_preprocess, @field_order); > logger ("DEBUG: Checking field lengths for $sname: \"" . join("\",\"", @rrd_preprocess) . "\".") if $DEBUG; > > # Get max label length > $max_field_len = munin_get_max_label_length ($service, \@field_order); > > # Global headers makes the value tables easier to read no matter how > # wide the labels are. > my $global_headers = 1; > > # Default format for printing under graph. > my $avgformat; > my $rrdformat=$avgformat="%6.2lf"; > > if (munin_get ($service, "graph_args", "") =~ /--base\s+1024/) { > # If the base unit is 1024 then 1012.56 is a valid > # number to show. That's 7 positions, not 6. > $rrdformat=$avgformat="%7.2lf"; > } > > # Plugin specified complete printf format > $rrdformat = munin_get ($service, "graph_printf", $rrdformat); > > my $rrdscale = ''; > if (munin_get_bool ($service, "graph_scale", 1)) { > $rrdscale = '%s'; > } > > # Array to keep negative data until we're finished with positive. > my @rrd_negatives = (); > > my $filename = "unknown"; > my %total_pos; > my %total_neg; > my $autostacking=0; > > logger ("DEBUG: Treating fields \"" . join ("\",\"", @field_order) . "\".") if $DEBUG; > for my $fname (@field_order) { > my $path = undef; > my $field = undef; > > if ($fname =~ s/=(.+)//) { > $path = $1; > } > $field = munin_get_node ($service, [$fname]); > > next if (!defined $field or !$field or !process_field ($field)); > logger ("DEBUG: Processing field \"$fname\" [".munin_get_node_name($field)."].") if $DEBUG; > > my $fielddraw = munin_get ($field, "draw", "LINE2"); > > if ($field_count == 0 and $fielddraw eq 'STACK') { > # Illegal -- first field is a STACK > logger ("ERROR: First field (\"$fname\") of graph " . join (' :: ', munin_get_node_loc ($service)) . > " is STACK. STACK can only be drawn after a LINEx or AREA."); > $fielddraw = "LINE2"; > } > > if ($fielddraw eq 'AREASTACK') { > if ($autostacking==0) { > $fielddraw='AREA'; > $autostacking=1; > } else { > $fielddraw='STACK'; > } > } > > if ($fielddraw =~ /LINESTACK(\d+(?:.\d+)?)/ ) { > if ($autostacking==0) { > $fielddraw="LINE$1"; > $autostacking=1; > } else { > $fielddraw='STACK'; > } > } > > # Getting name of rrd file > $filename = munin_get_rrd_filename ($field, $path); > > my $update = RRDs::last ($filename); > $update = 0 if ! defined $update; > if ($update > $lastupdate) { > $lastupdate = $update; > } > > # It does not look like $fieldname.rrdfield is possible to set > my $rrdfield = munin_get ($field, "rrdfield", "42"); > > my $single_value = $force_single_value || single_value ($service); > > my $has_negative = munin_get ($field, "negative"); > > # Trim the fieldname to make room for other field names. > $rrdname = &get_field_name ($fname); > if ($rrdname ne $fname) { > # A change was made > munin_set ($field, "cdef_name", $rrdname); > } > > push (@rrd, "DEF:g$rrdname=" . > $filename . ":" . $rrdfield . ":AVERAGE"); > push (@rrd, "DEF:i$rrdname=" . > $filename . ":" . $rrdfield . ":MIN"); > push (@rrd, "DEF:a$rrdname=" . > $filename . ":" . $rrdfield . ":MAX"); > > if (munin_get_bool ($field, "onlynullcdef", 0)) { > push (@rrd, "CDEF:c$rrdname=g$rrdname" . (($now-$update)>900 ? ",POP,UNKN" : "")); > } > > if (munin_get ($field, "type", "GAUGE") ne "GAUGE" and graph_by_minute ($service)) { > push (@rrd, expand_cdef($service, \$rrdname, "$fname,60,*")); > } > > if (my $tmpcdef = munin_get ($field, "cdef")) { > push (@rrd,expand_cdef($service, \$rrdname, $tmpcdef)); > push (@rrd, "CDEF:c$rrdname=g$rrdname"); > logger ("DEBUG: Field name after cdef set to $rrdname") if $DEBUG; > } elsif (!munin_get_bool ($field, "onlynullcdef", 0)) { > push (@rrd, "CDEF:c$rrdname=g$rrdname" . (($now-$update)>900 ? ",POP,UNKN" : "")); > } > > next if !munin_draw_field ($field); > logger ("DEBUG: Drawing field \"$fname\".") if $DEBUG; > > if ($single_value) { > # Only one field. Do min/max range. > push (@rrd, "CDEF:min_max_diff=a$rrdname,i$rrdname,-"); > push (@rrd, "CDEF:re_zero=min_max_diff,min_max_diff,-") if !munin_get ($field, "negative"); > push (@rrd, "AREA:i$rrdname#ffffff"); > push (@rrd, "STACK:min_max_diff$range_colour"); > push (@rrd, "LINE2:re_zero#000000") if !munin_get ($field, "negative"); > } > > if ($has_negative and !@rrd_negatives) { # Push "global" headers... > push (@rrd, "COMMENT:" . (" " x $max_field_len)); > push (@rrd, "COMMENT:Cur (-/+)"); > push (@rrd, "COMMENT:Min (-/+)"); > push (@rrd, "COMMENT:Avg (-/+)"); > push (@rrd, "COMMENT:Max (-/+) \\j"); > } elsif ($global_headers == 1) { > push (@rrd, "COMMENT:" . (" " x $max_field_len)); > push (@rrd, "COMMENT: Cur$RRDkludge:"); > push (@rrd, "COMMENT:Min$RRDkludge:"); > push (@rrd, "COMMENT:Avg$RRDkludge:"); > push (@rrd, "COMMENT:Max$RRDkludge: \\j"); > $global_headers++; > } > > my $colour; > > if (my $tmpcol = munin_get ($field, "colour")) { > $colour = "#" . $tmpcol; > } elsif ($single_value) { > $colour = $single_colour; > } else { > $colour = $COLOUR[$field_count%@COLOUR]; > } > > $field_count++; > > my $tmplabel = munin_get ($field, "label", $fname); > > push (@rrd, $fielddraw . ":g$rrdname" . $colour . ":" . > escape ($tmplabel) . (" " x ($max_field_len + 1 - length $tmplabel))); > > # Check for negative fields (typically network (or disk) traffic) > if ($has_negative) { > my $negfieldname = orig_to_cdef ($service, munin_get ($field, "negative")); > my $negfield = $service->{$negfieldname}; > if (my $tmpneg = munin_get ($negfield, "realname")) { > $negfieldname = $tmpneg; > $negfield = $service->{$negfieldname}; > } > > if (!@rrd_negatives) { > # zero-line, to redraw zero afterwards. > push (@rrd_negatives, "CDEF:re_zero=g$negfieldname,UN,0,0,IF"); > } > > push (@rrd_negatives, "CDEF:ng$negfieldname=g$negfieldname,-1,*"); > > if ($single_value) { > # Only one field. Do min/max range. > push (@rrd, "CDEF:neg_min_max_diff=i$negfieldname,a$negfieldname,-"); > push (@rrd, "CDEF:ni$negfieldname=i$negfieldname,-1,*"); > push (@rrd, "AREA:ni$negfieldname#ffffff"); > push (@rrd, "STACK:neg_min_max_diff$range_colour"); > } > > push (@rrd_negatives, $fielddraw . ":ng$negfieldname" . $colour ); > > # Draw HRULEs > my $linedef = munin_get ($negfield, "line"); > if ($linedef) { > my ($number, $ldcolour, $label) = split (/:/, $linedef, 3); > push (@rrd_negatives, "HRULE:".$number. > ($ldcolour ? "#$ldcolour" : $colour)); > > } elsif (my $tmpwarn = munin_get ($negfield, "warn")) { > push (@rrd_negatives, "HRULE:".$negfieldname. > (defined $single_value and $single_value) ? "#ff0000" : $colour); > } > > push (@rrd, "GPRINT:c$negfieldname:LAST:$rrdformat" . $rrdscale . "/\\g"); > push (@rrd, "GPRINT:c$rrdname:LAST:$rrdformat" . $rrdscale . ""); > push (@rrd, "GPRINT:i$negfieldname:MIN:$rrdformat" . $rrdscale . "/\\g"); > push (@rrd, "GPRINT:i$rrdname:MIN:$rrdformat" . $rrdscale . ""); > push (@rrd, "GPRINT:g$negfieldname:AVERAGE:$avgformat" . $rrdscale . "/\\g"); > push (@rrd, "GPRINT:g$rrdname:AVERAGE:$avgformat" . $rrdscale . ""); > push (@rrd, "GPRINT:a$negfieldname:MAX:$rrdformat" . $rrdscale . "/\\g"); > push (@rrd, "GPRINT:a$rrdname:MAX:$rrdformat" . $rrdscale . "\\j"); > push (@{$total_pos{'min'}}, "i$rrdname"); > push (@{$total_pos{'avg'}}, "g$rrdname"); > push (@{$total_pos{'max'}}, "a$rrdname"); > push (@{$total_neg{'min'}}, "i$negfieldname"); > push (@{$total_neg{'avg'}}, "g$negfieldname"); > push (@{$total_neg{'max'}}, "a$negfieldname"); > } else { > push (@rrd, "COMMENT: Cur$RRDkludge:") unless $global_headers; > push (@rrd, "GPRINT:c$rrdname:LAST:$rrdformat" . $rrdscale . ""); > push (@rrd, "COMMENT: Min$RRDkludge:") unless $global_headers; > push (@rrd, "GPRINT:i$rrdname:MIN:$rrdformat" . $rrdscale . ""); > push (@rrd, "COMMENT: Avg$RRDkludge:") unless $global_headers; > push (@rrd, "GPRINT:g$rrdname:AVERAGE:$avgformat" . $rrdscale . ""); > push (@rrd, "COMMENT: Max$RRDkludge:") unless $global_headers; > push (@rrd, "GPRINT:a$rrdname:MAX:$rrdformat" . $rrdscale . "\\j"); > push (@{$total_pos{'min'}}, "i$rrdname"); > push (@{$total_pos{'avg'}}, "g$rrdname"); > push (@{$total_pos{'max'}}, "a$rrdname"); > } > > # Draw HRULEs > my $linedef = munin_get ($field, "line"); > if ($linedef) { > my ($number, $ldcolour, $label) = split (/:/, $linedef, 3); > $label =~ s/:/\\:/g if defined $label; > push (@rrd, "HRULE:".$number. > ($ldcolour ? "#$ldcolour" : > ((defined $single_value and $single_value) ? > "#ff0000" : $colour)). > ((defined $label and length ($label)) ? ":$label" : ""), > "COMMENT: \\j" > ); > } elsif (my $tmpwarn = munin_get ($field, "warn")) { > push (@rrd,"HRULE:".$tmpwarn.($single_value ? "#ff0000" : $colour)); > } > } > > my $graphtotal = munin_get ($service, "graph_total"); > if (@rrd_negatives) { > push (@rrd, @rrd_negatives); > push (@rrd, "LINE2:re_zero#000000"); # Redraw zero. > if (defined $graphtotal and exists $total_pos{'min'} and > exists $total_neg{'min'} and > @{$total_pos{'min'}} and @{$total_neg{'min'}}) { > > push (@rrd, "CDEF:ipostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'min'}}).(",+" x (@{$total_pos{'min'}}-1))); > push (@rrd, "CDEF:gpostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'avg'}}).(",+" x (@{$total_pos{'avg'}}-1))); > push (@rrd, "CDEF:apostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'max'}}).(",+" x (@{$total_pos{'max'}}-1))); > push (@rrd, "CDEF:inegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'min'}}).(",+" x (@{$total_neg{'min'}}-1))); > push (@rrd, "CDEF:gnegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'avg'}}).(",+" x (@{$total_neg{'avg'}}-1))); > push (@rrd, "CDEF:anegtotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_neg{'max'}}).(",+" x (@{$total_neg{'max'}}-1))); > push (@rrd, "CDEF:dpostotal=ipostotal,UN,ipostotal,UNKN,IF"); > push (@rrd, "LINE1:dpostotal#000000:$graphtotal" . (" " x ($max_field_len - length ($graphtotal) + 1))); > push (@rrd, "GPRINT:gnegtotal:LAST:$rrdformat" . $rrdscale . "/\\g"); > push (@rrd, "GPRINT:gpostotal:LAST:$rrdformat" . $rrdscale . ""); > push (@rrd, "GPRINT:inegtotal:MIN:$rrdformat" . $rrdscale . "/\\g"); > push (@rrd, "GPRINT:ipostotal:MIN:$rrdformat" . $rrdscale . ""); > push (@rrd, "GPRINT:gnegtotal:AVERAGE:$avgformat" . $rrdscale . "/\\g"); > push (@rrd, "GPRINT:gpostotal:AVERAGE:$avgformat" . $rrdscale . ""); > push (@rrd, "GPRINT:anegtotal:MAX:$rrdformat" . $rrdscale . "/\\g"); > push (@rrd, "GPRINT:apostotal:MAX:$rrdformat" . $rrdscale . "\\j"); > } > } elsif (defined $graphtotal and exists $total_pos{'min'} and @{$total_pos{'min'}}) { > push (@rrd, "CDEF:ipostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'min'}}).(",+" x (@{$total_pos{'min'}}-1))); > push (@rrd, "CDEF:gpostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'avg'}}).(",+" x (@{$total_pos{'avg'}}-1))); > push (@rrd, "CDEF:apostotal=".join (",", map { "$_,UN,0,$_,IF" } @{$total_pos{'max'}}).(",+" x (@{$total_pos{'max'}}-1))); > > push (@rrd, "CDEF:dpostotal=ipostotal,UN,ipostotal,UNKN,IF"); > push (@rrd, "LINE1:dpostotal#000000:$graphtotal" . (" " x ($max_field_len - length ($graphtotal) + 1))); > push (@rrd, "COMMENT: Cur$RRDkludge:") unless $global_headers; > push (@rrd, "GPRINT:gpostotal:LAST:$rrdformat" . $rrdscale . ""); > push (@rrd, "COMMENT: Min$RRDkludge:") unless $global_headers; > push (@rrd, "GPRINT:ipostotal:MIN:$rrdformat" . $rrdscale . ""); > push (@rrd, "COMMENT: Avg$RRDkludge:") unless $global_headers; > push (@rrd, "GPRINT:gpostotal:AVERAGE:$avgformat" . $rrdscale .""); > push (@rrd, "COMMENT: Max$RRDkludge:") unless $global_headers; > push (@rrd, "GPRINT:apostotal:MAX:$rrdformat" . $rrdscale . "\\j"); > } > > for my $time (keys %times) { > next unless ($draw{$time}); > my $picfilename = munin_get_picture_filename ($service, $time); > (my $picdirname = $picfilename) =~ s/\/[^\/]+$//; > > my @complete = (); > if ($RRDkludge) { > #push (@complete, > #'--font' ,'LEGEND:7:/usr/libexec/munin/VeraMono.ttf', > # since rrdtool 1.3 with libpango the LEGEND column alignment > # only works with monospace fonts > if ( $RRDs::VERSION >= 1.3 ) { > push (@complete, > '--font' ,'LEGEND:7:/usr/libexec/munin/VeraMono.ttf'); > } else { > push (@complete, > '--font' ,'LEGEND:7:@@LIBDIR@@/VeraMono.ttf'); > } > push (@complete, > '--font' ,'UNIT:7:/usr/libexec/munin/VeraMono.ttf', > '--font' ,'AXIS:7:/usr/libexec/munin/VeraMono.ttf'); > } > push(@complete,'-W', $watermark) if $RRDs::VERSION >= 1.2; > > # Do the header (title, vtitle, size, etc...) > push @complete, @{get_header ($service, $time)}; > if ($LINEkluge) { > @rrd = map { s/LINE3:/LINE2.2:/; $_; } @rrd; > @rrd = map { s/LINE2:/LINE1.6:/; $_; } @rrd; > # LINE1 is thin enough. > } > push @complete, @rrd; > > push (@complete, "COMMENT:Last update$RRDkludge: " . > RRDescape(scalar localtime($lastupdate)) . "\\r"); > > if (time - 300 < $lastupdate) { > push @complete, "--end", > (int($lastupdate/$resolutions{$time}))*$resolutions{$time}; > } > print "\n\nrrdtool \"graph\" \"", > join ("\"\n\t\"",@complete), "\"\n" if $DEBUG; > > # Since version 1.3 rrdtool uses libpango which needs its input > # as utf8 string. So we assume that every input is in latin1 > # and decode it to perl's internal representation and then to utf8. > if ( $RRDs::VERSION >= 1.3 ) { > @complete = map { > $_ = encode("utf8", (decode("latin1", $_))); > } @complete; > } > > # Make sure directory exists > munin_mkdir_p ($picdirname, 0777); > > RRDs::graph (@complete); > if (my $ERROR = RRDs::error) { > logger ("Unable to graph ". munin_get_picture_filename ($service, $time) . ": $ERROR"); > } elsif ($list_images) { > # Command-line option to list images created > print munin_get_picture_filename ($service, $time),"\n"; > } > } > > if (munin_get_bool ($service, "graph_sums", 0)) { > foreach my $time (keys %sumtimes) { > my $picfilename = munin_get_picture_filename ($service, $time, 1); > (my $picdirname = $picfilename) =~ s/\/[^\/]+$//; > next unless ($draw{"sum".$time}); > my @rrd_sum; > push @rrd_sum, @{get_header ($service, $time, 1)}; > > if (time - 300 < $lastupdate) { > push @rrd_sum, "--end",(int($lastupdate/$resolutions{$time}))*$resolutions{$time}; > } > push @rrd_sum, @rrd; > push (@rrd_sum, "COMMENT:Last update$RRDkludge: " . RRDescape(scalar localtime($lastupdate)) . "\\r"); > > my $labelled = 0; > my @defined = (); > for (my $index = 0; $index <= $#rrd_sum; $index++) { > if ($rrd_sum[$index] =~ /^(--vertical-label|-v)$/) { > (my $label = munin_get ($service, "graph_vlabel")) =~ s/\$\{graph_period\}/$sumtimes{$time}[0]/g; > splice (@rrd_sum, $index, 2, ("--vertical-label", $label)); > $index++; > $labelled++; > } elsif ($rrd_sum[$index] =~ /^(LINE[123]|STACK|AREA|GPRINT):([^#:]+)([#:].+)$/) { > my ($pre, $fname, $post) = ($1, $2, $3); > next if $fname eq "re_zero"; > if ($post =~ /^:AVERAGE/) { > splice (@rrd_sum, $index, 1, $pre . ":x$fname" . $post); > $index++; > next; > } > next if grep /^x$fname$/, @defined; > push @defined, "x$fname"; > my @replace; > > if (munin_get ($service->{$fname}, "type", "GAUGE") ne "GAUGE") { > if ($time eq "week") { > # Every plot is half an hour. Add two plots and multiply, to get per hour > if (graph_by_minute ($service)) { > # Already multiplied by 60 > push @replace, "CDEF:x$fname=PREV($fname),UN,0,PREV($fname),IF,$fname,+,5,*,6,*"; > } else { > push @replace, "CDEF:x$fname=PREV($fname),UN,0,PREV($fname),IF,$fname,+,300,*,6,*"; > } > } else { > # Every plot is one day exactly. Just multiply. > if (graph_by_minute ($service)) { > # Already multiplied by 60 > push @replace, "CDEF:x$fname=$fname,5,*,288,*"; > } else { > push @replace, "CDEF:x$fname=$fname,300,*,288,*"; > } > } > } > push @replace, $pre . ":x$fname" . $post; > splice (@rrd_sum, $index, 1, @replace); > $index++; > } elsif ($rrd_sum[$index] =~ /^(--lower-limit|--upper-limit|-l|-u)$/) { > $index++; > $rrd_sum[$index] = $rrd_sum[$index] * 300 * $sumtimes{$time}->[1]; > } > } > > unless ($labelled) { > my $label = munin_get ($service, "graph_vlabel_sum_$time", $sumtimes{$time}->[0]); > unshift @rrd_sum, "--vertical-label", $label; > } > > print "\n\nrrdtool \"graph\" \"", join ("\"\n\t\"",@rrd_sum), "\"\n" if $DEBUG; > > # Make sure directory exists > munin_mkdir_p ($picdirname, 0777); > > RRDs::graph (@rrd_sum); > > if (my $ERROR = RRDs::error) { > logger ("Unable to graph ". munin_get_picture_filename ($service, $time) . ": $ERROR"); > } elsif ($list_images) { > # Command-line option to list images created > print munin_get_picture_filename ($service, $time, 1),"\n"; > } > } > } > > $service_time = sprintf ("%.2f",(Time::HiRes::time - $service_time)); > logger ("Graphed service : $sname ($service_time sec * 4)"); > print STATS "GS|$service_time\n" unless $skip_stats; > > foreach (@added) { > delete $service->{$_} if exists $service->{$_}; > } > @added = (); >} > >sub graph_by_minute { > my $service = shift; > > return (munin_get ($service, "graph_period", "second") eq "minute"); >} > >sub orig_to_cdef { > my $service = shift; > my $fieldname = shift; > > return undef unless ref ($service) eq "HASH"; > > if (defined $service->{$fieldname}->{"cdef_name"}) { > return orig_to_cdef ($service, $service->{$fieldname}->{"cdef_name"}); > } > return $fieldname; >} > >sub skip_service { > my $service = shift; > my $sname = munin_get_node_name ($service); > > # Skip if we've limited services with cli options > return 1 if (@limit_services and !grep /^$sname$/, @limit_services); > > # Always graph if --force is present > return 0 if $force_graphing; > > # See if we should skip it because of conf-options > return 1 if (munin_get ($service, "graph", "yes") eq "on-demand" or > !munin_get_bool ($service, "graph", 1)); > > # Don't skip > return 0; >} > >sub expand_cdef { > my $service = shift; > my $cfield_ref = shift; > my $cdef = shift; > > my $new_field = &get_field_name ("cdef$$cfield_ref"); > > my ($max, $min, $avg) = ("CDEF:a$new_field=$cdef", "CDEF:i$new_field=$cdef", "CDEF:g$new_field=$cdef"); > > foreach my $field (@{munin_find_field ($service, "label")}) { > my $fieldname = munin_get_node_name ($field); > my $rrdname = &orig_to_cdef ($service, $fieldname); > if ($cdef =~ /\b$fieldname\b/) { > $max =~ s/([,=])$fieldname([,=]|$)/$1a$rrdname$2/g; > $min =~ s/([,=])$fieldname([,=]|$)/$1i$rrdname$2/g; > $avg =~ s/([,=])$fieldname([,=]|$)/$1g$rrdname$2/g; > } > } > > munin_set_var_loc ($service, [$$cfield_ref, "cdef_name"], $new_field); > $$cfield_ref = $new_field; > > return ($max, $min, $avg); >} > >sub logger_open { > my $dirname = shift; > > if (!$log->opened) { > unless (open ($log, ">>$dirname/munin-graph.log")) { > print STDERR "Warning: Could not open log file \"$dirname/munin-graph.log\" for writing: $!"; > } > } else { > close (STDERR); > *STDERR = \$log; > } >} > >sub logger { > my ($comment) = @_; > my $now = strftime "%b %d %H:%M:%S", localtime; > > print "$now - $comment\n" if $stdout; > if ($log->opened) { > print $log "$now - $comment\n"; > } else { > if (defined $config->{logdir}) { > if (open ($log, ">>$config->{logdir}/munin-graph.log")) { > print $log "$now - $comment\n"; > $log->flush; > close (STDERR); > open (STDERR, ">&", $log); > } else { > print STDERR "Warning: Could not open log file \"$config->{logdir}/munin-graph.log\" for writing: $!"; > print STDERR "$now - $comment\n"; > } > } else { > print STDERR "$now - $comment\n"; > } > } >} > >sub parse_path >{ > my ($path, $domain, $node, $service, $field) = @_; > my $filename = "unknown"; > > if ($path =~ /^\s*([^:]*):([^:]*):([^:]*):([^:]*)\s*$/) > { > $filename = munin_get_filename ($config, $1, $2, $3, $4); > } > elsif ($path =~ /^\s*([^:]*):([^:]*):([^:]*)\s*$/) > { > $filename = munin_get_filename ($config, $domain, $1, $2, $3); > } > elsif ($path =~ /^\s*([^:]*):([^:]*)\s*$/) > { > $filename = munin_get_filename ($config, $domain, $node, $1, $2); > } > elsif ($path =~ /^\s*([^:]*)\s*$/) > { > $filename = munin_get_filename ($config, $domain, $node, $service, $1); > } > return $filename; >} > >sub escape >{ > my $text = shift; > return undef if not defined $text; > $text =~ s/\\/\\\\/g; > $text =~ s/:/\\:/g; > return $text; >} > >sub RRDescape >{ > my $text = shift; > return $RRDs::VERSION < 1.2 ? $text : escape($text); >} > >1; > >=head1 NAME > >munin-graph - A program to create graphs from data contained in rrd-files. > >=head1 SYNOPSIS > >munin-graph [--options] > >=head1 OPTIONS > >=over 5 > >=item B<< --[no]force >> > >If set, force drawing of graphs that are not usually drawn due to options in the config file. [--noforce] > >=item B<< --[no]lazy >> > >If set, only redraw graphs when it would look different from the existing one. [--lazy] > >=item B<< --help >> > >View help. > >=item B<< --[no]force-root >> > >Force running as root (stupid and unnecessary). [--noforce-root] > >=item B<< --[no]debug >> > >If set, view debug messages. [--nodebug] > >=item B<< --service <service> >> > >Limit graphed services to E<lt>serviceE<gt>. Multiple --service options may be supplied. [unset] > >=item B<< --host <host> >> > >Limit graphed hosts to E<lt>hostE<gt>. Multiple --host options may be supplied. [unset] > >=item B<< --config <file> >> > >Use E<lt>fileE<gt> as configuration file. [/etc/munin/munin.conf] > >=item B<< --[no]list-images >> > >If set, list the filenames of the images created. [--nolist-images] > >=item B<< --[no]day >> > >If set, create day-based graphs. [--day] > >=item B<< --[no]week >> > >If set, create week-based graphs. [--week] > >=item B<< --[no]month >> > >If set, create month-based graphs. [--month] > >=item B<< --[no]year >> > >If set, create year-based graphs. [--year] > >=back > >=head1 DESCRIPTION > >Munin-graph is a part of the package Munin, which is used in combination >with Munin's node. Munin is a group of programs to gather data from >Munin's nodes, graph them, create html-pages, and optionally warn Nagios >about any off-limit values. > >munin-graph does the graphing. It is usually only used from within >munin-cron. If munin.conf sets "graph_strategy cgi" then munin-graph >does no work, instead munin-html generates references to the graphing >CGI. Please see http://munin.projects.linpro.no/wiki/CgiHowto for >more information about CGI grpahing. > >It checks the rrd-files for updated values, and redraws the graphs if >needed. To force redrawing of graphs (after setup-changes et alia), use >'--nolazy'. > >=head1 FILES > > /etc/munin/munin.conf > /var/lib/munin/* > /var/log/munin/munin-graph > /var/run/munin/* > >=head1 AUTHORS > >Audun Ytterdal, Jimmy Olsen, Tore Anderson, Nicolai Langfeldt. > >=head1 BUGS > >munin-graph does, as of now, not check the syntax of the configuration file. > >Please report other bugs in the bug tracker at L<http://munin.sf.net/>. > >=head1 COPYRIGHT > >Copyright (C) 2002-2006 Audun Ytterdal, Jimmy Olsen, Tore Anderson, and Nicolai Langfeldt > >This is free software; see the source for copying conditions. There is >NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR >PURPOSE. > >This program is released under the GNU General Public License > >=head1 SEE ALSO > >For information on configuration options, please refer to the man page for >F<munin.conf>. > >=cut > ># vim: syntax=perl ts=8
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 253965
: 177568