Introduction
The VDEF directive provides a mechanism for applying mathematical operations on sets of data. Unlike the CDEF directive, the result of a VDEF is a single value. The VDEF can reference either a DEF or CDEF data set and can perform a number of operations including calculating averages, standard deviations, least squares lines, and more. These values can then be further referenced in CDEFs for graphing or printed out.
There is often much confusion regarding the differences of the DEF, CDEF, and VDEF directives. It may help to think of the different directives in the following manner:
- A DEF directive references a set of “raw” data as it is stored in a RRA
- A CDEF directive applies a function to each data point it references
- A VDEF directive applies a function to an aggregate of data points
The VDEF Directive
The basic format for a VDEF directive is as follows:
VDEF:Label=RPN Expression
Label is the name of the VDEF. It may be referenced in other directives including HRULEs or CDEF calculations. It may be from 1-19 characters long and consists of characters in the set [a-zA-Z0-9_]. Note that the label must be unique and cannot overlap with any labels assigned to other DEFs, CDEFs, or VDEFs.
RPN Expression is the mathematical or logical expression that is applied to a data set. The expression uses Reverse Polish Notation to eliminate confusion or errors that may occur with the precedence rules required of traditional infix notation. There are a number of mathematical, boolean and logical operators available for inclusion in a VDEF directive.
VDEF Examples
Example 1
This is a simple example which illustrates the use of VDEFs to reveal information about the set of data. In this case, the MINIMUM, MAXIMUM, and AVERAGE operations are used to determine the respective values for the data set. The resulting value for each operation is then used as the value for a HRULE providing a clear illustration in the resulting graph. Note that the VDEF values are based only on the data referenced. In this case, the data is bounded by the start and end time specified and so would likely differ for a different window into the original data set.
rrdtool graph "Example 1 VDEF.png" \
--start "end-48 hours" --end "12am Nov 1, 2009" \
--imgformat PNG --width 500 --height 120 \
--title "Example 1" \
--vertical-label "Temperature" \
DEF:temp=sysinfo.rrd:temperature:AVERAGE \
VDEF:min=temp,MINIMUM \
VDEF:max=temp,MAXIMUM \
VDEF:avg=temp,AVERAGE \
AREA:temp#FFEF00 \
HRULE:max#FF0000:"Max" \
HRULE:avg#000000:"Average" \
HRULE:min#0000FF:"Min"
Example 2
This example uses the average and standard deviation VDEF operations to identify temperature ranges that exceed the average temperature by more than one standard deviation. The VDEF operations determine the appropriate values, which are then used in the CDEF operations to generate new data sets. The original data set is graphed in the “hot” color with the “normal” and “cool” graphs overlayed on top of the appropriate sections.
The CDEF calculations may be difficult to parse for a novice to Reverse Polish syntax. It may help to break it down as follows:
- cool=temp,avg,stdev,-,LE,temp,UNKN,IF
- cool=temp,(avg – stdev),LE,temp,UNKN,IF
- cool=(temp <= (avg – stdev)),temp,UNKN,IF
- cool=if (temp <= (avg – stdev)) then temp else UNKN
rrdtool graph "Example 2 VDEF.png" \
--start "end-48 hours" --end "12am Nov 1, 2009" \
--imgformat PNG --width 500 --height 120 \
--title "Example 2" \
--vertical-label "Temperature" \
DEF:temp=sysinfo.rrd:temperature:AVERAGE \
VDEF:avg=temp,AVERAGE \
VDEF:stdev=temp,STDEV \
CDEF:cool=temp,avg,stdev,-,LE,temp,UNKN,IF \
CDEF:medium=temp,avg,stdev,+,LE,temp,UNKN,IF \
AREA:temp#FF0000:"Hot" \
AREA:medium#FFEF00:"Normal" \
AREA:cool#0000FF:"Cool"
Example 3
This example illustrates how to use the least squares line VDEF operations to draw a trendline. The LSLSLOPE operation can determine the slope of line and the LSLINT can provide the y-axis intercept value. A trendline can then be generated using the classic "y=mx+b" formula (where m is the slope and b is the intercept).
The CDEF operation implements this formula using several “tricks” of rrdtool: a workaround for the CDEF requirement to reference a DEF or CDEF, and the use of the COUNT operation to increment a value for each data point in the graph set. In the example, the CDEF reference requirement is satisfied by the “temp,POP” elements, which effectively puts a value from the temp DEF on the stack and then pops it back off, discarding it.
rrdtool graph "Example 3 VDEF.png" \
--start "end-48 hours" --end "12am Nov 1, 2009" \
--imgformat PNG --width 500 --height 120 \
--title "Example 3" \
--vertical-label "Temperature" \
DEF:temp=sysinfo.rrd:temperature:AVERAGE \
VDEF:slope=temp,LSLSLOPE \
VDEF:intercept=temp,LSLINT \
CDEF:trendline=temp,POP,COUNT,slope,*,intercept,+ \
AREA:temp#FFEF00 \
LINE2:trendline#000000
Example 4
This examples uses the PERCENTNAN operation in order to identify the 5% coolest and 5% hottest temperatures in the data set. These values are then applied as part of the CDEF calculations to generate the appropriate data sets for graphing. Note that it is frequently best to use the PERCENTNAN operation instead of the PERCENT operation as the PERCENTNAN variant handles any gaps in the data in a more graceful manner.
rrdtool graph "Example 4 VDEF.png" \
--start "end-48 hours" --end "12am Nov 1, 2009" \
--imgformat PNG --width 500 --height 120 \
--title "Example 4" \
--vertical-label "Temperature" \
DEF:temp=sysinfo.rrd:temperature:AVERAGE \
VDEF:cool5=temp,5,PERCENTNAN \
VDEF:hot95=temp,95,PERCENTNAN \
CDEF:cool=temp,cool5,LE,temp,UNKN,IF \
CDEF:medium=temp,hot95,LE,temp,UNKN,IF \
AREA:temp#FF0000:"Hot" \
AREA:medium#FFEF00:"Normal" \
AREA:cool#0000FF:"Cool"


















