X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=contrib%2Fcollection3%2Fbin%2Fgraph.cgi;h=ba189dead65e069612902c437fe7308b07477377;hb=711f5b6c86f51061c21bedcaa46214a01de0125c;hp=c84199df3511afbb22ee00fc76b37f4c4bae94f0;hpb=654783aed1fab02766a9cc036e859799e01f6f9e;p=collectd.git diff --git a/contrib/collection3/bin/graph.cgi b/contrib/collection3/bin/graph.cgi index c84199df..ba189dea 100755 --- a/contrib/collection3/bin/graph.cgi +++ b/contrib/collection3/bin/graph.cgi @@ -1,148 +1,334 @@ #!/usr/bin/perl +# Copyright (C) 2008-2011 Florian Forster +# Copyright (C) 2011 noris network AG +# +# 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; only version 2 of the License is applicable. +# +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# Authors: +# Florian "octo" Forster + use strict; use warnings; -use lib ('../lib'); +use utf8; +use vars (qw($BASE_DIR)); + +BEGIN +{ + if (defined $ENV{'SCRIPT_FILENAME'}) + { + if ($ENV{'SCRIPT_FILENAME'} =~ m{^(/.+)/bin/[^/]+$}) + { + $::BASE_DIR = $1; + unshift (@::INC, "$::BASE_DIR/lib"); + } + } +} -use FindBin ('$RealBin'); use Carp (qw(confess cluck)); use CGI (':cgi'); use RRDs (); +use File::Temp (':POSIX'); -use Collectd::Graph::TypeLoader (qw(tl_read_config tl_load_type)); +use Collectd::Graph::Config (qw(gc_read_config gc_get_scalar)); +use Collectd::Graph::TypeLoader (qw(tl_load_type)); use Collectd::Graph::Common (qw(sanitize_type get_selected_files - epoch_to_rfc1123)); + epoch_to_rfc1123 flush_files)); use Collectd::Graph::Type (); -our $Debug = param ('debug'); -our $Begin = param ('begin'); -our $End = param ('end'); - -if ($Debug) +sub base_dir { - print < 0) && ($Begin > $End)) + if ($GraphWidth) { - my $temp = $End; - $End = $Begin; - $Begin = $temp; + $GraphWidth =~ s/\D//g; } -} -my $type = param ('type') or die; -my $obj; + if (!$GraphWidth) + { + $GraphWidth = gc_get_scalar ('GraphWidth', 400); + } -$obj = tl_load_type ($type); -if (!$obj) -{ - confess ("tl_load_type ($type) failed"); -} + if ($GraphHeight) + { + $GraphHeight =~ s/\D//g; + } -$type = ucfirst (lc ($type)); -$type =~ s/_([A-Za-z])/\U$1\E/g; -$type = sanitize_type ($type); + if (!$GraphHeight) + { + $GraphHeight = gc_get_scalar ('GraphHeight', 100); + } -my $files = get_selected_files (); -if ($Debug) -{ - require Data::Dumper; - print STDOUT Data::Dumper->Dump ([$files], ['files']); -} -for (@$files) -{ - $obj->addFiles ($_); -} + { # Sanitize begin and end times + $End ||= 0; + $Begin ||= 0; -my $expires = time (); -if (($End == 0) || (($Begin <= $expires) && ($End >= $expires))) -{ - # 400 == width in pixels - my $timespan = $expires - $Begin; - $expires += int ($timespan / 400); -} -elsif (($End > 0) && ($End < $expires)) -{ - $expires += 366 * 86400; -} -elsif ($Begin > $expires) -{ - $expires = $Begin; -} + if ($End =~ m/\D/) + { + $End = 0; + } -print STDOUT header (-Content_type => 'image/png', - -Last_Modified => epoch_to_rfc1123 ($obj->getLastModified ()), - -Expires => epoch_to_rfc1123 ($expires)); + if (!$Begin || !($Begin =~ m/^-?([1-9][0-9]*)$/)) + { + $Begin = -86400; + } -my $args = $obj->getRRDArgs (0); + if ($Begin < 0) + { + if ($End) + { + $Begin = $End + $Begin; + } + else + { + $Begin = time () + $Begin; + } + } -if ($Debug) -{ - require Data::Dumper; - print STDOUT Data::Dumper->Dump ([$obj], ['obj']); - print STDOUT join (",\n", @$args) . "\n"; - print STDOUT "Last-Modified: " . epoch_to_rfc1123 ($obj->getLastModified ()) . "\n"; -} -else -{ - my @timesel = (); + if ($Begin < 0) + { + $Begin = time () - 86400; + } + + if (($End > 0) && ($Begin > $End)) + { + my $temp = $End; + $End = $Begin; + $Begin = $temp; + } + } - if ($End) # $Begin is always true + my $type = param ('type') or die; + my $obj; + + $obj = tl_load_type ($type); + if (!$obj) { - @timesel = ('-s', $Begin, '-e', $End); + confess ("tl_load_type ($type) failed"); } - else + + $type = ucfirst (lc ($type)); + $type =~ s/_([A-Za-z])/\U$1\E/g; + $type = sanitize_type ($type); + + my $files = get_selected_files (); + if (param ('debug')) { - @timesel = ('-s', $Begin); # End is implicitely `now'. + require Data::Dumper; + print Data::Dumper->Dump ([$files], ['files']); + } + for (@$files) + { + $obj->addFiles ($_); } - $| = 1; - RRDs::graph ('-', '-a', 'PNG', @timesel, @$args); - if (my $err = RRDs::error ()) + my $expires = time (); +# IF (End is `now') +# OR (Begin is before `now' AND End is after `now') + if (($End == 0) || (($Begin <= $expires) && ($End >= $expires))) { - print STDERR "RRDs::graph failed: $err\n"; - exit (1); + # 400 == width in pixels + my $timespan; + + if ($End == 0) + { + $timespan = $expires - $Begin; + } + else + { + $timespan = $End - $Begin; + } + $expires += int ($timespan / 400.0); } -} +# IF (End is not `now') +# AND (End is before `now') +# ==> Graph will never change again! + elsif (($End > 0) && ($End < $expires)) + { + $expires += (366 * 86400); + } + elsif ($Begin > $expires) + { + $expires = $Begin; + } + +# Send FLUSH command to the daemon if necessary and possible. + flush_files ($files, + begin => $Begin, + end => $End, + addr => gc_get_scalar ('UnixSockAddr', undef), + interval => gc_get_scalar ('Interval', 10)); + + print header (-Content_type => $ContentType, + -Last_Modified => epoch_to_rfc1123 ($obj->getLastModified ()), + -Expires => epoch_to_rfc1123 ($expires)); + + if (param ('debug')) + { + print "\$expires = $expires;\n"; + } + + my $args = $obj->getRRDArgs (0 + $Index); + if (param ('debug')) + { + require Data::Dumper; + print Data::Dumper->Dump ([$obj], ['obj']); + print join (",\n", @$args) . "\n"; + print "Last-Modified: " . epoch_to_rfc1123 ($obj->getLastModified ()) . "\n"; + } + else + { + my @timesel = (); + my $tmpfile = tmpnam (); + my $status; + + if ($End) # $Begin is always true + { + @timesel = ('-s', $Begin, '-e', $End); + } + else + { + @timesel = ('-s', $Begin); # End is implicitely `now'. + } + + if (-S "/var/run/rrdcached.sock" && -w "/var/run/rrdcached.sock") + { + $ENV{"RRDCACHED_ADDRESS"} = "/var/run/rrdcached.sock"; + } + unlink ($tmpfile); + RRDs::graph ($tmpfile, '-a', $OutputFormat, '--width', $GraphWidth, '--height', $GraphHeight, @timesel, @$args); + if (my $err = RRDs::error ()) + { + print STDERR "RRDs::graph failed: $err\n"; + exit (1); + } + + $status = open (IMG, '<', $tmpfile) or die ("open ($tmpfile): $!"); + if (!$status) + { + print STDERR "graph.cgi: Unable to open temporary file \"$tmpfile\" for reading: $!\n"; + } + else + { + local $/ = undef; + while (my $data = ) + { + print STDOUT $data; + } + + close (IMG); + unlink ($tmpfile); + } + } +} # sub main -exit (0); +main (); # vim: set shiftwidth=2 softtabstop=2 tabstop=8 :