rrdtool create <file> \ --start "<unix timestamp>" \ --step <step> \ DS:g:GAUGE:<heartbeat>:<min>:<max> \ RRA:AVERAGE:<xfiles factor>:<steps>:<rows>
When you create database, you specify data sources (DS), which define what rrdtool expects on input, and round robin archives (RRA), which define how to store and aggregate data.
rrdtool expects input data every step seconds, ideally. But generally, it's not feasible to do so exactly every step seconds. As such, rrdtool interpolates data into primary data points (PDPs), which are what it would be if data were passed exactly every step seconds. Data used for interpolation are taken from the interval of heartbeat seconds. I didn't see values other than 300 seconds for step and 600 seconds for heartbeat. But it's not that they're the only legitimate values.
PDPs are then consolidated into RRAs. xfiles factor defines how many input values we need for PDP to not be *UNKNOWN* (the docs generally uses value 0.5). steps are how many PDPs are consolidated in one consolidated data point (CDP). rows are how many CDPs are stored in RRA. Hence, RRA stores data for a period of step * steps * rows seconds.
Speaking of data source types (DSTs), you'd use GAUGE for storing things like temperature, COUNTER, DERIVE are for counters. COUNTER data source is supposed to always increase. DERIVE may decrease.
Also, note that data are expected to be fed continuously, rrdtool won't accept data other then from 1 to heartbeat seconds later than the previous value.
#!/usr/bin/env bash set -eu DIR=$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")") SCRIPT=$(basename -- "$(readlink -f -- "${BASH_SOURCE[0]}")") start=$(date '+%s') rrdtool create "$DIR/db.rrd" \ --start "$start" \ --step 300 \ DS:g:GAUGE:600:U:U \ RRA:AVERAGE:0.5:1:500 t=$(( start + 300 )) for (( i = 0; i < 5; i++ )); do for (( j = 0; j < 100; j++ )); do rrdtool update "$DIR/db.rrd" "$t:$(( i * 100 ))" t=$(( t + 300 )) done done rrdtool graph "$DIR/$SCRIPT.png" \ --start $start --end $(( start + 300 * 500 )) \ "DEF:g=$DIR/db.rrd:g:AVERAGE" \ LINE2:g#FF0000
rrdtutorial
rrdcreate
rrdgraph
monitor site response time
#!/usr/bin/env bash set -eu DIR=$(dirname -- "$0") name=$1 url=$2 step=300 IFS=: read -r today now <<< $(date +%F:%s) midnight=$(date -d "$today 0" +%s) start=$(( midnight + (now - midnight) / step * step )) # round to step (( start += step )) rrdtool create "$DIR/$name.rrd" \ --start "$start" \ --step "$step" \ DS:time_namelookup:GAUGE:$(( 2 * step )):U:U \ DS:time_connect:GAUGE:$(( 2 * step )):U:U \ DS:time_appconnect:GAUGE:$(( 2 * step )):U:U \ DS:time_pretransfer:GAUGE:$(( 2 * step )):U:U \ DS:time_starttransfer:GAUGE:$(( 2 * step )):U:U \ DS:time_total:GAUGE:$(( 2 * step )):U:U \ RRA:AVERAGE:0.5:1:$(( 24 * 60 * 60 / step )) sleep $(( start - $(date +%s) )) t=$start date +%s while true; do echo -en '\033[0K\r'; echo -n $(date +%s) IFS=: read -r time_namelookup time_connect time_appconnect time_pretransfer time_starttransfer time_total \ <<< "$(curl -sS "$url" -w \ '%{time_namelookup}:%{time_connect}:%{time_appconnect}:%{time_pretransfer}:%{time_starttransfer}:%{time_total}' \ -o /dev/null)" rrdtool update "$DIR/$name.rrd" "N:$time_namelookup:$time_connect:$time_appconnect:$time_pretransfer:$time_starttransfer:$time_total" (( t += step )) sleep $(( t - $(date +%s) )) done
#!/usr/bin/env bash set -eu DIR=$(dirname -- "$0") name=$1 end=$(rrdtool info "$DIR/$name.rrd" | grep ^last_update | sed -E 's/[^0-9]+//g') start=$(( end - 24 * 60 * 60 )) rrdtool graph "$DIR/$name.png" \ --start "$start" --end "$end" \ --height 350 \ --no-gridfit \ "DEF:time_namelookup=$DIR/$name.rrd:time_namelookup:AVERAGE" \ "DEF:time_connect=$DIR/$name.rrd:time_connect:AVERAGE" \ "DEF:time_appconnect=$DIR/$name.rrd:time_appconnect:AVERAGE" \ "DEF:time_pretransfer=$DIR/$name.rrd:time_pretransfer:AVERAGE" \ "DEF:time_starttransfer=$DIR/$name.rrd:time_starttransfer:AVERAGE" \ "DEF:time_total=$DIR/$name.rrd:time_total:AVERAGE" \ "CDEF:namelookup=time_namelookup,1000,*" \ "CDEF:connect=time_connect,1000,*" \ "CDEF:appconnect=time_appconnect,1000,*" \ "CDEF:pretransfer=time_pretransfer,1000,*" \ "CDEF:starttransfer=time_starttransfer,1000,*" \ "CDEF:total=time_total,1000,*" \ LINE1:namelookup#00cc00 \ LINE1:connect#0066b3 \ LINE1:appconnect#ff8000 \ LINE1:pretransfer#ffcc00 \ LINE1:starttransfer#330099 \ LINE1:total#990099