Tue 18 Jul 2006
On a number of occasions I've used RRDTool to graph network traffic and the like. A few years ago when I started using cacti I started wondering how to make the graphs myself. Creating the graphs on the command line isn't that hard once you know how to set things up and it turns out doing the same in PHP is just as easy.
For this tutorial I'm going to assume you understand how to get RRDTool installed and working from the command line. If not you should take a look at this tutorial (if you are in a hurry look at the "A Real World Example" section) or any of the tutorials on this page.
Setup and introduction
You need to have PHP compiled with RRDTool support to run the following PHP examples. If you compile PHP by hand then see: how to build the php rrdtool extension by hand. If you are using a distribution's pre-compiled PHP binary you should be able to install a second package with RRDTool support. You can verify that your PHP install is ready to go by running this:
Then search for "rrdtool" in the output and make sure that "rrdtool support" is enabled.
While going through each of the following steps you will notice that each call takes a couple of parameters and then one parameter that is just a string of options. The string of options is exactly how it is for generating/updating/graphing RRDs from the command line. This makes for a consistent interface for the different languages that have RRDTool support.
Creating a RRD
We first need to create a database for our data. For these examples I will be creating a database that could be used for generating network graphs. This database is created for updates every 5 minutes (300 seconds), has input and output counters that store data for the average and max counts and stores enough samples for hourly, daily, monthly and yearly graphs of both average and max.
$fname = "net.rrd";
$opts = array( "--step", "300", "--start", 0,
"DS:input:COUNTER:600:U:U",
"DS:output:COUNTER:600:U:U",
"RRA:AVERAGE:0.5:1:600",
"RRA:AVERAGE:0.5:6:700",
"RRA:AVERAGE:0.5:24:775",
"RRA:AVERAGE:0.5:288:797",
"RRA:MAX:0.5:1:600",
"RRA:MAX:0.5:6:700",
"RRA:MAX:0.5:24:775",
"RRA:MAX:0.5:288:797"
);
$ret = rrd_create($fname, $opts, count($opts));
if( $ret == 0 )
{
$err = rrd_error();
echo "Create error: $err\n";
}
?>
After running you will have a file called net.rrd in the current directory. This is your RRD and will contain all the samples for your graphs.
For more information on the options to rrd_create see: rrdcreate
Updating a RRD
The next step is to update your RRD on the frequency you set when you created it. In the case above the frequency was set to 5 minutes (300 seconds). The following script generates random input and output values as input to the update function, sleeps for 300 seconds and then loops.
$fname = "net.rrd";
$total_input_traffic = 0;
$total_output_traffic = 0;
while(true)
{
$total_input_traffic += rand(10000, 15000);
$total_output_traffic += rand(10000, 30000);
echo time() . ": " . $total_input_traffic . " and " . $total_output_traffic . "\n";
$ret = rrd_update($fname, "N:$total_input_traffic:$total_output_traffic");
if( $ret == 0 )
{
$err = rrd_error();
echo "ERROR occurred: $err\n";
}
sleep(300);
}
?>
Your input and output values could be pulled from anywhere here, I just wanted to have a source that would work for anyone who wanted to try the script.
After letting this script run for a few hours you can run the following shell script to see what type of data you have collected so far:
For more information on the options to rrd_update here: rrdupdate
END=`date +%s`
START=`echo $END-3600|bc` # over the hour
rrdtool fetch net.rrd AVERAGE --start $START --end $END
That should display the average sample values for the last hour.
Displaying RRD data as a graph
Now that you have data in your RRD you will want to graph it. The following code will graph the average input and output for 1 day as well as the max for that day.
$opts = array( "--start", "-1d", "--vertical-label=B/s",
"DEF:inoctets=net.rrd:input:AVERAGE",
"DEF:outoctets=net.rrd:output:AVERAGE",
"AREA:inoctets#00FF00:In traffic",
"LINE1:outoctets#0000FF:Out traffic\\r",
"CDEF:inbits=inoctets,8,*",
"CDEF:outbits=outoctets,8,*",
"COMMENT:\\n",
"GPRINT:inbits:AVERAGE:Avg In traffic\: %6.2lf %Sbps",
"COMMENT: ",
"GPRINT:inbits:MAX:Max In traffic\: %6.2lf %Sbps\\r",
"GPRINT:outbits:AVERAGE:Avg Out traffic\: %6.2lf %Sbps",
"COMMENT: ",
"GPRINT:outbits:MAX:Max Out traffic\: %6.2lf %Sbps\\r"
);
$ret = rrd_graph("net_1d.gif", $opts, count($opts));
if( !is_array($ret) )
{
$err = rrd_error();
echo "rrd_graph() ERROR: $err\n";
}
?>
You should end up with a file named net_1d.gif in your working directory that looks something like:

You can also do weekly and monthly graphs by changing the start parameter to -1w or -1m:
For the impatient you can download my net.rrd file and try the graphs for yourself.
See the other tutorials for more information on the options you have for graphing.
For more information on the options to rrd_graph see: rrdgraph


















December 9th, 2006 at 4:50 pm
Seems nice, makes the graph and all but doesnt update any info? Graph available for download also didnt not show any info, with script to check provided.
-- copy as . due to some funky stuff on this site.
December 9th, 2006 at 5:06 pm
Just to update before the prev post gets approved it seems to work, it was just reading a weird cache copy, changed a few names and all is good.
Please make a note on the — (double dashes) copying over as . (periods), was a little weird.
January 1st, 2007 at 12:37 pm
[...] A good place to start is the PHP RRDTool tutorial. It will make it easier to read the following code if you have an idea of how to use the RRDTool extension. [...]
January 30th, 2007 at 1:02 am
I did every configuration as mensioned in http://www.ioncannon.net/system-administration/25/how-to-build-the-php-rrdtool-extension-by-hand/.
But I dont get 'rrdtool' in
phpinfo(INFO_MODULES);
I get the Configure Command as './configure' '--with-apxs2=/usr/local/apache/apache2/bin/apxs' '--with-mysql' '--with-rrdtool' when try
phpinfo() alone.
Could you help me?
March 14th, 2007 at 11:50 am
Does anyone know how can I made a raw output directly in PHP without generate the image file on the disk ?
I've tried to put '-' as filename and effectively no file is generated … but I don't know how can I get the output …
# this code doesn't work because rrd_graph return an array but no raw datas …
header('Content-type: image/png');
…
echo rrd_graph("-", $opts, count($opts);
June 8th, 2007 at 12:12 pm
There's an rrd_fetch function included with the library as well, but I cannot for the life of me get it to work. This should work:
rrd_fetch("basic.rrd",array("MAX"),1);
But it just spits back null. If I add any arguments (like a start time), I get a seg fault. e.g.
rrd_fetch("basic.rrd",array("MAX","-s","now-1hr"),3);
Anyone got any insights in to this?
July 3rd, 2007 at 3:07 am
thanks for that work. but how do I use RRDtool to monitor the hard disk usage.\
thanks
April 30th, 2008 at 5:23 pm
The rrdtool extension works great with the apache php module through a web browser. But if I try to use any of the rrd functions from the php-cli command line php, I get a segmentation fault.
Any ideas/advice?
June 1st, 2008 at 7:34 am
Is there any way to force it to make png's instead of gifs. I'd like to use some custom fonts but ttf support is only available in png's.
cheers, Novae.