X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=contrib%2Fcollection3%2Fbin%2Fgraph.cgi;h=ba189dead65e069612902c437fe7308b07477377;hb=711f5b6c86f51061c21bedcaa46214a01de0125c;hp=8a5bf85a17de71a3b978f55bab662d3cccc2197a;hpb=8f40e8dacad2bfcb9d659e12740aa3ebc15ada65;p=collectd.git diff --git a/contrib/collection3/bin/graph.cgi b/contrib/collection3/bin/graph.cgi index 8a5bf85a..ba189dea 100755 --- a/contrib/collection3/bin/graph.cgi +++ b/contrib/collection3/bin/graph.cgi @@ -1,14 +1,45 @@ #!/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::Config (qw(gc_read_config gc_get_scalar)); use Collectd::Graph::TypeLoader (qw(tl_load_type)); @@ -17,200 +48,287 @@ use Collectd::Graph::Common (qw(sanitize_type get_selected_files epoch_to_rfc1123 flush_files)); use Collectd::Graph::Type (); -our $Debug = param ('debug'); -our $Begin = param ('begin'); -our $End = param ('end'); -our $GraphWidth = param ('width'); -our $GraphHeight = param ('height'); -our $Index = param ('index') || 0; -our $OutputFormat = 'PNG'; -our $ContentType = 'image/png'; - -if (param ('format')) +sub base_dir { - my $temp = param ('format') || ''; - $temp = uc ($temp); + if (defined $::BASE_DIR) + { + return ($::BASE_DIR); + } - if ($temp =~ m/^(PNG|SVG|EPS|PDF)$/) + if (!defined ($ENV{'SCRIPT_FILENAME'})) { - $OutputFormat = $temp; + return; + } - if ($OutputFormat eq 'SVG') { $ContentType = 'image/svg+xml'; } - elsif ($OutputFormat eq 'EPS') { $ContentType = 'image/eps'; } - elsif ($OutputFormat eq 'PDF') { $ContentType = 'application/pdf'; } + if ($ENV{'SCRIPT_FILENAME'} =~ m{^(/.+)/bin/[^/]+$}) + { + $::BASE_DIR = $1; + return ($::BASE_DIR); } + + return; } -if ($Debug) +sub lib_dir { - print < 0) && ($Begin > $End)) + if ($GraphHeight) { - my $temp = $End; - $End = $Begin; - $Begin = $temp; + $GraphHeight =~ s/\D//g; } -} -my $type = param ('type') or die; -my $obj; + if (!$GraphHeight) + { + $GraphHeight = gc_get_scalar ('GraphHeight', 100); + } -$obj = tl_load_type ($type); -if (!$obj) -{ - confess ("tl_load_type ($type) failed"); -} + { # Sanitize begin and end times + $End ||= 0; + $Begin ||= 0; -$type = ucfirst (lc ($type)); -$type =~ s/_([A-Za-z])/\U$1\E/g; -$type = sanitize_type ($type); + if ($End =~ m/\D/) + { + $End = 0; + } -my $files = get_selected_files (); -if ($Debug) -{ - require Data::Dumper; - print STDOUT Data::Dumper->Dump ([$files], ['files']); -} -for (@$files) -{ - $obj->addFiles ($_); -} + if (!$Begin || !($Begin =~ m/^-?([1-9][0-9]*)$/)) + { + $Begin = -86400; + } -my $expires = time (); -# IF (End is `now') -# OR (Begin is before `now' AND End is after `now') -if (($End == 0) || (($Begin <= $expires) && ($End >= $expires))) -{ - # 400 == width in pixels - my $timespan; + if ($Begin < 0) + { + if ($End) + { + $Begin = $End + $Begin; + } + else + { + $Begin = time () + $Begin; + } + } - if ($End == 0) + if ($Begin < 0) + { + $Begin = time () - 86400; + } + + if (($End > 0) && ($Begin > $End)) + { + my $temp = $End; + $End = $Begin; + $Begin = $temp; + } + } + + my $type = param ('type') or die; + my $obj; + + $obj = tl_load_type ($type); + if (!$obj) { - $timespan = $expires - $Begin; + 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')) { - $timespan = $End - $Begin; + require Data::Dumper; + print Data::Dumper->Dump ([$files], ['files']); + } + for (@$files) + { + $obj->addFiles ($_); + } + + my $expires = time (); +# IF (End is `now') +# OR (Begin is before `now' AND End is after `now') + if (($End == 0) || (($Begin <= $expires) && ($End >= $expires))) + { + # 400 == width in pixels + my $timespan; + + if ($End == 0) + { + $timespan = $expires - $Begin; + } + else + { + $timespan = $End - $Begin; + } + $expires += int ($timespan / 400.0); } - $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; -} + 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, + flush_files ($files, begin => $Begin, end => $End, addr => gc_get_scalar ('UnixSockAddr', undef), interval => gc_get_scalar ('Interval', 10)); -print STDOUT header (-Content_type => $ContentType, - -Last_Modified => epoch_to_rfc1123 ($obj->getLastModified ()), - -Expires => epoch_to_rfc1123 ($expires)); - -if ($Debug) -{ - print "\$expires = $expires;\n"; -} - -my $args = $obj->getRRDArgs (0 + $Index); + print header (-Content_type => $ContentType, + -Last_Modified => epoch_to_rfc1123 ($obj->getLastModified ()), + -Expires => epoch_to_rfc1123 ($expires)); -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 (param ('debug')) + { + print "\$expires = $expires;\n"; + } - if ($End) # $Begin is always true + my $args = $obj->getRRDArgs (0 + $Index); + if (param ('debug')) { - @timesel = ('-s', $Begin, '-e', $End); + require Data::Dumper; + print Data::Dumper->Dump ([$obj], ['obj']); + print join (",\n", @$args) . "\n"; + print "Last-Modified: " . epoch_to_rfc1123 ($obj->getLastModified ()) . "\n"; } else { - @timesel = ('-s', $Begin); # End is implicitely `now'. - } + my @timesel = (); + my $tmpfile = tmpnam (); + my $status; - $| = 1; - RRDs::graph ('-', '-a', $OutputFormat, '--width', $GraphWidth, '--height', $GraphHeight, @timesel, @$args); - if (my $err = RRDs::error ()) - { - print STDERR "RRDs::graph failed: $err\n"; - exit (1); + 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 :