ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/experimental/reports/graphing/graph.pl
Revision: 1.7
Committed: Wed Mar 13 20:50:48 2002 UTC (22 years, 2 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.6: +4 -1 lines
Log Message:
Added a graph of "the last year". Also fixed a minor bug with the script to
create the rrd's. As an aside, I've noticed the grid on the graphs seems to
differ between the different graphs. I'm sure this is because I've got some
of my numbers a bit silly ;) oh well :)

File Contents

# Content
1 #!/usr/bin/perl -w
2
3 # -----------------------------------------------------------
4 # i-scream graph generation script
5 # http://www.i-scream.org.uk
6 #
7 # Generates graphs from rrd databases for i-scream data.
8 #
9 # $Author: tdb $
10 # $Id: graph.pl,v 1.6 2002/03/11 17:06:45 tdb Exp $
11 #------------------------------------------------------------
12
13 ## TODO
14 # possibly make more configurable?
15 # -- allow configurable periods of graphs
16 # -- comments, types, etc
17 # -- move all to external config file
18
19 $| = 1;
20 use strict;
21 use RRDs;
22
23 # Base directory for images
24 # (a directory will be constructed for each host under this)
25 my($imgdir) = "/home/tdb/public_html/rrd";
26
27 # Location of RRD databases
28 my($rrddir) = "/u1/i-scream/rrd";
29
30 # / converted to a decimal then hex'd
31 my($hex_slash) = "_2f";
32 # _ converted to a decimal then hex'd
33 my($hex_underscore) = "_5f";
34
35 # Read the contents of the base directory
36 # and pull out the list of subdirectories (except . and .. :)
37 opendir(DIR, $rrddir);
38 my(@rrddirlist) = grep { -d "$rrddir/$_" && !/^\.$/ && !/^\.\.$/ } readdir(DIR);
39 closedir DIR;
40
41 # look through each directoty, as they might
42 # contain rrds for a particular machine
43 foreach my $machine (@rrddirlist) {
44 # Read the contents of the directory
45 opendir(DIR, "$rrddir/$machine");
46 my(@rrdlist) = grep { /\.rrd$/ && -f "$rrddir/$machine/$_" } readdir(DIR);
47 closedir DIR;
48
49 # See what rrd we have, and generate the graphs accordingly
50 foreach my $rrd (@rrdlist) {
51 chomp $rrd;
52 if($rrd =~ /^(cpu)\.rrd$/) {
53 my(@data);
54 my(@rawdata);
55 push @data, "LINE2:$1:idle:idle#00FF00:idle cpu";
56 push @data, "LINE2:$1:user:user#0000FF:user cpu";
57 push @data, "LINE2:$1:kernel:kernel#00FFFF:kernel cpu";
58 push @data, "LINE2:$1:swap:swap#FF00FF:swap cpu";
59 push @data, "LINE2:$1:iowait:iowait#FF0000:iowait cpu";
60 push @rawdata, "--upper-limit=100";
61 &makegraph($machine, $1, "CPU Usage for $machine", \@data, \@rawdata);
62 }
63 if($rrd =~ /^(mem)\.rrd$/) {
64 my(@data);
65 my(@rawdata);
66 # we don't actually want to display free memory,
67 # although we need it to do inuse...
68 push @data, "NONE:$1:free:free#CCCCFF:free memory";
69 push @data, "LINE2:$1:total:total#0000FF:total memory";
70 # calculate inuse
71 push @rawdata, "CDEF:inuse=total,free,-";
72 # and add it to the graph
73 push @rawdata, "AREA:inuse#CCCCFF:memory in use";
74 push @rawdata, "--base=1024";
75 &makegraph($machine, $1, "Memory Usage for $machine", \@data, \@rawdata);
76 }
77 if($rrd =~ /^(load)\.rrd$/) {
78 my(@data);
79 push @data, "LINE2:$1:load1:load1#CCCCFF:1 minute load average";
80 push @data, "LINE2:$1:load5:load5#7777FF:5 minute load average";
81 push @data, "LINE2:$1:load15:load15#0000FF:15 minute load average";
82 &makegraph($machine, $1, "Loads for $machine", \@data);
83 }
84 if($rrd =~ /^(proc)\.rrd$/) {
85 my(@data);
86 push @data, "LINE2:$1:cpu:cpu#00FF00:cpu processes";
87 push @data, "LINE2:$1:sleeping:sleeping#0000FF:sleeping processes";
88 push @data, "LINE2:$1:stopped:stopped#00FFFF:stopped processes";
89 push @data, "LINE2:$1:total:total#FF00FF:total processes";
90 push @data, "LINE2:$1:zombie:zombie#FF0000:zombie processes";
91 &makegraph($machine, $1, "Processes on $machine", \@data);
92 }
93 if($rrd =~ /^(swap)\.rrd$/) {
94 my(@data);
95 my(@rawdata);
96 # we don't actually want to display free swap,
97 # although we need it to do inuse...
98 push @data, "NONE:$1:free:free#CCCCFF:free swap";
99 push @data, "LINE2:$1:total:total#0000FF:total swap";
100 # calculate inuse
101 push @rawdata, "CDEF:inuse=total,free,-";
102 # and add it to the graph
103 push @rawdata, "AREA:inuse#CCCCFF:swap in use";
104 push @rawdata, "--base=1024";
105 &makegraph($machine, $1, "Swap Usage for $machine", \@data, \@rawdata);
106 }
107 if($rrd =~ /^(users)\.rrd$/) {
108 my(@data);
109 push @data, "AREA:$1:count:count#CCCCFF:user count";
110 &makegraph($machine, $1, "User Count for $machine", \@data);
111 }
112 if($rrd =~ /^(disk)-(\S+).rrd$/) {
113 my(@data);
114 my(@rawdata);
115 push @data, "LINE2:$1-$2:kbytes:kbytes#0000FF:total size";
116 push @data, "AREA:$1-$2:used:used#CCCCFF:used";
117 push @rawdata, "--base=1024";
118 my($type) = $1;
119 my($name) = $2;
120 my($nicename) = $2;
121 $nicename =~ s/$hex_slash/\//g;
122 $nicename =~ s/$hex_underscore/_/g;
123 &makegraph($machine, "$type-$name", "Disk Usage for $machine on $nicename", \@data, \@rawdata);
124 }
125 # probably a queue with a name like this :)
126 if($rrd =~ /^(\d+)_0\.rrd$/) {
127 my(@data);
128 my(@rawdata);
129 my($baserrd) = $1;
130 my($i) = 0;
131 while( -f "$rrddir/$machine/$baserrd\_$i.rrd" ) {
132 push @data, "LINE2:$baserrd\_$i:size:size$i" . &get_colour($i) . ":queue$i size ";
133 ++$i;
134 }
135 push @data, "LINE2:$baserrd\_0:total:total#FF0000:packets/sec - currently";
136 push @rawdata, "GPRINT:total:LAST:%lf %spackets/sec";
137 my($comment);
138 if(-f "$rrddir/$machine/$baserrd.def") {
139 open(DEF, "$rrddir/$machine/$baserrd.def");
140 $comment = <DEF>;
141 chomp $comment if defined $comment;
142 }
143 $comment = "unknown queue" if not defined $comment;
144 &makegraph($machine, $baserrd, $comment, \@data, \@rawdata);
145 }
146 }
147 }
148
149 #
150 # subroutine to make some graphs
151 #
152 # $machine = name of the machine
153 # (eg. kernow.ukc.ac.uk)
154 # $type = the type of graph for the machine
155 # (eg. cpu)
156 # $title = the title for the graph
157 # (eg. kernow CPU usage)
158 # $dataref = a reference to an array containing information for the graph
159 # elements of format: "gtype:rrdname:dsname:name#colour:comment with spaces"
160 # (if gtype is "NONE" only a DEF of 'name' will be defined, no line will be plotted)
161 # $rawcmdref = a reference to an array containing raw rrd commands
162 # elements a single command each, no spaces
163 #
164
165 sub makegraph() {
166 my($machine, $type, $title, $dataref, $rawcmdref) = @_;
167 # pass in these arrays by reference
168 my(@data) = @$dataref if defined $dataref;
169 my(@rawcmd) = @$rawcmdref if defined $rawcmdref;
170 # check if directory exists for images
171 if(! -d "$imgdir/$machine") {
172 # not sure on this umask, but it seems to work?
173 mkdir "$imgdir/$machine", 0777;
174 }
175 my(@rrdcmd);
176 foreach my $dataitem (@data) {
177 # dataitem should be: "gtype:rrdname:dsname:name#colour:comment with spaces"
178 # (if gtype is "NONE" only a DEF of 'name' will be defined, no line will be plotted)
179 if($dataitem =~ /^(\S+):(\S+):(\S+):(\S+)#(.{6}):(.*)$/) {
180 push @rrdcmd, "DEF:$4=$rrddir/$machine/$2.rrd:$3:AVERAGE";
181 if($1 ne "NONE") {
182 push @rrdcmd, "$1:$4#$5:$6";
183 }
184 }
185 }
186 push @rrdcmd, "--title=$title";
187 push @rrdcmd, "--imgformat=PNG";
188 push @rrdcmd, "--lower-limit=0";
189 # not entirely convinced this is good...
190 push @rrdcmd, "--alt-autoscale-max";
191 # add any further raw commands
192 push @rrdcmd, @rawcmd;
193 RRDs::graph ("$imgdir/$machine/$type-3h.png", "--start=-10800", @rrdcmd);
194 my($err_3h) = RRDs::error;
195 print STDERR "Error generating 3h graph for $machine/$type: $err_3h\n" if $err_3h;
196 RRDs::graph ("$imgdir/$machine/$type-1d.png", "--start=-86400", @rrdcmd);
197 my($err_1d) = RRDs::error;
198 print STDERR "Error generating 1d graph for $machine/$type: $err_1d\n" if $err_1d;
199 RRDs::graph ("$imgdir/$machine/$type-1w.png", "--start=-604800", @rrdcmd);
200 my($err_1w) = RRDs::error;
201 print STDERR "Error generating 1w graph for $machine/$type: $err_1w\n" if $err_1w;
202 RRDs::graph ("$imgdir/$machine/$type-1m.png", "--start=-2678400", @rrdcmd);
203 my($err_1m) = RRDs::error;
204 print STDERR "Error generating 1m graph for $machine/$type: $err_1m\n" if $err_1m;
205 RRDs::graph ("$imgdir/$machine/$type-1y.png", "--start=-31536000", @rrdcmd);
206 my($err_1y) = RRDs::error;
207 print STDERR "Error generating 1y graph for $machine/$type: $err_1y\n" if $err_1y;
208 return;
209 }
210
211 # hacky subroutine to return a colour
212 # could be done much better somehow :/
213 sub get_colour {
214 my($col) = @_;
215 if($col == 0) {
216 return "#0000FF";
217 }
218 elsif($col == 1) {
219 return "#00FF00";
220 }
221 elsif($col == 2) {
222 return "#FF00FF";
223 }
224 elsif($col == 3) {
225 return "#FFFF00";
226 }
227 elsif($col == 4) {
228 return "#00FFFF";
229 }
230 else {
231 return "#000066";
232 }
233 }