08557b479da3ebc97d26f68b1ab17c84552b2fe9
[collectd.git] / contrib / collection3 / bin / graph.cgi
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5 use lib ('../lib');
6
7 use FindBin ('$RealBin');
8 use Carp (qw(confess cluck));
9 use CGI (':cgi');
10 use RRDs ();
11
12 use Collectd::Graph::TypeLoader (qw(tl_read_config tl_load_type));
13
14 use Collectd::Graph::Common (qw(sanitize_type get_selected_files
15       epoch_to_rfc1123));
16 use Collectd::Graph::Type ();
17
18 our $Debug = param ('debug');
19 our $Begin = param ('begin');
20 our $End = param ('end');
21 our $GraphWidth = param ('width');
22
23 if ($Debug)
24 {
25   print <<HTTP;
26 Content-Type: text/plain
27
28 HTTP
29 }
30
31 tl_read_config ("$RealBin/../etc/collection.conf");
32
33 { # Sanitize begin and end times
34   $End ||= 0;
35   $Begin ||= 0;
36
37   if ($End =~ m/\D/)
38   {
39     $End = 0;
40   }
41
42   if (!$Begin || !($Begin =~ m/^-?([1-9][0-9]*)$/))
43   {
44     $Begin = -86400;
45   }
46
47   if ($Begin < 0)
48   {
49     if ($End)
50     {
51       $Begin = $End + $Begin;
52     }
53     else
54     {
55       $Begin = time () + $Begin;
56     }
57   }
58
59   if ($Begin < 0)
60   {
61     $Begin = time () - 86400;
62   }
63
64   if (($End > 0) && ($Begin > $End))
65   {
66     my $temp = $End;
67     $End = $Begin;
68     $Begin = $temp;
69   }
70 }
71
72 my $type = param ('type') or die;
73 my $obj;
74
75 $obj = tl_load_type ($type);
76 if (!$obj)
77 {
78   confess ("tl_load_type ($type) failed");
79 }
80
81 $type = ucfirst (lc ($type));
82 $type =~ s/_([A-Za-z])/\U$1\E/g;
83 $type = sanitize_type ($type);
84
85 my $files = get_selected_files ();
86 if ($Debug)
87 {
88   require Data::Dumper;
89   print STDOUT Data::Dumper->Dump ([$files], ['files']);
90 }
91 for (@$files)
92 {
93   $obj->addFiles ($_);
94 }
95
96 my $expires = time ();
97 # IF (End is `now')
98 #    OR (Begin is before `now' AND End is after `now')
99 if (($End == 0) || (($Begin <= $expires) && ($End >= $expires)))
100 {
101   # 400 == width in pixels
102   my $timespan;
103
104   if ($End == 0)
105   {
106     $timespan = $expires - $Begin;
107   }
108   else
109   {
110     $timespan = $End - $Begin;
111   }
112   $expires += int ($timespan / 400.0);
113 }
114 # IF (End is not `now')
115 #    AND (End is before `now')
116 # ==> Graph will never change again!
117 elsif (($End > 0) && ($End < $expires))
118 {
119   $expires += (366 * 86400);
120 }
121 elsif ($Begin > $expires)
122 {
123   $expires = $Begin;
124 }
125
126 print STDOUT header (-Content_type => 'image/png',
127   -Last_Modified => epoch_to_rfc1123 ($obj->getLastModified ()),
128   -Expires => epoch_to_rfc1123 ($expires));
129
130 if ($Debug)
131 {
132   print "\$expires = $expires;\n";
133 }
134
135 my $args = $obj->getRRDArgs (0);
136
137 if ($Debug)
138 {
139   require Data::Dumper;
140   print STDOUT Data::Dumper->Dump ([$obj], ['obj']);
141   print STDOUT join (",\n", @$args) . "\n";
142   print STDOUT "Last-Modified: " . epoch_to_rfc1123 ($obj->getLastModified ()) . "\n";
143 }
144 else
145 {
146   my @timesel = ();
147
148   if ($End) # $Begin is always true
149   {
150     @timesel = ('-s', $Begin, '-e', $End);
151   }
152   else
153   {
154     @timesel = ('-s', $Begin); # End is implicitely `now'.
155   }
156
157   $| = 1;
158   RRDs::graph ('-', '-a', 'PNG', @timesel, @$args);
159   if (my $err = RRDs::error ())
160   {
161     print STDERR "RRDs::graph failed: $err\n";
162     exit (1);
163   }
164 }
165
166 exit (0);
167
168 # vim: set shiftwidth=2 softtabstop=2 tabstop=8 :