network: Add missing freeaddrinfo on error path.
[collectd.git] / contrib / collectd2html.pl
1 #!/usr/bin/perl
2
3 ################################################################################
4 #
5 # collectd2html.pl
6 #
7 # Description:
8 #   Generate an html page with all rrd data gathered by collectd.
9 #
10 # Usage:
11 #   collectd2html.pl
12 #
13 #   When run on <host>, it generated <host>.html and <host>.dir, the latter
14 #   containing all necessary images.
15 #
16 #
17 # Copyright 2006 Vincent StehlĂ© <vincent.stehle@free.fr>
18 #
19 # Patch to configure the data directory and hostname by Eddy Petrisor
20 # <eddy.petrisor@gmail.com>.
21 #
22 # This program is free software; you can redistribute it and/or modify
23 # it under the terms of the GNU General Public License as published by
24 # the Free Software Foundation; either version 2 of the License, or
25 # (at your option) any later version.
26 #
27 # This program is distributed in the hope that it will be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30 # GNU General Public License for more details.
31 #
32 # You should have received a copy of the GNU General Public License
33 # along with this program; if not, write to the Free Software
34 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
35 #
36 ################################################################################
37
38 use warnings;
39 use strict;
40 use Fatal qw(open close);
41 use File::Basename;
42 use Getopt::Long qw(:config no_ignore_case bundling pass_through);
43
44 my $DIR       = "/var/lib/collectd";
45 my $HOST      = undef;
46 my $IMG_FMT   = "PNG";
47 my $RECURSIVE = 1;
48
49 GetOptions (
50     "host=s"         => \$HOST,
51     "data-dir=s"     => \$DIR,
52     "image-format=s" => \$IMG_FMT,
53     "recursive"      => \$RECURSIVE
54 );
55
56 if (($DIR !~ m/\/rrd\/?$/) && (-d "$DIR/rrd")) {
57         $DIR .= "/rrd";
58 }
59
60 if (defined($HOST) && ($DIR !~ m/\/$HOST\/?$/) && (-d "$DIR/$HOST")) {
61         $DIR .= "/$HOST";
62 }
63
64 my @COLORS = (0xff7777, 0x7777ff, 0x55ff55, 0xffcc77, 0xff77ff, 0x77ffff,
65         0xffff77, 0x55aaff);
66 my @tmp = `/bin/hostname -f`; chomp(@tmp);
67 $HOST = $tmp[0] if (! defined $HOST);
68 my $svg_p = ($IMG_FMT eq "SVG");
69 my $IMG_SFX = $svg_p ? ".svg" : ".png";
70 my $IMG_DIR = "${HOST}.dir";
71 my $HTML = "${HOST}.xhtml";
72
73 ################################################################################
74 #
75 # fade_component
76 #
77 # Description:
78 #   Fade a color's component to the white.
79 #
80 ################################################################################
81 sub fade_component($)
82 {
83         my($component) = @_;
84         return (($component + 255 * 5) / 6);
85 }
86
87 ################################################################################
88 #
89 # fade_color
90 #
91 # Description:
92 #   Fade a color to the white.
93 #
94 ################################################################################
95 sub fade_color($)
96 {
97         my($color) = @_;
98         my $r = 0;
99
100         for my $i (0 .. 2){
101                 my $shft = ($i * 8);
102                 my $component = (($color >> $shft) & 255);
103                 $r |= (fade_component($component) << $shft);
104         }
105
106         return $r;
107 }
108
109 ################################################################################
110 #
111 # main
112 #
113 ################################################################################
114 system("rm -fR $IMG_DIR");
115 system("mkdir -p $IMG_DIR");
116 local *OUT;
117 open(OUT, ">$HTML");
118 my $title="Rrd plot for $HOST";
119
120 print OUT <<END;
121 <!DOCTYPE html PUBLIC
122   "-//W3C//DTD XHTML 1.1//EN"
123   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
124 <html xmlns="http://www.w3.org/1999/xhtml">
125 <head>
126 <style type="text/css" media="screen">
127 .graph { text-align: center; }
128 object.graph { width: 670; height: 179; }
129 </style>
130 <title>$title</title>
131 <meta http-equiv="Content-Type"
132       content="application/xhtml+xml; charset=us-ascii" />
133 </head>
134 <body>
135 END
136
137 # list interesting rrd
138 my @rrds;
139 my @list;
140
141 if ($RECURSIVE) {
142         @list = `find $DIR -type f -name '*.rrd'`;
143 }
144 else {
145         @list = `ls $DIR/*.rrd`;
146 }
147 chomp(@list);
148
149 @list = sort @list;
150 foreach my $rrd (@list){
151         $rrd =~ m/^$DIR\/(.*)\.rrd$/;
152         push(@rrds, $1);
153 }
154
155 # table of contents
156 print OUT <<END;
157 <h1><a id="top">$title</a></h1>
158 <p>
159 END
160
161 foreach my $bn (@rrds){
162         my $cleaned_bn = $bn;
163         $cleaned_bn =~ tr/%\//__/;
164         print OUT <<END;
165 <a href="#$cleaned_bn">$bn</a>
166 END
167 }
168
169 print OUT <<END;
170 </p>
171 END
172
173 # graph interesting rrd
174 for (my $i = 0; $i < scalar(@rrds); ++$i) {
175         my $bn = $rrds[$i];
176         print "$bn\n";
177
178         my $rrd = $list[$i];
179         my $cmd = "rrdtool info $rrd |grep 'ds\\[' |sed 's/^ds\\[//'" 
180                 ." |sed 's/\\].*//' |sort |uniq";
181         my @dss = `$cmd`; chomp(@dss);
182
183         # all DEF
184         my $j = 0;
185         my $defs = "";
186
187         foreach my $ds (@dss){
188                 $defs .= " DEF:${ds}_avg=$rrd:$ds:AVERAGE"
189                         ." DEF:${ds}_max=$rrd:$ds:MAX ";
190         }
191
192         # all AREA
193         $j = 0;
194
195         foreach my $ds (@dss){
196                 my $color = $COLORS[$j % scalar(@COLORS)]; $j++;
197                 my $faded_color = fade_color($color);
198                 $defs .= sprintf(" AREA:${ds}_max#%06x ", $faded_color);
199         }
200
201         # all LINE      
202         $j = 0;
203
204         foreach my $ds (@dss){
205                 my $color = $COLORS[$j % scalar(@COLORS)]; $j++;
206                 $defs .= sprintf(" LINE2:${ds}_avg#%06x:$ds"
207                         ." GPRINT:${ds}_avg:AVERAGE:%%5.1lf%%sAvg"
208                         ." GPRINT:${ds}_max:MAX:%%5.1lf%%sMax"
209                         , $color);
210         }
211
212         my $cleaned_bn = $bn;
213         $cleaned_bn =~ tr/%\//__/;
214         print OUT <<END;
215 <h2><a id="$cleaned_bn">$bn</a></h2>
216 END
217
218         # graph various ranges
219         foreach my $span (qw(1hour 1day 1week 1month)){
220                 system("mkdir -p $IMG_DIR/" . dirname($bn));
221                 my $img = "$IMG_DIR/${bn}-$span$IMG_SFX";
222
223                 my $cmd = "rrdtool graph $img"
224                         ." -t \"$bn $span\" --imgformat $IMG_FMT --width 600 --height 100"
225                         ." --start now-$span --end now --interlaced"
226                         ." $defs >/dev/null 2>&1";
227                 system($cmd);
228
229                 my $cleaned_img = $img; $cleaned_img =~ s/%/%25/g;
230                 if (! $svg_p) {
231                         print OUT <<END;
232 <p class="graph"><img src="$cleaned_img" alt="${bn} $span" /></p>
233 END
234                 } else {
235                         print OUT <<END;
236 <p class="graph"><object data="$cleaned_img" type="image/svg+xml">
237   ${bn} $span</object></p>
238 END
239                 }
240         }
241
242         print OUT <<END;
243 <p><a href="#top">[top]</a></p>
244 END
245 }
246
247 print OUT <<END;
248 <hr />
249 <p>
250   <a href="http://validator.w3.org/check?uri=referer"><img
251      src="http://www.w3.org/Icons/valid-xhtml10"
252      alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
253 </p>
254 </body>
255 </html>
256 END
257
258 close(OUT);