[Orca-dev] dynamic charts

Brian Egge brianegge at yahoo.com
Thu Mar 5 12:58:04 PST 2009


First - I'm not a Perl programmer.  In fact, this is probably the most  
Perl I've written to date.  So, I wouldn't consider this patch  
anywhere near ready to commit, but it fixed and itch I had, and may be  
useful for others.

Basically, I wanted to be able to see charts updated as soon as new  
data was available.  This is useful during performance testing, where  
a test might run fo 30-60 minutes.  Keeping with the standard five  
minute sampling period, I update the rdd files just after the data is  
captured.  Updating the RRD files, but not the html or images does not  
take very much time.  I then allow the images to be re-rendered on the  
fly when they are requested via a CGI script.  This is a low volume  
environment, so I'm not even using FastCGI.

I did this is the simplest, dumbest way possible.  When orca invokes  
the RRDTool, I capture the params and save it in a file.  When I want  
to re-render the image, I load the params, and adjust the time, and  
rerender the graph.  I could be a bit smarter and only re-render the  
image if the RRD files are more up to date than the last image, but  
this optimisation hasn't been necessary in my environment yet.


diff -u /app/home/emgdev/src/orca-snapshot-r535/lib/Orca/Config.pm lib/ 
perl/Orca/Config.pm
--- /app/home/emgdev/src/orca-snapshot-r535/lib/Orca/Config.pm  
2005-11-28 16:48:49.000000000 +1100
+++ lib/perl/Orca/Config.pm 2009-03-03 16:23:47.951662000 +1100
@@ -103,6 +103,7 @@
                                      require             => 1,
                                      rrd_dir             => 1,
                                      state_file          => 1,
+                                    dynamic_plots       => 1,
                                      warn_email          => 1);
  map { $pcl_global_elements{$_} = 1 } @plot_type_global_elements;
  my %pcl_group_elements         =   (column_description  => 1,
@@ -203,6 +204,7 @@
                                      html_page_header
                                      html_top_title
                                      late_interval
+                                    dynamic_plots
                                      warn_email);
  my @cc_default_is_false_group  = qw(date_parse
                                      reopen);
diff -u /app/home/emgdev/src/orca-snapshot-r535/lib/Orca/ImageFile.pm  
lib/perl/Orca/ImageFile.pm
--- /app/home/emgdev/src/orca-snapshot-r535/lib/Orca/ImageFile.pm  
2005-11-28 16:48:49.000000000 +1100
+++ lib/perl/Orca/ImageFile.pm 2009-03-05 08:46:35.187806000 +1100
@@ -28,6 +28,7 @@
  package Orca::ImageFile;

  use strict;
+use Storable qw(store store_fd);
  use Carp;
  use RRDs;
  use Orca::Constants qw($opt_generate_gifs
@@ -409,6 +410,16 @@
      $plot_end_time_ctime =~ s/:/\\:/g;
    }

+  my(@args) = (
+      $image_filename,
+      @{$self->[I_GRAPH_OPTIONS]},
+      '-t', $self->[I_PLOT_LEGEND_BASE+$i],
+      '-s', ($plot_end_time-$image_time_span),
+      '-e', $plot_end_time,
+      '-w', $plot_ref->{plot_width},
+      '-h', $plot_ref->{plot_height},
+      'COMMENT:\s',
+      "COMMENT:Last data entered at $plot_end_time_ctime." );
    my ($graph_return, $image_width, $image_height) =
      RRDs::graph
        $image_filename,
@@ -420,6 +431,11 @@
        '-h', $plot_ref->{plot_height},
        'COMMENT:\s',
        "COMMENT:Last data entered at $plot_end_time_ctime.";
