jablonka.czprosek.czf

hotsanic

Subversion Repositories:
[/] [branches/] [HotSaNIC-0.5.0-pre6/] [lib/] [HotSaNICdiagram.pm] - Blame information for rev 18

 

Line No. Rev Author Line
11simandl#
2# $Id: HotSaNICdiagram.pm,v 1.29 2004/09/19 10:07:19 bernisys Exp $
3#
4 
5package HotSaNICdiagram;
6 
7use RRDs;
8 
9($VERSION = '$Revision: 1.29 $') =~ s/.*(\d+\.\d+).*/$1/;
10 
11my @Weekday=("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
12 
13######################################################################
14#
15# evaluates some diagram properties from the given range
16#
17# Usage:
18# ($description,$file_description,$build_interval,$diagram_range,$timestring)=get_diagram_properties($range);
19#
20sub get_diagram_properties {
21 my ($range)=@_;
22 my ($descr,$file,$build,$fullrange);
23 if ($range eq "1h") { $descr="hour"; $file=$descr; $build=0; $fullrange=3600; }
24 elsif ($range eq "6h") { $descr="6 hours"; $file="6h"; $build=30; $fullrange=21600; }
25 elsif ($range eq "1day") { $descr="day"; $file=$descr; $build=120; $fullrange=86400; }
26 elsif ($range eq "1week") { $descr="week"; $file=$descr; $build=1000; $fullrange=604800; }
27 elsif ($range eq "1month") { $descr="month"; $file=$descr; $build=4300; $fullrange=2592000; }
28 elsif ($range eq "1year") { $descr="year"; $file=$descr; $build=52500; $fullrange=31536000; }
29 
30 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
31 $year+=1900;
32 $mon++;
33 if ($mon<10) { $mon="0".$mon; }
34 if ($mday<10) { $mday="0".$mday; }
35 if ($hour<10) { $hour="0".$hour; }
36 if ($min<10) { $min="0".$min; }
37 $buildtime="$Weekday[$wday] $year-$mon-$mday $hour:$min";
38 
39 return ($descr,$file,$build,$fullrange,$buildtime);
40 }
41 
42######################################################################
43#
44# Creates a diagram from the options passed within a config hash
45#
46# Usage:
47# graph(%CONFIGHASH);
48#
49# Hints:
50# The hash has to contain the following items:
51#
52# %CONFIGHASH=( FILENAME => "full path to output file without suffix"
53# FORMAT => "gif" # ("png" or "gif")
54# INTERVAL => <seconds between neccessary update>
55# FORCE => 0 for automatic checking, >0 forces plot
56# RANGE => plot range of diagram (1year 6h 1h ...)
57# DEBUGLEVEL => everything >1 plots complete optiin array
58# OPTIONS => array of options that will be passed tpo RRDs
59# assign it like this: => [(@a1,@a2,...)]
60#
61sub graph {
62 my %CONF=@_;
63 
64 my $FILE=$CONF{FILENAME}.".".$CONF{FORMAT};
65 my $TEMPFILE=$CONF{FILENAME}."-temp.".$CONF{FORMAT};
66 
67 my @OPTIONS=@{$CONF{OPTIONS}};
68 
69 if (! -e $FILE) { $CONF{FORCE}++; }
70 else { $CONF{FORCE}++ if time >= (stat($FILE))[9]+$CONF{INTERVAL}; }
71 
72 if ($CONF{FORCE} > 0) {
73 if ($CONF{DEBUGLEVEL} > 1) { print join("\n",$TEMPFILE,@OPTIONS),"\n"; }
74 my ($prints,$xs,$ys)=RRDs::graph $TEMPFILE,@OPTIONS;
75 if ($ERROR = RRDs::error) { print time," ",$CONF{MODNAME},": $ERROR\n"; }
76 else {
77 rename $TEMPFILE,$FILE;
78 printf " %9s %4d x %4d %s\n", $CONF{RANGE},$xs,$ys,$FILE;
79 }
80 }
81 }
82 
83sub check_args {
84 my $OPT=0;
85 $FORCE=0;
86 $DEBUGLEVEL=-1;
87 %PLOT=();
88 foreach (@_) {
89 $FORCE=1 if $_ eq "a";
90 $DEBUGLEVEL=100 if $_ eq "d";
91 if ($OPT==1) { $PLOT{$_}=1; $OPT=0; }
92 $OPT=1 if $_ eq "g";
93 if ( ($_ eq "?") or ($_ eq "h") ) {
94 print "options:\n
95 g <name> only graph item <name>
96 (can be used multiple times, default: plot all)\n
97 a plot all time-graphs of selected items
98 (default: plot only expired graphs)\n
99 d enable debug mode (prints all graph options -
100 much output!)\n
101 ? or h display this help-text
102 \n";
103 exit;
104 }
105 }
106 return ($FORCE,$DEBUGLEVEL,%PLOT);
107 }
108 
109########################################
110# get_common_options calculates an array of common module-specific and
111# global diagram options to be passed to RRDs::graph. it accepts a hash
112# containing both modulespecific and global settings.
113#
114sub get_common_options {
115 my %CONFIG=@_;
116 my @OPTIONS=();
117 if ($CONFIG{GRAPH_RIGID} == 1 ) { push @OPTIONS,"-r"; }
118 if ($CONFIG{GRAPH_FORCE_LEGEND} == 1 ) { push @OPTIONS,"-F"; }
119 if ($CONFIG{GRAPH_STYLE} eq "log" ) {
120 push @OPTIONS,"-o";
121 $CONFIG{GRAPH_MIN}=$CONFIG{GRAPH_MIN_LOG};
122 }
123 if (defined $CONFIG{GRAPH_BASE}) {
124 if ( ($CONFIG{GRAPH_BASE} eq "percent") or ($CONFIG{GRAPH_BASE} eq "%") ) {
125 if (defined $CONFIG{GRAPH_MAX}) { $CONFIG{GRAPH_MAX}*=100; }
126 if (defined $CONFIG{GRAPH_MIN}) { $CONFIG{GRAPH_MIN}*=100; }
127 }
128 if ($CONFIG{GRAPH_BASE} eq "bits") {
129 if (defined $CONFIG{GRAPH_MAX}) { $CONFIG{GRAPH_MAX}*=8; }
130 if (defined $CONFIG{GRAPH_MIN}) { $CONFIG{GRAPH_MIN}*=8; }
131 }
132 elsif ($CONFIG{GRAPH_BASE} eq "ms") {
133 if (defined $CONFIG{GRAPH_MAX}) { $CONFIG{GRAPH_MAX}/=1000; }
134 if (defined $CONFIG{GRAPH_MIN}) { $CONFIG{GRAPH_MIN}/=1000; }
135 }
136 elsif ($CONFIG{GRAPH_BASE} eq "us") {
137 if (defined $CONFIG{GRAPH_MAX}) { $CONFIG{GRAPH_MAX}/=1000000; }
138 if (defined $CONFIG{GRAPH_MIN}) { $CONFIG{GRAPH_MIN}/=1000000; }
139 }
140 }
141 
142 push @OPTIONS,(
143 "-i", # graphic interlaced mode
144 "-w",$CONFIG{WIDTH}, # drawing area width
145 "-h",$CONFIG{HEIGHT}, # drawing area height
146 "-b",$CONFIG{GRAPH_UNIT}, # value of "1k" (1000 or 1024)
147 "-u",$CONFIG{GRAPH_MAX}, # upper initial border
148 "-l",$CONFIG{GRAPH_MIN}, # lower initial border
149 "-a",uc($CONFIG{IMAGEFORMAT}) # image format
150 );
151 return @OPTIONS;
152 }
153 
154 
155######################################################################
156#
157# generates an array suitable to feed to RRDs::graph to build a graph
158# including a legend with the desired consolidation functions.
159#
160# Usage:
161# insert_data(type,var,color,description,legends,unit,use_SI);
162#
163# type: AREA LINE1 LINE2 LINE3 STACK
164#
165# var: RRD variable to be graphed and variables which will
166# be assigned to min, average, max and now. They
167# have to be separated by spaces. If less than five
168# variables are stated, the LAST entry will be copied
169# to the remaining positions.
170# If you just want to insert a legend without adding a
171# graph, the first element must be a numerical zero "0"
172# The "description" can be used for padding the legend.
173#
174# color: graph's color in RRDs::graph notation ( RRGGBB )
175#
176# description: name of the graph or short description that will be
177# used in the legend
178#
179# legends: one or more space-separated occurances of:
180# min avg max cur now ("now" is the same as "cur")
181#
182# unit: the unit that will be appended after the last legend
183#
184# use_SI: 0 -> just print the plain value
185# 1 -> print values in SI units (micro, milli, kilo, mega, ...)
186# -1 -> same as "1", but SI-units will be added without a space
187#
188# EXAMPLE:
189#
190# insert_data("AREA","abc xyz","#0000ff","test legend","min max","bytes",1);
191#
192# -> draw a blue area with the rrd variable "abc" and add a corrosponding
193# legend to it, but refer the legend to the variable "xyz". The legend
194# will use SI-units and the unit "bytes". It will look like this:
195#
196# [#] test legend (min: 1.23k max: 12.34M bytes)
197#
198sub insert_data {
199 my $graphtype=shift || "LINE1";
200 my $rrdvar=shift || "";
201 my $color=shift || "000000";
202 my $description=shift || "";
203 my $legends=shift || "min avg max";
204 my $unit=shift || "";
205 my $use_SI_units=shift || 0;
206 
207 my @legends=split / /,$legends;
208 
209 my @vars=split / /,$rrdvar;
210 while ($#vars<4) { push @vars,$vars[$#vars]; }
211 
212 my $lead="";
213 my @array=();
214 if ($vars[0] ne "0") { push @array,"$graphtype:$vars[0]#$color:$description"; $description=""; }
215 else { $lead=" "; }
216 
217 $SI="";
218 if ($use_SI_units == 1) { $SI=" %s"; }
219 elsif ($use_SI_units == -1) { $SI="%s"; }
220 
221 if ($unit ne "") { $unit=" $unit"; }
222 
223 my $num=0;
224 foreach $legend (@legends) {
225 my $open="";
226 my $close="";
227 if ($num == 0) { $open="$lead$description$lead("; }
228 if ($num == $#legends) { $close="$unit)\\n"; }
229 $num++;
230 if ($legend eq "min") { push @array,"GPRINT:$vars[1]:MIN:$open"."min\\:%7.2lf$SI$close"; }
231 elsif ($legend eq "avg") { push @array,"GPRINT:$vars[2]:AVERAGE:$open"."avg\\:%7.2lf$SI$close"; }
232 elsif ($legend eq "max") { push @array,"GPRINT:$vars[3]:MAX:$open"."max\\:%7.2lf$SI$close"; }
233 elsif ($legend eq "now") { push @array,"GPRINT:$vars[4]:LAST:$open"."now\\:%7.2lf$SI$close"; }
234 elsif ($legend eq "cur") { push @array,"GPRINT:$vars[4]:LAST:$open"."now\\:%7.2lf$SI$close"; }
235 $description="";
236 $lead="";
237 }
238 
239 return @array;
240 }
241 
242######################################################################
243#
244# generates an array suitable to feed to RRDs::graph to build a min/max
245# graph including a legend with the desired consolidation functions.
246#
247# Usage:
248# insert_minmax(var,areacolor,bordercolor,description,unit,use_SI);
249#
250# var: RRD variables to be graphed and assigned to min and max.
251# They have to be separated by spaces.
252# If you just want to insert a legend without adding a
253# graph, the first element must be a numerical zero "0"
254# The "description" can be used for padding the legend.
255#
256# areacolor: graph area color in RRDs::graph notation ( #RRGGBB )
257#
258# bordercolor: border color in RRDs::graph notation ( #RRGGBB )
259#
260# description: short description that will be appended in the legend
261#
262# unit: the unit that will be appended after the last legend
263#
264# use_SI: 0 -> just print the plain value
265# 1 -> print values in SI units (micro, milli, kilo, mega, ...)
266# -1 -> same as "1", but SI-units will be added without a space
267#
268# EXAMPLE:
269#
270# insert_data("AREA","abc xyz","0000ff","test legend","min max","bytes",1);
271#
272# -> draw a blue area with the rrd variable "abc" and add a corrosponding
273# legend to it, but refer the legend to the variable "xyz". The legend
274# will use SI-units and the unit "bytes". It will look like this:
275#
276# [#] test legend (min: 1.23k max: 12.34M bytes)
277#
278sub insert_minmax {
279 my $rrdvar=shift || "";
280 my $areacolor=shift || "000000";
281 my $bordercolor=shift || "";
282 my $description=shift || "";
283 my $unit=shift || "";
284 my $use_SI_units=shift || 0;
285 
286 my @vars=split / /,$rrdvar;
287 
288 my $lead="";
289 my @array=();
290 if ($vars[0] ne "0") {
291 push @array,(
292 "CDEF:negmin$vars[0]=$vars[0],0,LT,$vars[0],0,IF",
293 "CDEF:negmax$vars[1]=$vars[1],0,LT,$vars[1],0,IF",
294 "AREA:$vars[1]#$areacolor:$description",
295 "AREA:$vars[0]#FFFFFF:",
296 "AREA:negmin$vars[0]#$areacolor:",
297 "AREA:negmax$vars[1]#FFFFFF:"
298 );
299 if ($bordercolor ne "") {
300 push @array,(
301 "LINE1:$vars[0]#$bordercolor:",
302 "LINE1:$vars[1]#$bordercolor:"
303 );
304 }
305 $description="";
306 }
307 else { $lead=" "; }
308 
309 if (! defined $vars[2]) { push @vars,$vars[0]; }
310 if (! defined $vars[3]) { push @vars,$vars[1]; }
311 
312 $SI="";
313 if ($use_SI_units == 1) { $SI=" %s"; }
314 elsif ($use_SI_units == -1) { $SI="%s"; }
315 
316 if ($unit ne "") { $unit=" $unit"; }
317 
318 push @array,(
319 "GPRINT:$vars[2]:MIN:$lead$description$lead(min\\:%7.2lf$SI",
320 "GPRINT:$vars[2]:MAX:$lead$description$lead/%7.2lf$SI",
321 "GPRINT:$vars[3]:MIN:max\\:%7.2lf$SI",
322 "GPRINT:$vars[3]:MAX:/%7.2lf$SI$unit)\\n"
323 );
324 
325 return @array;
326 }
327 
328 
329######################################################################
330#
331# generates an array suitable to feed to RRDs::graph to mark
332# areas of unknown values
333#
334# Usage:
335# insert_unknown_area($vars,$color,$description);
336#
337# vars: space separated list of all variables to be taken
338# into account. If one of them is unknown, the area
339# will be marked
340#
341# color: graph's color in RRDs::graph notation ( RRGGBB )
342#
343# description: some additional legend that will (if defined) show
344# up in brackets after the string "data unknown".
345#
346sub insert_unknown_area {
347 my $vars=shift;
348 my $color=shift || "ffffa0";
349 my $description=shift || "";
350 
351 if ($description ne "") { $description=" ($description)"; }
352 
353 # the scaring ;) definition of "wrongdata":
354 # if TIME < now { if x unknown { INF else 0 } else 0 }
355 # CDEF:wrongdata=TIME,$DATE,LT,x,UN,INF,0,IF,0,IF \
356 # where "x" is the result of the addition of all variables
357 
358 my @vars=split /\s+/,$vars;
359 my $string=shift @vars;
360 if (@vars) { $string = $string.",".join (",+,",@vars).",+"; }
361 
362 return (
363 "CDEF:wrongdata=TIME,".time.",LT,$string,UN,INF,0,IF,0,IF",
364 "AREA:wrongdata#$color:data unknown$description\\n",
365 "CDEF:wrongdatainv=0,wrongdata,-",
366 "AREA:wrongdatainv#$color:"
367 );
368 }
369 
370 
371sub insert_lines {
372 my %CONFIG=@_;
373 my @array=("HRULE:0#000000");
374 if (defined $CONFIG{GRAPH_ADDLINE}) {
375 foreach (@{$CONFIG{GRAPH_ADDLINE}}) {
376 my ($pos,$color,$comment)=split /,/;
377 if (defined $CONFIG{$color}) { $color=$CONFIG{$color}; }
378 push @array,"HRULE:$pos#$color:$comment";
379 }
380 }
381 return @array
382 }
383 
384sub insert_vars {
385 my $dbname=shift;
386 my $dbvar=shift;
387 my $graphvar=shift;
388 my $which=shift;
389 my @array=();
390 foreach my $consolidation (split /\s+/,$which) {
391 my $consname=lc $consolidation;
392 if ($consname eq "average") { $consname="avg"; }
393 push @array,"DEF:$graphvar"."_"."$consname=$dbname:$dbvar:$consolidation"
394 }
395 return @array;
396 }
397 
3981;
399 

Powered by WebSVN 2.2.1