Holger Levsen wrote:
> Also, please reply to the bug and attach the code you currently have (and/or 
> provide the link to a git repo which has it :)

Sorry, no git.  I'm working on a test vm with a live install.

This patch is ONLY for the munin perl code.  I will have changed
dynazoom.html so much that attaching it will be smaller.

The patch attached does the following:
GraphOld.pm:
1) Adds --nototal
2) Adds --fields
3) Adds skipping fields in process_service
4) BUG with stacked fields and skipping the first non stacked fields
5) Keeps field color the same
6) Causes the total virtual field to be skipped based on --nototal
HTMLConfig.pm:
7) Adds URL::Escape
8) Add generating a list of fields with labels
9) Adds the generated field list to the dynazoom urls as pairs of
        field=<field>:<label> and uses URL::Escape to encode it
10) Adds hastotal=1 to the dynazoom urls
munin-cgi-graph:
11) Add debug with QUERY_STRING.  (My debugging, may remove)
12) Adds filename too long checking.  Urls generated by dynazoom.html can
        now be too long.  If this happens, the params is MD5 encoded
13) Adds --field foreach field= CGI Parameter
14) Adds --nototal if nototal CGI parameter is ... I don't remember if it
        was a test for existence or a test for a true value.  Possibly true
        value.

Another feature I've changed in dynazoom is the click 'n' drag to select an
area to zoom into.  The original 3 clicks was annoying.  At this point, it
works, but I took dynazoom.html fresh after fixing the original bugs.

diff -ruN /usr/lib/munin/cgi/munin-cgi-graph-orig 
/usr/lib/munin/cgi/munin-cgi-graph
--- /usr/lib/munin/cgi/munin-cgi-graph-orig     2013-05-27 15:52:30.000000000 
-0400
+++ /usr/lib/munin/cgi/munin-cgi-graph  2013-06-09 20:23:15.418711000 -0400
@@ -102,6 +102,7 @@
     my $path = $ENV{PATH_INFO} || "";
 
     DEBUG "Request path is $path";
+    DEBUG "Request query is $ENV{QUERY_STRING}";
 
     # The full URL looks like this:
     # Case 1:
@@ -342,6 +343,8 @@
     my $scale   = shift;
     my $fileext = shift;
     my $params  = shift;
+    my $filename_base;
+    my $filename;
 
     # XXX - hack to fix cgitmpdir default 
     $config->{cgitmpdir} ||= "$Munin::Common::Defaults::MUNIN_CGITMPDIR";
@@ -350,7 +353,17 @@
     $params = $params ? "?$params" : "";
     $params =~ tr/\//_/; # / are forbidden in a filename
     $params = $1 if $params =~ m/(.*)/; # XXX - Q&D untaint
