index c644766e63d16cc5c17b82b548440ae7d3893f52..bf2abe8c438473ffbd809d635d2512c6f885269c 100644 (file)
=head1 NAME
-RRDp - Attach rrdtool from within a perl script via a set of pipes;
+RRDp - Attach RRDtool from within a perl script via a set of pipes;
=head1 SYNOPSIS
use B<RRDp>
-B<RRDp::start> I<path to rrdtool executable>
+B<RRDp::start> I<path to RRDtool executable>
B<RRDp::cmd> I<rrdtool commandline>
$status = B<RRD::end>
-B<$RRDp::user>, B<$RRDp::sys>, B<$RRDp::real>
+B<$RRDp::user>, B<$RRDp::sys>, B<$RRDp::real>, B<$RRDp::error_mode>, B<$RRDp::error>
=head1 DESCRIPTION
-With this module you can safely communicate with the rrdtool.
+With this module you can safely communicate with the RRDtool.
After every B<RRDp::cmd> you have to issue an B<RRDp::read> command to get
-B<rrdtool>s answer to your command. The answer is returned as a pointer,
+B<RRDtool>s answer to your command. The answer is returned as a pointer,
in order to speed things up. If the last command did not return any
data, B<RRDp::read> will return an undefined variable.
If you import the PERFORMANCE variables into your namespace,
-you can access rrdtools internal performance measurements.
+you can access RRDtool's internal performance measurements.
=over 8
Load the RRDp::pipe module.
-=item B<RRDp::start> I<path to rrdtool executable>
+=item B<RRDp::start> I<path to RRDtool executable>
-start rrdtool. The argument must be the path to the rrdtool executable
+start RRDtool. The argument must be the path to the RRDtool executable
=item B<RRDp::cmd> I<rrdtool commandline>
-pass commands on to rrdtool. check the rrdtool documentation for
-more info on the rrdtool commands.
+pass commands on to RRDtool. Check the RRDtool documentation for
+more info on the RRDtool commands.
+
+B<Note>: Due to design limitations, B<RRDp::cmd> does not support the
+C<graph -> command - use C<graphv -> instead.
=item $answer = B<RRDp::read>
-read rrdtools response to your command. Note that the $answer variable will
+read RRDtool's response to your command. Note that the $answer variable will
only contain a pointer to the returned data. The reason for this is, that
-rrdtool can potentially return quite excessive amounts of data
+RRDtool can potentially return quite excessive amounts of data
and we don't want to copy this around in memory. So when you want to
access the contents of $answer you have to use $$answer which dereferences
the variable.
=item $status = B<RRDp::end>
-terminates rrdtool and returns rrdtools status ...
+terminates RRDtool and returns RRDtool's status ...
=item B<$RRDp::user>, B<$RRDp::sys>, B<$RRDp::real>
these variables will contain totals of the user time, system time and
-real time as seen by rrdtool. User time is the time rrdtool is
+real time as seen by RRDtool. User time is the time RRDtool is
running, System time is the time spend in system calls and real time
-is the total time rrdtool has been running.
+is the total time RRDtool has been running.
The difference between user + system and real is the time spent
-waiting for things like the hard disk and new input from the perl
+waiting for things like the hard disk and new input from the Perl
script.
+=item B<$RRDp::error_mode> and B<$RRDp::error>
+
+If you set the variable $RRDp::error_mode to the value 'catch' before you run RRDp::read a potential
+ERROR message will not cause the program to abort but will be returned in this variable. If no error
+occurs the variable will be empty.
+
+ $RRDp::error_mode = 'catch';
+ RRDp::cmd qw(info file.rrd);
+ print $RRDp::error if $RRDp::error;
+
=back
=head1 SEE ALSO
-For more information on how to use rrdtool, check the manpages.
+For more information on how to use RRDtool, check the manpages.
=head1 AUTHOR
-Tobias Oetiker <oetiker@ee.ethz.ch>
+Tobias Oetiker <tobi@oetiker.ch>
=cut
+
#' this is to make cperl.el happy
use strict;
sub end ();
sub read ();
-$VERSION = 1.000331 ;
+$VERSION=1.4003;
sub start ($){
croak "rrdtool is already running"
sub read () {
croak "RRDp::read can only be called after RRDp::cmd"
unless $Sequence eq 'C';
+ $RRDp::error = undef;
$Sequence = 'R';
my $inmask = 0;
my $srbuf;
my $buffer;
my $nfound;
my $timeleft;
- my $ERR = 0;
vec($inmask,fileno(RRDreadHand),1) = 1; # setup select mask for Reader
while (1) {
my $rout;
$minibuf .= $srbuf;
while ($minibuf =~ s|^(.+?)\n||s) {
my $line = $1;
- # print $line,"\n";
- if ($line =~ m|^ERROR|) {
- croak $line;
- $ERR = 1;
+ # print $line,"\n";
+ $RRDp::error = undef;
+ if ($line =~ m|^ERROR|) {
+ $RRDp::error_mode eq 'catch' ? $RRDp::error = $line : croak $line;
+ $RRDp::sys = undef;
+ $RRDp::user = undef;
+ $RRDp::real = undef;
+ return undef;
}
- elsif ($line =~ m|^OK u:([\d\.]+) s:([\d\.]+) r:([\d\.]+)|){
+ elsif ($line =~ m|^OK(?: u:([\d\.]+) s:([\d\.]+) r:([\d\.]+))?|){
($RRDp::sys,$RRDp::user,$RRDp::real)=($1,$2,$3);
- return $ERR == 1 ? undef : \$buffer;
+ return \$buffer;
} else {
$buffer .= $line. "\n";
}
}
$cmd =~ s/\n/ /gs;
$cmd =~ s/\s/ /gs;
+
+ # The generated graphs aren't necessarily terminated by a newline,
+ # causing RRDp::read() to wait for a line matching '^OK' forever.
+ if ($cmd =~ m/^\s*graph\s+-\s+/) {
+ croak "RRDp does not support the 'graph -' command - "
+ . "use 'graphv -' instead";
+ }
print RRDwriteHand "$cmd\n";
}