NAME
RRD::Editor - Portable, standalone (no need for RRDs.pm) tool to create and edit RRD files.
SYNOPSIS
use strict;
use RRD::Editor ();
# Create a new object
my $rrd = RRD::Editor->new();
# Create a new RRD with 3 data sources called bytesIn, bytesOut and
# faultsPerSec and one RRA which stores 1 day worth of data at 5 minute
# intervals (288 data points). The argument format is the same as that used
# by 'rrdtool create', see L<http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html>
$rrd->create("DS:bytesIn:GAUGE:600:U:U DS:bytesOut:GAUGE:600:U:U DS:faultsPerSec:COUNTER:600:U:U RRA:AVERAGE:0.5:1:288")
# Save RRD to a file
$rrd->save("myfile.rrd");
# The file format to use can also be optionally specified:
# $rrd->save("myfile.rrd","native-double"); # default; non-portable format used by RRDTOOL
# $rrd->save("myfile.rrd","portable-double"); # portable, data stored in double-precision
# $rrd->save("myfile.rrd","portable-single"); # portable, data stored in single-precision
# Load RRD from a file. Automagically figures out the file format
# (native-double, portable-double etc)
$rrd->open("myfile.rrd");
# Add new data to the RRD for the same 3 data sources bytesIn,
# bytesOut and faultsPerSec. The argument format is the same as that used by
# 'rrdtool update', see L<http://oss.oetiker.ch/rrdtool/doc/rrdupdate.en.html>
$rrd->update("N:10039:389:0.4");
# Show information about an RRD. Output generated is similar to
# 'rrdtool info'.
print $rrd->info();
# XML dump of RRD contents. Output generated is similar to 'rrdtool dump'.
print $rrd->dump();
# Extract data measurements stored in RRAs of type AVERAGE
# The argument format is the same as that used by 'rrdtool fetch' and
# the output generated is also similar, see
# L<http://oss.oetiker.ch/rrdtool/doc/rrdfetch.en.html>
print $rrd->fetch("AVERAGE");
# Get the time when the RRD was last updated (as a unix timestamp)
printf "RRD last updated at %d\n", $rrd->last();
# Get the measurements added when the RRD was last updated
print $rrd->lastupdate();
# Get the min step size (or resolution) of the RRD. This defaults to 300s unless specified
otherwise when creating an RRD.
print $rrd->minstep()
Edit Data Sources
# Add a new data-source called bytes. Argument format is the same as $rrd->create().
$rrd->add_DS("DS:bytes:GAUGE:600:U:U");
# Delete the data-source bytesIn
$rrd->delete_DS("bytesIn");
# Get a list of the data-sources names
print $rrd->DS_names();
# Change the name of data-source bytes to be bytes_new
$rrd->rename_DS("bytes", "bytes_new")
# Get the heartbeat value for data-source bytesOut (the max number of seconds that
# may elapse between data measurements)
printf "Heartbeat for DS bytesOut = %d\n", $rrd->DS_heartbeat("bytesOut");
# Set the heartbeat value for data-source bytesOut to be 1200 secs
$rrd->set_DS_heartbeat("bytesOut",1200);
# Get the type (COUNTER, GAUGE etc) of data-source bytesOut
printf "Type of DS bytesOut = %s\n", $rrd->DS_type("bytesOut");
# Set the type of data-source bytesOut to be COUNTER
$rrd->set_DS_type("bytesOut", "COUNTER");
# Get the minimum value allowed for measurements from data-source bytesOut
printf "Min value of DS bytesOut = %s\n", $rrd->DS_min("bytesOut");
# Set the minimum value allowed for measurements from data-source bytesOut to be 0
$rrd->set_DS_min("bytesOut",0);
# Get the maximum value allowed for measurements from data-source bytesOut
printf "Max value of DS bytesOut = %s\n", $rrd->DS_max("bytesOut");
# Set the maximum value allowed for measurements from data-source bytesOut to be 100
$rrd->set_DS_max("bytesOut",100);
Edit RRAs
# Add a new RRA which stores 1 weeks worth of data (336 data points) at 30 minute
# intervals (30 mins = 6 x 5 mins)
$rrd->add_RRA("RRA:AVERAGE:0.5:6:336");
# RRAs are identified by an index in range 0 .. $rrd->num_RRAs(). The index
# of an RRD can also be found using $rrd->info() or $rrd->dump()
my $rra_idx=1;
# Delete an existing RRA with index $rra_idx.
$rrd->delete_RRA($rra_idx);
# Get the number of rows/data points stored in the RRA with index $rra_idx
$rra_idx=0;
printf "number of rows of RRA %d = %d\n", $rra_idx, $rrd->RRA_numrows($rra_idx);
# Change the number of rows/data points stored in the RRA with index
# $rra_idx to be 600.
$rra->resize_RRA($rra_idx, 600);
# Get the value of bytesIn stored at the 10th row/data-point in the
# RRA with index $rra_idx.
printf "Value of data-source bytesIn at row 10 in RRA %d = %d", $rra_idx, $rra->RRA_el($rra_idx, "bytesIn", 10);
# Set the value of bytesIn at the 10th row/data-point to be 100
$rra->set_RRA_el($rra_idx, "bytesIn", 10, 100);
# Get the xff value for the RRA with index $rra_idx
printf "Xff value of RRA %d = %d\n", $rra_idx, $rra->RRA_xff($rra_idx);
# Set the xff value to 0.75 for the RRA with index $rra_idx
$rra->RRA_xff($rra_idx,0.75);
# Get the type (AVERAGE, LAST etc) of the RRA with index $rra_idx
print $rrd->RRA_type($rra_idx);
# Get the step (in seconds) of the RRA with index $rra_idx
print $rrd->RRA_step($rra_idx);
DESCRIPTION
RRD:Editor implements most of the functionality of RRDTOOL, apart from graphing, plus adds some new editing and portability features. It aims to be portable and self-contained (no need for RRDs.pm).
RRD::Editor provides the ability to add/delete DSs and RRAs and to get/set most of the parameters in DSs and RRAs (renaming, resizing etc). It also allows the data values stored in each RRA to be inspected and changed individually. That is, it provides almost complete control over the contents of an RRD.
The RRD files created by RRDTOOL use a binary format (let's call it native-double
) that is not portable across platforms. In addition to this file format, RRD:Editor provides two new portable file formats (portable-double
and portable-single
) that allow the exchange of files. RRD::Editor can freely convert RRD files between these three formats (native-double
,portable-double
and portable-single
).
Notes:
times must all be specified as unix timestamps (i.e. -1d, -1w etc don't work, and there is no @ option in rrdupdate).
there is full support for COUNTER, GAUGE, DERIVE and ABSOLUTE data-source types but the COMPUTE type is only partially supported.
there is full support for AVERAGE, MIN, MAX, LAST RRA types but the HWPREDICT, MHWPREDICT, SEASONAL etc types are only partially supported).
METHODS
new
my $rrd=new RRD:Editor->new();
Creates a new RRD::Editor object
create
$rrd->create($args);
The method will create a new RRD with the data-sources and RRAs specified by $args
. $args
is a string that contains the same sort of command line arguments that would be passed to rrdtool create
. The format for $args
is:
[--start|-b start time] [--step|-s step] [--format|-f encoding] [DS:ds-name:DST:heartbeat:min:max] [RRA:CF:xff:steps:rows]
where DST may be one of GAUGE, COUNTER, DERIVE, ABSOLUTE and CF may be one of AVERAGE, MIN, MAX, LAST. Possible values for encoding are native-double
, portable-double
, portable-single
. If omitted, defaults to native-double
(the non-portable file format used by RRDTOOL). See http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html for further information.
open
$rrd->open($file_name);
Load the RRD in the file called $file_name
. Only the file header is loaded initially, to improve efficiency, with the body of the file subsequently loaded if needed. The file format (native-double
, portable-double
etc) is detected automagically.
save
$rrd->save();
$rrd->save($file_name);
$rrd->save($file_name, $encoding);
Save RRD to a file called $file_name with format specified by $encoding
. Possible values for $encoding
are "native-double"
, "portable-double"
, "portable-single"
.
If omitted, $encoding
defaults to the format of the file specified when calling open()
, or to "native-double"
if the RRD has just been created using create()
. native-double
is the non-portable binary format used by RRDTOOL. portable-double
is portable across platforms and stores data as double-precision values. portable-single
is portable across platforms and stores data as single-precision values (reducing the RRD file size by approximately half). If interested in the gory details, portable-double
is just the native-double
format used by Intel 32-bit platforms (i.e. little-endian byte ordering, 32 bit integers, 64 bit IEEE 754 doubles, storage aligned to 32 bit boundaries) - an arbitrary choice, but not unreasonable since Intel platforms are probably the most widespread at the moment, and it is also compatible with web tools such as javascriptRRD http://javascriptrrd.sourceforge.net/.
If the RRD was opened using open()
, then $file_name
is optional and if omitted save()
will save the RRD to the same file as it was read from.
close
$rrd->close();
Close an RRD file accessed using open()
or save()
. Calling close()
flushes any cached data to disk.
info
my $info = $rrd->info();
Returns a string containing information on the DSs and RRAs in the RRD (but not showing the data values stored in the RRAs). Also shows details of the file format (native-double
, portable-double
etc) if the RRD was read from a file.
dump
my $dump = $rrd->dump();
my $dump = $rrd->dump($arg);
Returns a string containing the complete contents of the RRD (including data) in XML format. $arg
is optional. Possible values are "--no-header" or "-n", which remove the XML header from the output string.
fetch
my $vals = $rrd->fetch($args);
Returns a string containing a table of measurement data from the RRD. $args
is a string that contains the same sort of command line arguments that would be passed to rrdtool fetch
. The format for $args
is:
CF [--resolution|-r resolution] [--start|-s start] [--end|-e end]
where CF
may be one of AVERAGE, MIN, MAX, LAST. See http://oss.oetiker.ch/rrdtool/doc/rrdfetch.en.html for further details.
update
$rrd->update($args);
Feeds new data values into the RRD. $args
is a string that contains the same sort of command line arguments that would be passed to rrdtool update
. The format for $args
is:
[--template:-t ds-name[:ds-name]...] N|timestamp:value[:value...] [timestamp:value[:value...] ...]
See http://oss.oetiker.ch/rrdtool/doc/rrdupdate.en.html for further details.
Since update()
is often called repeatedly, in-place updating of RRD files is used where possible for greater efficiency . To understand this, a little knowledge of the RRD file format is needed. RRD files consist of a small header containing details of the DSs and RRAs, and a large body containing the data values stored in the RRAs. Reading the body into memory is relatively costly since it is much larger than the header, and so is only done by RRD::Editor on an "as-needed" basis. So long as the body has not yet been read into memory when update()
is called, update()
will update the file on disk i.e. without reading in the body. In this case there is no need to call save()
. If the body has been loaded into memory when update()
is called, then the copy of the data stored in memory will be updated and the file on disk left untouched - a call to save()
is then needed to freshen the file stored on disk. Seems complicated, but its actually ok in practice. If all you want to do is efficiently update a file, just use the following formula:
$rrd->open($file_name);
$rrd->update($args);
$rrd->close();
and that's it. If you want to do more, then be sure to call save()
when you're done.
last
my $unixtime = $rrd->last();
Returns the time when the data stored in the RRD was last updated. The time is returned as a unix timestamp. This value should not be confused with the last modified time of the RRD file.
set_last
$rrd->set_last($unixtime);
Set the last update time to equal $unixtime
. WARNING: Rarely needed, use with caution !
lastupdate
my @vals=$rrd->lastupdate();
Return a list containing the data-source values inserted at the most recent update to the RRD
minstep
my $minstep = $rrd->minstep();
Returns the minimum step size (in seconds) used to store data values in the RRD. RRA data intervals must be integer multiples of this step size. The min step size defaults to 300s when creating an RRD (where it is referred to as the "resolution"). NB: Changing the min step size is hard as it would require resampling all of the stored data, so we leave this "to do".
add_DS
$rrd->add_DS($arg);
Add a new data-source to the RRD. Only one data-source can be added at a time. Details of the data-source to be added are specified by the string $arg
. The format of $arg
is:
[DS:ds-name:DST:heartbeat:min:max]
where DST may be one of GAUGE, COUNTER, DERIVE, ABSOLUTE i.e. the same format as used for create()
.
delete_DS
$rrd->delete_DS($ds-name);
Delete the data-source with name $ds-name
from the RRD. WARNING: This will irreversibly delete all of the data stored for the data-source.
DS_names
my @ds-names = $rrd->DS_names();
Returns a list containing the names of the data-sources in the RRD.
rename_DS
$rrd->rename_DS($ds-name, $ds-newname);
Change the name of data-source $ds-name
to be $ds-newname
DS_heartbeat
my $hb= $rrd->DS_heartbeat($ds-name);
Returns the current heartbeat (in seconds) of a data-source. The heartbeat is the max number of seconds that may elapse between data measurements before declaring that data is missing.
set_DS_heartbeat
$rrd->set_DS_heartbeat($ds-name,$hb);
Sets the heartbeat value (in seconds) of data-source $ds-name
to be $hb
.
DS_type
my $type = $rrd->DS_type($ds-name);
Returns the type (GAUGE, COUNTER etc) of a data-source.
set_DS_type
$rrd->set_DS_type($ds-name, $type);
Sets the type of data-source $ds-name
to be $type
.
DS_min
my $min = $rrd->DS_min($ds-name);
Returns the minimum allowed for measurements from data-source $ds-name
. Measurements below this value are set equal to $mi
n when stored in the RRD.
set_DS_min
$rrd->set_DS_min($ds-name, $min);
Set the minimum value for data-source $ds-name
to be $min
.
DS_max
my $max = $rrd->DS_max($ds-name);
Returns the maximum allowed for measurements from data-source $ds-name
. Measurements above this value are set equal to $max
when stored in the RRD.
set_DS_max
$rrd->set_DS_max($ds-name, $max);
Set the maximum value for data-source $ds-name
to be $max
.
add_RRA
$rrd->add_RRA($arg);
Add a new RRA to the RRD. Only one RRA can be added at a time. Details of the RRA to be added are specified by the string $arg
. The format of $arg
is:
[RRA:CF:xff:steps:rows]
where CF may be one of AVERAGE, MIN, MAX, LAST i.e. the same format as used for create()
.
num_RRAs
my $num_RRAs = $rrd->num_RRAs();
Returns the number of RRAs stored in the RRD. Unfortunately, unlike data-sources, RRAs are not named and so are only identified by an index in the range 0 .. num_RRAs()-1
. The index of a specific RRD can be found using info()
or dump()
.
delete_RRA
$rrd->delete_RRA($rra_idx);
Delete the RRA with index $rra_idx
(see above discussion for how to determine the index of an RRA). WARNING: This will irreversibly delete all of the data stored in the RRA.
RRA_numrows
my $numrows = $rrd->RRA_numrows($rra_idx);
Returns the number of rows in the RRA with index $rra_idx
.
resize_RRA
$rra->resize_RRA($rra_idx, $numrows);
Change the number of rows to be $numrows
in the RRA with index $rra_idx
. WARNING: If $numrows
is smaller than the current row size, excess data points will be discarded.
RRA_el
my ($t,$val) = $rra->RRA_el($rra_idx, $ds-name, $row);
Returns the timestamp and the value of data-source $ds-name
stored at row $row
in the RRA with index $rra_idx
. $row
must be in the range [0 .. RRA_numrows($rra_idx)-1
]. Row 0 corresponds to the oldest data point stored and row RRA_numrows($rra_idx)-1
to the most recent data point.
set_RRA_el
$rra->set_RRA_el($rra_idx, $ds-name, $row, $val);
Set the stored value equal to $val
for data-source $ds-nam
e stored at row $row
in the RRA with index $rra_idx
.
RRA_xff
my $xff = $rra->RRA_xff($rra_idx);
Returns the xff value for the RRA with index $rra_idx
. The xff value defines the proportion of an RRA data interval that may contain UNKNOWN data (i.e. missing data) and still be treated as known. For example, an xff value 0.5 in an RRA with data interval 300 seconds (5 minutes) means that if less than 150s of valid data is available since the last measurement, UNKNOWN will be stored in the RRA for the next data point.
set_RRA_xff
$rra->RRA_xff($rra_idx,$xff);
Sets the xff value to $xff
for the RRA with index $rra_idx
.
RRA_step
my $step = $rrd->RRA_step($rra_idx);
Returns the data interval (in seconds) of the RRA with index $rra_idx
. NB: Changing the step size is hard as it would require resampling the data stored in the RRA, so we leave this "to do".
RRA_type
my $type = $rrd->RRA_type($rra_idx);
Returns the type of the RRA with index $rra_idx
i.e. AVERAGE, MAX, MIN, LAST etc. NB: Changing the type of an RRA is hard (impossible ?) as the stored data doesn't contain enough information to allow its type to be changed. To change type, its recommended instead to delete the RRA and add a new RRA with the desired type.
EXPORTS
You can export the following functions if you do not want to use the object orientated interface:
create
open
save
close
update
info
dump
fetch
last
set_last
lastupdate
minstep
add_RRA
delete_RRA
num_RRAs
RRA_numrows
resize_RRA
RRA_type
RRA_step
RRA_xff
set_RRA_xff
add_DS
delete_DS
DS_names
rename_DS
DS_heartbeat
set_DS_heartbeat
DS_min
set_DS_min
DS_max
set_DS_max
DS_type
set_DS_type
The tag all
is available to easily export everything:
use RRD::Editor qw(:all);
Portability/Compatibility with RRDTOOL
The RRD::Editor code is portable, and so long as you stick to using the portable-double
and portable-single
file formats the RRD files generated will also be portable. Portability issues arise when the native-double
file format of RRD::Editor is used to store RRDs. This format tries to be compatible with the non-portable binary format used by RRDTOOL, which requires RRD::Editor to figure out nasty low-level details of the platform it is running on (byte ordering, byte alignment, representation used for doubles etc). To date, RRD::Editor and RRDTOOL have been confirmed compatible (i.e. they can read each others RRD files in native-double
format) on the following architectures:
Intel 386 32bit, Intel 686 32bit, AMD64/Intel x86 64bit, Itanium 64bit, Alpha 64bit, MIPS 32bit, MIPSel 32 bit, MIPS 64bit, PowerPC 32bit, ARMv6 (e.g. Raspberry Pi), SPARC 32bit, SPARC 64bit, SH4
Known issues:
On ARMv5 platforms RRD::Editor and RRDTOOL file formats may be only partially compatible (RRD::Editor can read RRDTOOL files, but sometimes not vice-versa depending on ARM config)
For more information on RRD::Editor portability testing, see http://www.leith.ie/rrdeditor/. If your platform is not listed, there is a good chance things will "just work" but double checking that RRDTOOL can read the native-double
format RRD files generated by RRD::Editor, and vice-versa, would be a good idea if that's important to you.
SEE ALSO
rrdtool.pl command line interface for RRD::Editor, RRD::Simple, RRDTool::OO, http://www.rrdtool.org
VERSION
Ver 0.19
AUTHOR
Doug Leith
BUGS
Please report any bugs or feature requests to bug-rrd-db at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=RRD-Editor. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
COPYRIGHT
Copyright 2014 D.J.Leith.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.