1 #! /usr/sepp/bin/perl
2 #
3 # rrdlastds - report the latest DS values from the RRA with
4 # the shortest time resolution
5 #
6 # steve rader
7 # <rader@wiscnet.net>
8 # Jan 8th, 2000
9 #
10 # $Id$
11 #
13 #makes things work when run without install
14 use lib qw( ../../perl-shared/blib/lib ../../perl-shared/blib/arch );
15 # this is for after install
16 use lib qw( /usr/local/rrdtool-1.0.30/lib/perl ../lib/perl );
18 use RRDs;
20 %scale_symbols = qw( -18 a -15 f -12 p -9 n -6 u -3 m
21 3 k 6 M 9 G 12 T 15 P 18 E );
23 #----------------------------------------
25 while ( $ARGV[0] =~ /^-/ ) {
26 switch: {
27 if ( $ARGV[0] eq '--autoscale' || $ARGV[0] =~ /^-a/ ) {
28 $scale = 1;
29 last switch;
30 }
31 if ( $ARGV[0] eq '--conversion' || $ARGV[0] =~ /^-c/ ) {
32 shift @ARGV;
33 $conversion = $ARGV[0];
34 if ( $conversion !~ /^\d+$|^\d+\.\d+$|^\.\d+$/ ) {
35 print "rrdlastds: bad conversion factor \"$conversion\"\n";
36 exit 1;
37 }
38 last switch;
39 }
40 if ( $ARGV[0] eq '--label' || $ARGV[0] =~ /^-l/ ) {
41 shift @ARGV;
42 $label = $ARGV[0];
43 last switch;
44 }
45 if ( $ARGV[0] eq '--start' || $ARGV[0] =~ /^-s/ ) {
46 shift @ARGV;
47 $start = $ARGV[0];
48 if ( $start =~ /^\d+$/ ) {
49 $end = $start+1;
50 } else {
51 $end = "${start}+1sec";
52 }
53 last switch;
54 }
55 if ( $ARGV[0] eq '--verbose' || $ARGV[0] =~ /^-v/ ) {
56 $verbose = 1;
57 last switch;
58 }
59 if ( $ARGV[0] eq '--debug' || $ARGV[0] =~ /^-d/ ) {
60 $debug = 1;
61 last switch;
62 }
63 print "rrdlastds: unknown option \"$ARGV[0]\"\n";
64 exit 1;
65 }
66 shift @ARGV;
67 }
69 if ( $#ARGV != 0 ) {
70 print <<_EOT_;
71 usage: rrdlastds [-v] [-a] [-c num] [-l label] [-s stamp] some.rrd
72 -v print the start and end times (also --verbose)
73 -a autoscale DS values (also --autoscale)
74 -c num convert DS values by "num" (also --conversion)
75 -l label label DS values with "label" (also --label)
76 -s time report about DS values at the time "time" (also --start)
78 The -s option supports the traditional "seconds since the Unix epoch"
79 and the AT-STYLE time specification (see man rrdfetch)
80 _EOT_
81 exit 1;
82 }
84 if ( ! -f "$ARGV[0]" ) {
85 print "rrdlastds: can't find \"$ARGV[0]\"\n";
86 exit 1;
87 }
89 #----------------------------------------
91 if ( $start ) {
92 @fetch = ("$ARGV[0]", "-s", "$start", "-e", "$end", "AVERAGE");
93 } else {
94 @fetch = ("$ARGV[0]", "-s", "-1sec", "AVERAGE");
95 }
96 if ( $debug ) {
97 print "rrdfetch ", join(' ',@fetch), "\n";
98 }
100 ($start,$step,$names,$data) = RRDs::fetch @fetch;
102 if ( $error = RRDs::error ) {
103 print "rrdlastds: rrdtool fetch failed: \"$error\"\n";
104 exit 1;
105 }
107 #----------------------------------------
109 if ( $debug ) {
110 $d_start = $start;
111 print "Start: ", scalar localtime($d_start), " ($d_start)\n";
112 print "Step size: $step seconds\n";
113 print "DS names: ", join (", ", @$names)."\n";
114 print "Data points: ", $#$data + 1, "\n";
115 print "Data:\n";
116 foreach $line (@$data) {
117 print " ", scalar localtime($d_start), " ($d_start) ";
118 $d_start += $step;
119 foreach $val (@$line) {
120 printf "%12.1f ", $val;
121 }
122 print "\n";
123 }
124 print "\n";
125 }
127 #----------------------------------------
129 if ( $verbose ) {
130 print scalar localtime($start), ' through ',
131 scalar localtime($start+$step), "\naverage";
132 } else {
133 print scalar localtime($start);
134 }
136 $line = $$data[0];
137 for $i (0 .. $#$names) {
138 if ( $conversion ) {
139 $$line[$i] = $$line[$i] * $conversion;
140 }
141 if ( $scale ) {
142 ($val, $units) = autoscale($$line[$i]);
143 } else {
144 $val = $$line[$i];
145 }
146 printf " %.2f$units$label %s", $val, $$names[$i];
147 }
148 print "\n";
150 exit 0;
152 #==================================================================
154 sub autoscale {
155 local($value) = @_;
156 local($floor, $mag, $index, $symbol, $new_value);
158 if ( $value =~ /^\s*[0]+\s*$/ ||
159 $value =~ /^\s*[0]+.[0]+\s*$/ ||
160 $value =~ /^\s*NaN\s*$/ ) {
161 return $value, ' ';
162 }
164 $floor = &floor($value);
165 $mag = int($floor/3);
166 $index = $mag * 3;
167 $symbol = $scale_symbols{$index};
168 $new_value = $value / (10 ** $index);
169 return $new_value, " $symbol";
170 }
172 #------------------------------------------------------------------
174 sub floor {
175 local($value) = @_;
176 local($i) = 0;
178 if ( $value > 1.0 ) {
179 # scale downward...
180 while ( $value > 10.0 ) {
181 $i++;
182 $value /= 10.0;
183 }
184 } else {
185 while ( $value < 10.0 ) {
186 $i--;
187 $value *= 10.0;
188 }
189 }
190 return $i;
191 }