-    return "$cgi_tmp_dir/$domain/$name/$service-$scale.$fileext" . $params;
+    $filename_base = "$cgi_tmp_dir/$domain/$name/$service-$scale.$fileext";
+    $filename = $filename_base . $params;
+
+    # Due to the ability to graph specific fields, the filename can now be way
+    # too long.  Exploit -f to see if the name is too long.
+    if (! -f $filename && $!{ENAMETOOLONG})
+    {
+        $filename = $filename_base . Digest::MD5::md5_hex($params);
+    }
+DEBUG "[DEBUG] Using $filename as image name";
+    return $filename;
 }
 
 sub has_offending_chars {
@@ -480,6 +493,12 @@
     push @params, "--debug"
       if (CGI::param("debug"));
 
+    # Limit fields
+    push @params, map {('--field' => $_)} CGI::param("field");
+
+    # Graph total
+    push @params, "--nototal" if CGI::param("nototal");
+DEBUG "graph_main(\"" . join('", "', @params) . "\");";
     graph_main(\@params);
 
     return $filename;
diff -ruN /usr/share/perl5/Munin/Master/GraphOld-old.pm 
/usr/share/perl5/Munin/Master/GraphOld.pm
--- /usr/share/perl5/Munin/Master/GraphOld-orig.pm      2013-05-27 
15:51:16.000000000 -0400
+++ /usr/share/perl5/Munin/Master/GraphOld.pm   2013-06-03 13:06:25.054711000 
-0400
@@ -94,6 +94,7 @@
 my $skip_locking   = 0;
 my $skip_stats     = 0;
 my $stdout         = 0;
+my $nototal        = 0;
 my $force_run_as_root = 0;
 my $conffile       = $Munin::Common::Defaults::MUNIN_CONFDIR . "/munin.conf";
 my $libdir         = $Munin::Common::Defaults::MUNIN_LIBDIR;
@@ -162,6 +163,7 @@
 # Limit graphing to certain hosts and/or services
 my @limit_hosts    = ();
 my @limit_services = ();
+my @limit_fields = ();
 my $only_fqn = '';
 
 my $watermark = "Munin " . $Munin::Common::Defaults::MUNIN_VERSION;
@@ -183,6 +185,7 @@
 
 my @init_limit_hosts = @limit_hosts;
 my @init_limit_services = @limit_services;
+my @init_limit_fields = @limit_fields;
 
 sub process_pinpoint {
     my ($pinpoint, $arg_name, $arg_value) = @_;     
@@ -225,6 +228,7 @@
     %draw = %init_draw;
     @limit_hosts = @init_limit_hosts;
     @limit_services = @init_limit_services;
+    @limit_fields = @init_limit_fields;
 
     $pinpoint       = undef;
     my $pinpointopt    = undef;
@@ -240,6 +244,7 @@
     $skip_locking   = 0;
     $skip_stats     = 0;
     $stdout         = 0;
+    $nototal        = 0;
 
     $size_x        = undef;
     $size_y         = undef;
@@ -265,9 +270,11 @@
                 "lazy!"         => \$force_lazy,
                 "host=s"        => \@limit_hosts,
                 "service=s"     => \@limit_services,
+                "field=s"       => \@limit_fields,
                 "only-fqn=s"    => sub{ $only_fqn = process_fqn(@_); },
                 "config=s"      => \$conffile,
                 "stdout!"       => \$stdout,
+                "nototal"      => \$nototal,
                 "force-run-as-root!" => \$force_run_as_root,
                 "day!"          => \$draw{'day'},
                 "week!"         => \$draw{'week'},
@@ -370,7 +377,10 @@
     # The loaded $config is stale within 5 minutes.
     # So, we need to reread it when this happens.
     $config = munin_readconfig_part('datafile');
-   
+
+    # Reset limit fields.
+    @limit_fields   = ();
+
     # Reset an eventual custom size
     $size_x        = undef;
     $size_y         = undef;
@@ -380,6 +390,7 @@
     $lower_limit    = undef;
     $upper_limit    = undef;
     $pinpoint       = undef;
+    $nototal        = 0;
 
     $fileext        = "png";
 
@@ -388,6 +399,8 @@
 
     GetOptions (
                 "host=s"        => \@limit_hosts,
+                "field=s"       => \@limit_fields,
+                "nototal"      => \$nototal,
                 "only-fqn=s"    => sub { $only_fqn = process_fqn(@_); },
                 "day!"          => \$draw{'day'},
                 "week!"         => \$draw{'week'},
@@ -903,6 +916,7 @@
     DEBUG "[DEBUG] Node name: $sname\n";
 
     my $field_count   = 0;
+    my $field_skip_count = 0;
     my $max_field_len = 0;
     my @field_order   = ();
     my $rrdname;
@@ -959,6 +973,8 @@
     my $autostacking = 0;
 
     DEBUG "[DEBUG] Treating fields \"" . join("\",\"", @field_order) . "\".";
+    DEBUG "[DEBUG] Graph only these fields: \"" . join("\",\"", @limit_fields) 
. "\"."
+        if (@limit_fields);
     for my $fname (@field_order) {
         my $path  = undef;
         my $field = undef;
@@ -968,6 +984,13 @@
         }
         $field = munin_get_node($service, [$fname]);
 
+        if (@limit_fields && !grep {$fname eq $_} @limit_fields)
+        {
+         DEBUG "[DEBUG] Skipping field $fname";
+         $field_skip_count++;
+         next;
+        }
+
         next if (!defined $field or !$field or !process_field($field));
         DEBUG "[DEBUG] Processing field \"$fname\" ["
             . munin_get_node_name($field) . "].";
@@ -977,9 +1000,11 @@
         if ($field_count == 0 and $fielddraw eq 'STACK') {
 
             # Illegal -- first field is a STACK
+            # Ignore if fields have been skipped.
             DEBUG "ERROR: First field (\"$fname\") of graph "
                 . join(' :: ', munin_get_node_loc($service))
-                . " is STACK. STACK can only be drawn after a LINEx or AREA.";
+                . " is STACK. STACK can only be drawn after a LINEx or AREA."
+                if ($field_skip_count > 0);
             $fielddraw = "LINE1";
         }
 
@@ -1116,7 +1141,9 @@
        }
        
        # Select a default colour if no explict one
-       $colour ||= ($single_value) ? $single_colour : $COLOUR[$field_count % 
@COLOUR];
+       # Add field_skip_count to keep the colors in the graph the same as
+       # graphs that show all fields.
+       $colour ||= ($single_value) ? $single_colour : $COLOUR[($field_count + 
$field_skip_count) % @COLOUR];
 
         # colour needed for transparent predictions and trends
         munin_set($field, "colour", $colour);
@@ -1278,7 +1305,7 @@
     }
 
     my $graphtotal = munin_get($service, "graph_total");
-    if (defined $graphtotal and $graphtotal eq "undef") {
+    if ($nototal or (defined $graphtotal and $graphtotal eq "undef")) {
         $graphtotal = undef;
     }
 
@@ -1979,6 +2006,9 @@
                        in Munin.)
     --host <host>       Limit graphed hosts to <host>. Multiple --host options
                         may be supplied.
+    --field <field>    Limit graphed fields to <field>. Multiple --field 
options
+                        may be supplied.
+    --nototal          Skip graphing total for graphs that have it.
     --only-fqn <FQN>    For internal use with CGI graphing.  Graph only a
                         single fully qualified named graph, e.g. --only-fqn
                           root/Backend/dafnes.example.com/diskstats_iops
diff -ruN /usr/share/perl5/Munin/Master/HTMLConfig-orig.pm 
/usr/share/perl5/Munin/Master/HTMLConfig.pm
--- /usr/share/perl5/Munin/Master/HTMLConfig-orig.pm    2013-05-27 
15:51:16.000000000 -0400
+++ /usr/share/perl5/Munin/Master/HTMLConfig.pm 2013-06-03 12:59:20.454711000 
-0400
@@ -12,6 +12,7 @@
 use Getopt::Long;
 use Time::HiRes;
 use Scalar::Util qw( weaken );
+use URI::Escape;
 
 use Munin::Master::Logger;
 use Munin::Master::Utils;
@@ -491,6 +492,12 @@
 
     # Compute the ZOOM urls
     {
+        my @fields;
+        # Personally, I don't like code preceeding "my" declarations.
+        foreach my $f (@{munin_get_field_order($service)}) {
+                push @fields, "$f:" . munin_get($service->{$f}, "label", $f);
+        }
+
         my $epoch_now = time;
        # The intervals are a bit larger, just like the munin-graph
        my $start_day = $epoch_now - (3600 * 30);
@@ -499,7 +506,13 @@
        my $start_year = $epoch_now - (3600 * 24 * 400);
        my $size_x = 800;
        my $size_y = 400;
-       my $common_url = 
"$root_path/static/dynazoom.html?cgiurl_graph=$config->{'cgiurl_graph'}&plugin_name=$path&size_x=$size_x&size_y=$size_y";
+       my $common_url = 
"$root_path/static/dynazoom.html?cgiurl_graph=$config->{'cgiurl_graph'}&plugin_name=$path&size_x=$size_x&size_y=$size_y&fields="
 . uri_escape(join(",", @fields));
+
+        my $graphtotal = munin_get($service, "graph_total");
+        if (defined $graphtotal and $graphtotal ne "undef") {
+            $common_url .= "&hastotal=1";
+        }
+
        $srv{zoomday} = 
"$common_url&start_epoch=$start_day&stop_epoch=$epoch_now";
        $srv{zoomweek} = 
"$common_url&start_epoch=$start_week&stop_epoch=$epoch_now";
        $srv{zoommonth} = 
"$common_url&start_epoch=$start_month&stop_epoch=$epoch_now";

Reply via email to