Make stripgraph/sparkline charts from RRDTool data

6th February 2006 - version 0.3


In his new book, Beautiful Evidence, Edward Tufte describes a sparkline as an "Intense, Simple, Word-Sized Graphic". In his description, they are intended to literally fit in the flow of words in a paragraph as a condensed indication of a lump of data. The aim for us isn't to give massive detail, just to show the 'shape' of the data, perhaps with some numbers for key points, to give a sense of scale. In his description, Tutfte is talking for the most part about print, where you have a very high resolution compared to the screen, and the examples include a whole year of data in an inch of typesetting...

RRD Sparklines

A small, embeddable stripchart generated from rrdtool XML output, collected by Cacti.

I had been stung a couple of times in the past by situations where we had some kind of network problem, and found that in retrospect, we should have seen it a lot sooner in our MRTG/Cacti data, because there it was, in Blue And Green. Rather than having someone made into "MRTG Officer", we decided to get the graphs out where many eyes could see them - onto our intranet pages. Everyone in the company sees that page at least once or twice an hour. Even one of our Accounting staff can see when theres an unusual shape on the chart, even if they can't interpret it. To do that, you need to make the information both denser and cleaner than the standard RRDtool output. On our pages, we have a stack of the graphs in the margin, showing the last 3 hours for various network, server and environmental variables in a clean way with a hyperlink to take you to the 'real' data in Cacti. It works too - people who would otherwise not notice have become deputies, asking "what's happening to the mail server right now?".

This is a perl script that produces sparkline-esque charts from the data stored in an RRDTool .rrd file. It takes the output from the RRDTool xport function, and uses it to produce a .png file to your specifications. Because xport can use the full range of RRDTool RPN functions, you can do a reasonable amount of preprocessing before the data is given to - summing several DS, for example, or multiplying the values by 8, since most routers keep byte counters and most ISPs know bits/sec.

To make this a bit more manageable, I used a shell script to drive the process, which I run every five minutes on the end of the cron job that updates the RRDs in the first place (for me, this is Cacti's poller.php, but could equally your MRTG job). For our stripgraphs, we show the current value in red, and highlight that point on the line too. This version doesn't produce 'real' sparklines, but it does do almost all the necessary heavy lifting to do that, and it's intended to have a future version which allows for even denser packing.

A sample shellscript to drive the perl

Note that the second graph generated uses a CDEF to change from a byte-rate to a bit-rate.


COLOURS="--backgroundcolour dedeff --linecolour 8080ff"

rrdtool xport -s now-$PERIOD -e now DEF:i=$RRA:$DS0:AVERAGE 'CDEF:inbits=i,1,*' XPORT:inbits:"NOC temperature" | ./$STRIP $COLOURS $COMMONOPTIONS --unformatted --nonzero  -outputfilename noc-temperature.png

rrdtool xport -s now-$PERIOD -e now DEF:i=$RRA:$DS0:AVERAGE 'CDEF:inbits=i,8,*' XPORT:inbits:"Transit outbound" | ./$STRIP $COLOURS $COMMONOPTIONS --nonzero --outputfilename transit-out.png

The possible options are:

--width nThe final image should be n pixels wide.
--height nThe final image should be n pixels high.
--outputfilename "string"The name of the PNG file to produce. Defaults to strip.png
--nonzeroThe y-axis of the graph should be from the minimum to the maximum values found in the RRD dump, rather than from zero to the maximum. If you have a variable that generally varies from 1000 to 1100 then having the graph start at zero hides a lot of detail.
--unformattedBy default, we try to format the numbers to use M,G,T etc for thousands. This stops that behaviour.
--label "string"Use "string" as the label for the graph. We'll try and figure this out from the RRD dump if it isn't given.
--linecolour colourspecSets the colour for the main part of the graph's line (excluding the last value). Colours are specified in HTML-style - 6 hex characters RRGGBB. Default is a dark blue.
--backgroundcolour colourspecSets the colour for the background of the graph part. Colours are specified in HTML-style - 6 hex characters RRGGBB. Default is a nice pale blue.
--font fontfileSpecifies the path to a truetype font file. This should look something like: ./ArialN.TTF, which is the very system-specific default.
--fontsize nSpecifies the font size in pixels. Default is 12.

Download version 0.3 - February 6th 2006
Version 0.3 - first available version. Re-written to use Imager rather than GD. Removes reliance on ImageMagick for post-processing. Very much untested beyond what I needed. I'm not at all surprised if you can make it do strange things by giving it odd options.
Copyright 1994-2006, by Howard Jones.