RRDTool::OO tries to marry rrdtool's database engine with the dwimminess and whipuptitude Perl programmers take for granted. Using RRDTool::OO abstracts away implementation details of the RRD engine, uses easy to memorize named parameters and sets meaningful defaults for parameters not needed in simple cases. For the experienced user, however, it provides full access to rrdtool's API (if you find a feature that's not implemented, let me know).

The constructor hooks up with an existing RRD database file $file, but doesn't create a new one if none exists. That's what the create() methode is for. Returns a RRDTool::OO object, which can be used to get access to the following methods.

This defines a RRD database with a step rate of 60 seconds in between primary data points. Additionally, the RRD start time can be specified by specifying a start parameter.

It also sets up one data source named my_data_source of type GAUGE, telling rrdtool to use values of data samples as-is, without additional trickery.

And it creates a single archive with a 1:1 mapping between primary data points and archive points, with a capacity to hold five data points.

The RRD's step parameter is optional, and will be set to 300 seconds by rrdtool by default.

In addition to the mandatory settings for name and type, data_source parameter takes the following optional parameters: min (minimum input, defaults to U), max (maximum input, defaults to U), heartbeat (defaults to twice the RRD's step rate).

Archives expect at least one parameter, rows indicating the number of data points the archive is configured to hold. If nothing else is set, rrdtool will store primary data points 1:1 in the archive.

If you want to combine several primary data points into one archive point, specify values for cpoints (the number of points to combine) and cfunc (the consolidation function) explicitly:

This will collect 10 data points to form one archive point, using the calculated average, as indicated by the parameter cfunc (Consolidation Function, CF). Other options for cfunc are MIN, MAX, and LAST.

If you're defining multiple data sources or multiple archives, just provide them in this manner:

Update the round robin database with a new data sample, consisting of a value and an optional time stamp. If called with a single parameter, like in

$rrd->update($value);

then the current timestamp and the defined $value will be used. If update is called with a named parameter list like in

$rrd->update(time => $time, value => $value);

then the given timestamp $time is used along with the given value $value.

When updating multiple data sources, use the values parameter (instead of value) and pass an arrayref:

$rrd->update(time => $time, values => [$val1, $val2, ...]);

This way, rrdtool expects you to pass in the data values in exactly the same order as the data sources were defined in the create method. If that's not the case, then the values parameter also accepts a hashref, mapping data source names to values:

Initializes the iterator to fetch data from the RRD. This works nicely without any parameters if your archives are using a single consolidation function (e.g. MAX). If there's several archives in the RRD using different consolidation functions, you have to specify which one you want:

$rrd->fetch_start(cfunc => "MAX");

Other options for cfunc are MIN, AVERAGE, and LAST.

fetch_start features a number of optional parameters: start, end and resolution.

If the start time parameter is omitted, the fetch starts 24 hours before the end of the archive. Also, an end time can be specified:

$rrd->fetch_start(start => time()-10*60,
end => time());

The third optional parameter, resolution defaults to the highest resolution available and can be set to a value in seconds, specifying the time interval between the data samples extracted from the RRD. See the rrdtool fetch manual page for details.

Development note: The current implementation fetches all values from the RRA in one swoop and caches them in memory. This might change in the future, to cache only the last timestamp and keep fetching from the RRD with every fetch_next() call.

rrdtool doesn't remember the time the first data sample went into the archive. So if you run a rrdtool fetch with a start time of 24 hours ago and you've only submitted a couple of samples to the archive, you'll see many undef values.

Starting from the current iterator position (or at the specified start time immediately after a fetch_start()), fetch_skip_undef() will skip all undef values in the RRA and positions the iterator right before the first defined value. If all values in the RRA are undefined, the a following $rrd->fetch_next() will return undef.

As always, RRDTool::OO will pick reasonable defaults for parameters not specified. The values for data source and consolidation function default to the first values it finds in the RRD. If there are multiple datasources in the RRD or multiple archives with different values for cfunc, just specify explicitly which one to draw:

If draw doesn't define a type, it defaults to "line". If you don't want to define a type (because the graph shouldn't be drawn), use type => "hidden". Other values are "area" for solid colored areas. The "stack" type (for graphical values stacked on top of each other) has been deprecated sind rrdtool-1.2, but RRDTool::OO still supports it by transforming it into an 'area' type with a 'stack' option.

If a file parameter is specified per draw, the defaults for dsname and cfunc are fetched from this file, not from the file that's attached to the RRDTool::OO object $rrd used.

Graphs may also consist of algebraic calculations of previously defined graphs. In this case, graphs derived from real data sources need to be named, so that subsequent cdef definitions can refer to them and calculate new graphs, based on the previously defined graph:

Note that the second draw doesn't refer to a datasource dsname (nor does it fall back to the default data source), but defines a cdef, performing calculations on a previously defined draw named firstgraph. The calculation is specified using RRDTool's reverse polish notation, where instructions are separated by commas ("firstgraph,2,*" simply multiplies firstgraph's values by 2).

On a global level, in addition to the vertical_label parameter shown in the examples above, graph offers a plethora of parameters:

Some options (e.g. alt_y_grid) don't expect values, they need to be specified like

alt_y_grid => undef

in order to be passed properly to RRDTool.

The color option expects a reference to a hash with various settings for the different graph areas: back (background), canvas, shadea (left/top border), shadeb (right/bottom border), grid, mgrid major grid, font, frame and arrow:

Fonts for various graph elements may be specified in font blocks, which must either name a TrueType font file or a PDF/Postscript font name. You may optionally specify a size and element name (defaults to DEFAULT, which to RRD means "use this font for everything). Example:

Sometimes it's useful to print max, min or average values of a given graph at the bottom of the chart or to STDOUT. That's what gprint and print options are for. They are printing variables which are defined as vdefs somewhere else:

This is identical to graph, but uses rrdtool's graphv function internally. The only difference is when using the print_results method described below, which then contains additional information. Be aware that rrdtool 1.3 is required for graphv to work.

Restore a RRD from a dump. The xml parameter specifies the name of the XML file containing the dump. If the optional flag range_check is set to a true value, restore will make sure the values in the RRAs do not exceed the limits defined for the different datasources:

# Set the heartbeat of the RRD's only datasource to 100
$rrd->tune(heartbeat => 100);
# Set the minimum of DS 'load' to 1
$rrd->tune(dsname => 'load', minimum => 1);
# Set the maximum of DS 'load' to 10
$rrd->tune(dsname => 'load', maximum => 10);
# Set the type of DS 'load' to AVERAGE
$rrd->tune(dsname => 'load', type => 'AVERAGE');
# Set the name of DS 'load' to 'load2'
$rrd->tune(dsname => 'load', name => 'load2');

RRDTool supports aberrant behavior detection (ABD), which takes a data source, stuffs its values into a special RRA, smoothes the data stream, tries to predict future values and triggers an alert if actual values are way off the predicted values.

Using a fairly elaborate algorithm not only allows it to find out if a data source produces a value that exceeds a certain fixed threshold. The algorithm constantly adapts its parameters to the input data and acts dynamically on slowly changing values.

The alpha parameter specifies the baseline and lies between 0 and 1. Values close to 1 specify that most recent values have the most weight on the prediction, whereas values close to 0 indicate that past values carry higher weight.

On top of that, ABD can deal with data input that displays continuously rising values (slope). The beta parameters, again between 0 and 1, specifies whether past values or more recent values carry the most weight.

And, furthermore, it deals with seasonal cycles, so it won't freak out if there's a daily peak at noon. The gamma parameter indicates this, if you don't specify it, it defaults to the value of alpha.

In the easiest case, an RRA with aberrant behavior detection can be created like

where alpha and beta default to 0.5, and the seasonal_period defaults to 1/5 of the rows number.

rows is the number of primary data points that are stored in the RRA before a wrap-around happens. Note that with ABD enabled, RRDTool won't consolidate the data from a data source before stuffing it into the HWPREDICT RRAs, as the whole point of ABD is to smooth unfiltered data and predict future values.

A violation happens if a new measured value falls outside of the prediction. If threshold or more violations happen within window_length, an error is reported to the FAILURES RRA. threshold defaults to 7, window_length to 9.

If you want to peek under the hood (not that you need to, just for your entertainment), with the specification above, RRDTool::OO will create the following five RRAs according to the RRDtool specification and fill in these values:

The rra-num argument is an internal index referencing other RRAs (for example, HWPREDICT references SEASONAL), but this will be taken care of automatically by RRDTool::OO with no user interaction required whatsoever.

captures the print data internally. To get access to a reference to the array containing the different pieces of data written in this way, call

my $array_ref = $rrd->print_results();

If no print output is available, the array referenced by $array_ref is empty.

If the graphv function is used instead of graph, the return value of print_results is a hashref containing the same information in the print keys, along with additional keys containing detailed information on the graph. See rrdtool documentation for more detail. Here is an example:

In this case, the option (image => "-") has been used to create the hash key with the same name, the value of which actually contains the BLOB of the image itself. This is useful when image needs to be passed to other modules (e.g. Image::Magick), instead of writing it to disk. Be aware that rrdtool 1.3 is required for graphv to work.

RRDTool::OO tracks rrdtool's progress loosely, so it might happen that at a given point in time, rrdtool introduces a new option that RRDTool::OO doesn't know about yet.

This might lead to problems, since default, RRDTool::OO has its strict mode enabled, rejecting all unknown options. This mode is usually helpful, because it catches typos (like "verical_label"), but if you want to use a new rrdtool option, it's in the way.

To work around this problem until a new version of RRDTool::OO supports the new parameter, you can use

$rrd->option_add("graph", "frobnication_level");

to add it to the optional parameter list of the graph (or whatever) rrd function. Note that some functions in RRDTool::OO have sub-methods, which you can specify with the dash notation. The graph method with its various "graph/draw", "graph/color", "graph/font" are notable examples.

And, as a band-aid, you can disable strict mode in these situation by setting the strict parameter to 0 in RRDTool::OO's constructor call:

my $rrd = RRDTool::OO->new(
strict => 0,
file => "myrrdfile.rrd",
);

Note that RRDTool::OO follows the convention that parameters names do not contain dashes, but underscores instead. So, you need to say "vertical_label", not "vertical-label". The underlying rrdtool layer, however, expects dashes, not underscores, which is why RRDTool::OO converts them automatically, e.g. transforming "vertical_label" to "--vertical-label" before the underlying rrdtool call happens.

but since dry_mode is on, they won't be handed through to the rrdtool layer anymore. Instead, RRDTool::OO allows you to retrieve a reference to the RRDs function it was about to call including its arguments:

my ($subref, $args) = $rrd->get_exec_env();

You can now examine or modify the subroutine reference $subref or the arguments in the array reference $args. Later, simply call

$subref->(@$args);

to execute the RRDs function with the modified argument list later. In this case, @$args would contain the following items:

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.3 or, at your option, any later version of Perl 5 you may have available.