Munin—the Raven Reports

Long-term monitoring with Munin is not restricted to system parameters. Why not monitor data of personal interest or data of interest to your colleagues?

and grep for this string in the “links” dump. Unfortunately, matters are a bit more complicated. The airport's departure timetable lists all flights in five-minute slots. But, even though the cron job on the Munin master is configured to run at zero, five, ten (and so on) minutes past the hour, we can't be sure it will run exactly on time. That's why our plugin uses a modulo operation (executed by bc) to round down the current minutes accordingly and combine hour and minutes in a case construction:

TIME=$(date +%H)
MIN=$(echo "($(date +%M)/5)*5"|bc)
case $MIN in
    0) TIME=$TIME:00   ;;
    5) TIME=$TIME:05   ;;
    *) TIME=$TIME:$MIN ;;

Now the TIME variable contains only hour:minute pairs in which the minutes are a multiple of five.

Stop Interpolating!

There's another complication—when the Munin master stores the values retrieved from the plugin in the relevant RRDs at a point in time deviating from the exact planned time that RRDtool interpolates them. This way the database rarely contains the integer values our plugin returns but slightly deviating floating-point values.

The good news is that RRDtool accepts time value pairs. In this case, it will refrain from interpolation. The time must be given in seconds since January 1, 1970 00:00:00 UTC as a prefix of the value. A colon (:) is used as the delimiter, as in the following example plugin output:

calling.value 1230841800:0
boarding.value 1230841800:1
departed.value 1230841800:1
planned.value 1230841800:0
cancelled.value 1230841800:0

(1230841800 equals January 1, 2009, 21:30.) Note that Munin versions before 1.3.4 were unable to handle plugin output using this extended format. This means the following plugin code won't be compatible with older Munin versions:

links -dump $DEP_URL | grep $TIME > $TMP_FILE

UNIXTIME=$(date -d$TIME:00 +%s)
echo "calling.value $UNIXTIME:$(grep calling $TMP_FILE | wc -l)"
echo "boarding.value $UNIXTIME:$(grep boarding $TMP_FILE | wc -l)"
echo "departed.value $UNIXTIME:$(grep departed $TMP_FILE | wc -l)"
echo "planned.value $UNIXTIME:$(grep planned $TMP_FILE | wc -l)"
echo "cancelled.value $UNIXTIME:$(grep cancelled $TMP_FILE | wc -l)"

The config Method

Apart from the output to be generated when the plugin is run without further arguments, all plugins are required to implement a config method, which is executed when the plugin is run with the config string as an argument. If we name our script muc (the abbreviation for Munich Airport) and start it from the directory where it is located, it might, for example, produce the following output:

$ ./muc config
graph_title Departures Munich Airport
graph_vlabel Number
graph_args --base 1000 --lower-limit 0
graph_category Departures
calling.label Calling
calling.draw AREA
boarding.label Boarding
boarding.draw STACK
departed.label Departed
departed.draw STACK
planned.label Late
planned.draw LINE2
cancelled.label Cancelled
cancelled.draw LINE2

Each time the Munin master asks the Munin node dæmon to run a plugin using the fetch command (as presented in the Telnet session above), it also executes the config method in order to find out how it should display the data in the diagram. In this example, the graph should be titled “Departures Munich Airport” (Figure 2), and the y-axis should be labeled “Number”.

Figure 2. Departures from Munich Airport, January 2, 2009

The graph_args variable allows the plugin to forward arguments to the RRDtool graphing routine (see the rrdgraph man page). Forwarding the option --base 1000, the muc plugin ensures that a k (kilo) unit prefix as displayed in the graph equals 1000, not 1024. The -lower-limit 0 influences RRDtool's autoscaling. It makes sure that the displayed y-axis always will range at least from 0.

The graph_category tells the Munin master in which category (Figure 1) the relevant diagrams are to be displayed. This allows you to group diagrams in a logical way. The diagrams of plugins that do not specify the graph_category variable can be found in the “Other” category. The muc data will be presented in our own new category titled Departures.