#!@@PERL@@ -Tw # # # Copyright (C) 2004 Jimmy Olsen # # 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-cgi-graph.in 1142 2006-10-17 12:27:35Z tore $ # # $Log$ # Revision 1.5.2.2 2005/03/09 20:12:40 jimmyo # Correct expires-headers in CGI output (SF#1159742). # # Revision 1.5.2.1 2005/01/29 18:22:59 jimmyo # Bugfix in munin-cgi-graph with hostnames including - (SF#1111510). # # Revision 1.5 2004/12/22 20:01:15 jimmyo # Optimised munin-cgi-graph a bit. # # Revision 1.4 2004/11/16 20:00:44 jimmyo # License cleanups. # use RRDs; use Munin; use strict; use IO::Handle; use Date::Manip; use POSIX qw(strftime); my $GRAPHER = "@@LIBDIR@@/munin-graph"; my $conffile = "@@CONFDIR@@/munin.conf"; my %TIMES = ( "day" => ["--noweek", "--nomonth", "--noyear", "--nosumweek", "--nosumyear"], "week" => ["--noday", "--nomonth", "--noyear", "--nosumweek", "--nosumyear"], "month" => ["--noday", "--noweek", "--noyear", "--nosumweek", "--nosumyear"], "year" => ["--noday", "--noweek", "--nomonth", "--nosumweek", "--nosumyear"], "week-sum" => ["--noday", "--nomonth", "--noyear", "--noweek", "--nosumyear"], "year-sum" => ["--noday", "--noweek", "--nomonth", "--nosumweek", "--noyear"] ); my %period = ( "day" => 300, "week" => 1800, "month" => 7200, "year" => 86400, "week-sum" => 1800, "year-sum" => 86400 ); my $log = new IO::Handle; my $scale = "day"; my $host = ""; my $serv = ""; my $dom = ""; my $config = &munin_readconfig ($conffile); my $path = $ENV{PATH_INFO} || ""; $path =~ s/^\///; ($dom, $host, $serv) = split /\//, $path; ($serv, $scale) = split /-/, $serv, 2; $scale =~ s/\.png$//; &verify_parameters ($dom, $host, $serv, $scale); my $filename = get_picture_filename ($config, $dom, $host, $serv, $scale); my $time = time; if (-f $filename) { my @sstats = stat ($filename); my $slast_modified = strftime ("%a, %d %b %Y %H:%M:%S %Z", localtime ($sstats[9])); if (defined $ENV{HTTP_IF_MODIFIED_SINCE} and !&modified ($ENV{HTTP_IF_MODIFIED_SINCE}, $sstats[9]-1)) { print "Status: 304\n"; print "Content-Type: image/png\n"; print "Expires: ", strftime ("%a, %d %b %Y %H:%M:%S GMT", gmtime(time+($period{$scale}-($time%$period{$scale})))), "\n"; print "Last-Modified: $slast_modified\n"; print "\n"; exit 0; } } if (! &graph_usable ($filename, $time)) { my $ret = (&draw_graph ($host, $serv, $TIMES{$scale}) || "Unknown error"); if (! -f $filename) { ::logger ("Warning: Could not draw graph \"$host-$serv-$scale.png\": $ret"); print "Status: 500\n"; print "Content-Type: image/png\n"; print "\n"; exit 0; } } my @stats = stat ($filename); my $last_modified = strftime ("%a, %d %b %Y %H:%M:%S %Z", localtime ($stats[9])); print "Content-Type: image/png\n"; print "Expires: ", strftime ("%a, %d %b %Y %H:%M:%S GMT", gmtime(time+($period{$scale}-($time%$period{$scale})))), "\n"; print "Last-Modified: $last_modified\n"; print "\n"; &graph ($filename); sub graph { my $filename = shift; open (GRAPH, $filename) or die "Warning: Could not open picture file \"$filename\" for reading: $!\n"; print while (); close (GRAPH); } sub get_picture_filename { my $config = shift; my $domain = shift; my $name = shift; my $service = shift; my $scale = shift; return "$config->{'htmldir'}/$domain/$name-$service-$scale.png"; } sub logger_open { my $dirname = shift; if (!$log->opened) { unless (open ($log, ">>$dirname/munin-cgi-graph.log")) { print STDERR "Warning: Could not open log file \"$dirname/munin-cgi-graph.log\" for writing: $!"; } } } sub logger { my ($comment) = @_; my $now = strftime ("%b %d %H:%M:%S", localtime); if ($log->opened) { print $log "$now - $comment\n"; } else { if (defined $config->{logdir}) { if (open ($log, ">>$config->{logdir}/munin-cgi-graph.log")) { print $log "$now - $comment\n"; } else { print STDERR "Warning: Could not open log file \"$config->{logdir}/munin-cgi-graph.log\" for wr iting: $!"; print STDERR "$now - $comment\n"; } } else { print STDERR "$now - $comment\n"; } } } sub verify_parameters { my $dom = shift; my $host = shift; my $serv = shift; my $scale = shift; if (!$dom) { print STDERR "Warning: Request for graph without specifying domain. Bailing out.\n"; exit 1; } if (!$host) { print STDERR "Warning: Request for graph without specifying host. Bailing out.\n"; exit 1; } if (!$serv) { print STDERR "Warning: Request for graph without specifying service. Bailing out.\n"; exit 1; } if (!$scale) { print STDERR "Warning: Request for graph without specifying scale. Bailing out.\n"; exit 1; } else { if (!defined $TIMES{$scale}) { print STDERR "Warning: Weird scale setting \"$scale\". Bailing out.\n"; exit 1; } } } sub graph_usable { my $filename = shift; my $time = shift; if (-f $filename) { my @stats = stat (_); if (($stats[9]) > ($time - $time%$period{$scale})) { #print STDERR "Skipping munin-graph-run for \"$filename\".\n"; #print STDERR ("Graph unexpired for $scale. ($stats[9] , $time, ", ($time%$period{$scale}), ", ", ($time - $time%$period{$scale}), ").\n"); return 1; } else { #print STDERR ("Graph expired for $scale. ($stats[9] , $time, ", ($time%$period{$scale}), ", ", ($time - $time%$period{$scale}), ").\n"); return 0; } } return 0; } sub draw_graph { my $host = shift; my $serv = shift; my $scale = shift; $serv =~ s/[^\w_\/"'\[\]\(\)+=-]/_/; $serv =~ /^(.+)$/; $serv = $1; $host =~ s/[^\w_\/"'\[\]\(\)+=-]/_/; $host =~ /^(.+)$/; $host = $1; my @params = ($GRAPHER); push @params, @$scale; push @params, "--skip-locking", "--skip-stats"; push @params, "--host", $host, "--service", $serv; push @params, "STDERR>&STDOUT"; my $file = "/dev/null"; unless (open (IN, "-|")) { %ENV=(); exec @params; } $file = join (' ', ); close (IN); return $file; } sub modified { # Format of since_string If-Modified-Since: Wed, 23 Jun 2004 16:11:06 GMT my $since_string = shift; my $created = shift; my $ifmodsec = &UnixDate (&ParseDateString ($since_string), "%s"); return 1 if ($ifmodsec < $created); return 0; } # vim: syntax=perl ts=8