+      if ($config_global{dynamic_plots}) {
+        my $data_filename = $image_filename;
+        $data_filename =~ s/.png/.data/;
+        store \@args, $data_filename;
+      }
    if (my $error = RRDs::error) {
      warn "$0: warning: cannot create '$image_filename': $error\n";
      return;
--- bin/orca~ 2009-03-03 14:55:50.366730000 +1100
+++ bin/orca 2009-03-04 15:05:39.653920000 +1100
@@ -44,6 +44,7 @@
  use Carp;
  use Getopt::Long;
  use Cwd;
+use URI::Escape;

  # For this script and all of the Orca::* Perl modules loaded by this
  # script, load of the all Perl modules here that have a minimum
@@ -63,7 +64,7 @@
  use warnings;

  use Digest::MD5          2.33;
-use Math::IntervalSearch 1.05 qw(interval_search);
+use Math::IntervalSearch qw(interval_search);
  use Storable             2.15;
  use RRDs                 1.000503;

@@ -781,6 +782,11 @@
                                 "$subgroup_name/" :
                                 "";
            $image_filename .= "$name-$html_files[$j]{plot_type}. 
$IMAGE_SUFFIX";
+          if ($config_global{dynamic_plots}) {
+            my $data_filename = $image_filename;
+            $data_filename =~ s/.png/.data/;
+            $image_filename = "image.cgi?data=" .  
uri_escape($data_filename);
+          }
            my $html = "<a $href><img src=\"$image_filename\"  
$image_size " .
                       "alt=\"$html_files[$j]{Plot_Type} $title\"></ 
a><br /> <br />\n";
            $html_files[$j]{fd}->print($html);
@@ -974,8 +980,14 @@
        my $image_size          = $image->image_src_size;
        foreach my $plot_type (@IMAGE_PLOT_TYPES) {
          my $Plot_Type    = capatialize($plot_type);
+        my $full_image_filename        .= "$plot_type.$IMAGE_SUFFIX";
+        if ($config_global{dynamic_plots}) {
+          my $data_filename = $full_image_filename;
+          $data_filename =~ s/.png/.data/;
+          $full_image_filename = "image.cgi?data=" .  
uri_escape($data_filename);
+        }
          $summarize_html->print("$html_hr\n<h2>$Plot_Type  
$legend_with_subgroup</h2>\n",
-                               "<img src=\"$image_filename-$plot_type. 
$IMAGE_SUFFIX\"",
+                               "<img src=\"$full_image_filename\"",
                                 $image_size,
                                 "alt=\"$Plot_Type  
$legend_with_subgroup\">\n");
        }
@@ -994,6 +1006,11 @@
          my $Plot_Type      = $legend_html_files[$i]{Plot_Type};
          my $image_filename = length($subgroup_name) ?  
"$subgroup_name/" : "";
          $image_filename   .= "$name-$legend_html_files[$i] 
{plot_type}.$IMAGE_SUFFIX";
+        if ($config_global{dynamic_plots}) {
+          my $data_filename = $image_filename;
+          $data_filename =~ s/.png/.data/;
+          $image_filename = "image.cgi?data=" .  
uri_escape($data_filename);
+        }
          my $html = "<a $href><img src=\"$image_filename\"  
$image_size " .
                     "alt=\"$Plot_Type $subgroup_name  
$legend_no_subgroup\"></a><br /><br />\n";
          $legend_html_files[$i]{fd}->print("$html_hr\n<h2><a ${href}  
name=\"$subgroup_name\">$Plot_Type $subgroup_name $legend_no_subgroup</ 
a></h2>\n");
--- /dev/null 2009-03-05 08:53:13.000000000 +1100
+++ ../webapps/orca/image.cgi 2009-03-04 17:12:39.533927000 +1100
@@ -0,0 +1,158 @@
+#!/app/retailtools/bin/perl -w # -*- perl -*-
+
+# Orca: display arbitrary data from files onto web pages using RRDtool.
+#
+# Orca 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Orca 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 Orca in the COPYING-GPL file; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA
+
+require 5.005_03;
+
+use strict;
+
+$| = 1;
+
+# Set the location of the Orca modules.
+BEGIN {
+  my $prefix      = "/app/retailtools/orca";
+  my $exec_prefix = "${prefix}";
+  my $libdir      = "${exec_prefix}/lib/perl";
+  unshift(@INC, $libdir);
+}
+
+use Carp;
+use Getopt::Long;
+use Cwd;
+
+# For this script and all of the Orca::* Perl modules loaded by this
+# script, load of the all Perl modules here that have a minimum
+# required version number so that the minimum module version numbers
+# can be listed in once place instead of spread out in each Orca::*
+# module.
+
+# Using the Data::Dumper module on an Ubuntu Breezy Badger (5.10)
+# system with Perl 5.8.7 generates the warning 'Argument "2.121_04"
+# isn't numeric in subroutine entry', so temporarily turn off warnings
+# when using this module.  Removing the minimum required version of
+# Data::Dumper also removes the warning, but Orca should demand a
+# particular version of Data::Dumper for systems with older Perls with
+# older Data::Dumper's.
+no warnings;
+use Data::Dumper         2.101;
+use warnings;
+
+use CGI                  qw(:standard);
+use Digest::MD5          2.33;
+use Storable             qw(retrieve);
+use RRDs                 1.000503;
+
+# Set behavior of the Data::Dumper module.
+$Data::Dumper::Indent   = 1;
+$Data::Dumper::Purity   = 1;
+$Data::Dumper::Deepcopy = 1;
+
+# Load the required Orca modules.
+use Orca::Constants     qw(IS_WIN32
+                           die_when_called
+                           $INCORRECT_NUMBER_OF_ARGS
+                           $ORCA_VERSION
+                           $opt_daemon
+                           $opt_generate_gifs
+                           $opt_log_filename
+                           $opt_no_html
+                           $opt_no_images
+                           $opt_once_only
+                           $opt_verbose
+                           @IMAGE_PLOT_TYPES
+                           $IMAGE_SUFFIX
+                           $MAX_PLOT_TYPE_LENGTH);
+use Orca::Config        qw(load_config
+                           %config_global
+                           @config_groups
+                           @config_groups_names
+                           @config_plots);
+use Orca::OldState      qw($orca_old_state
+                           load_old_state
+                           save_old_state);
+use Orca::Utils         qw(capatialize
+                           name_to_fsname
+                           perl_glob
+                           print_running_stats
+                           unique);
+use Orca::SourceFile;
+use Orca::SourceFileIDs qw(@sfile_fids);
+use Orca::HTMLFile      qw($html_hr);
+
+my $cgi = new CGI;
+my $data_filename = $cgi->param('data');
+my $image_filename = "";
+if (-r $data_filename) {
+  my $args = retrieve($data_filename);
+  $image_filename = $args->[0];
+  my $now = localtime;
+  my $lastarg = 0;
+  my $start = 0;
+  my $end = 0;
+  # read in the arguments, looking for the start and end time
+  foreach my $arg (@{$args}) {
+    if ($lastarg eq "-s") {
+      $start = $arg;
+    }
+    if ($lastarg eq "-e") {
+      $end = $arg;
+    }
+    $lastarg = $arg;
+  }
+  # change the arguments that we have to
+  my $image_time_span = $end - $start;
+  $end = time - time % 300;
+  $start = $end - $image_time_span;
+  foreach my $arg (@{$args}) {
+    $arg =~ s/(COMMENT[:]Last data entered at )(.*)/$1$now./;
+    if ($lastarg eq "-s") {
+      $arg = $start;
+    }
+    if ($lastarg eq "-e") {
+      $arg = $end;
+    }
+    $lastarg = $arg;
+  }
+
+  my ($graph_return, $image_width, $image_height) =
+        RRDs::graph @{$args};
+      }
+
+
+if (-r $image_filename) {
+  print $cgi->header( -type => "image/png" );
+  open (FILE, $image_filename);
+  local ($/);
+  my $file = <FILE>;
+  close (FILE);
+
+  print $file;
+  exit 0;
+}
+die "Can't find $image_filename";
+exit 1;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/orca-dev/attachments/20090305/c57c0a85/attachment.html>


More information about the Orca-dev mailing list