RRDTool

Материал из Belgorod Linux User Group - Белгород

Перейти к: навигация, поиск

Создание графиков с помощью rrdtool

Содержание

Задача

Построить графики по неким данным. К примеру полученным из log-файла путем его разбора и подсчета.

Решение

Подготовка данных

Будем использовать rrdtool - утилиту для работы с Round-robin Database. Подробнее тут: http://ru.wikibooks.org/wiki/RRDtool

Удобнее всего предварительно выгрузить наши данные в текстовый файл в формате

timestamp значение

Я предлагаю делать это perl-скриптом с получением некоего значения из логов и записи их в нужном формате. Вот пример подсчета количества вхождения слова "save" в строки некоего лога за промежуток date_from по date_to с интервалом в 5 минут.

open ( F , "$F_IN" );
        while (<F>) {
                @a_str=split (" ", $_);
                my $time = $a_str[0] ;
                # needed interval
                if ( ( $time >= $date_from ) && ( $time <= $date_to ) ) { 
                        # first iteration
                        if ( $time_start == 0 ) { 
                                $time_start = $time;
                        }
                        # count on 300 sec  
                        if ( $time > ($time_start + 300) ) {
                                print ( "$time $l_count\n" );
                                $time_start = $time ;                   
                                $l_count=0;
                        }
                        # XXX: regexp to get value
                        if ( index ($a_str[3], "save" ) > 0 ) {
                                $l_count++;
                        }
                }
}

Либо если в логах уже содержатся числовые значения - можно из получать регулярным выражением, а затем печатать:

                      $_ =~ / count: (\d+)/ ;
 ...
   print ( "$time $1\n" );

На выходе парсера логов должны получить файл нужного формата - "timestamp значение"

rrdcreate

Второй шаг - скрипт создания базы данных RRD и заполнения ее из файла с данными.

 #!/bin/bash
 
 INF=$1
 if [ ! -f "$INF" ] ; then
        echo "Use $0 <file_in.txt> [value_name=val]"
        echo " file format: TIMESTAMP VALUE"
        exit 1
 fi
 
 #.RRD File name
 rrdfile="$(basename $INF).rrd"
 
 # Частота получения данных в секундах. Используйте 1 - если у вас
 # данные очень часто изменяются (каждую секунду), если раз в 5
 # минут (по умолчанию) - можно поставить 300. Так же при
 # увеличении этого параметра - необходимо увеличить Heartbeat
 STEP=300
 #STEP=1
 
 # Heartbeat определяет максимальное количество секунд между двумя
 # обновлениями, по истечении этого значения в соответствующий
 # источник данных будет записано значение *UNKNOWN*.
 # Увеличивать значение следует при большом STEP (шаге данных) и 
 # для большей аппроксимации 
 # к примеру можно его взять как STEP*2 или больше
 HEARTBEAT=600
 
 # Проверка входных параметров
 # name of value
 NAME="val"
 if [ ! -z "$2" ]; then
        NAME="$2"
 fi
 
 if [ ! -f $INF ] ;then
        echo "Use $0 <file.in>" 
        echo " where file.in - text database with timestamp value"
        exit 1
 fi
 
 # Получаем первый timestamp - время начала нашей базы данных
 START=$(head -n1 $INF | awk '{print $1}')
 ((START--))
 if [ -f "$rrdfile" ] ; then
        echo "WARNING: RRD database $rrdfile alredy exists. Delete it."
        rm -f $rrdfile
 fi
 
 
 # Создаем базу данных.
 # Тут указан тип данных GAUGE (подробнее см. в документации)
 # RRA - архив значений. 
 # формат: RRA:AVERAGE | MIN | MAX | LAST:xff:steps:rows
 # первое значение - функция, которая применяется для хранения
 # второе - определяет какая часть данных может быть UNKNOWN
 # третье - шаг хранения данных. Внимание! это значение 
 # грубо говоря делит наш STEP, сохраняя в архив данные только 
 # с этим шагом, так что увеличивайте его только при
 # маленьком STEP, в случаи если вам надо аппроксимировать данные, 
 # используя функцию AVERAGE. При большом STEP (когда данные
 # итак редкие) - оставляйте 1
 # четвертое - количество хранимых элементов. Подбирается в 
 # зависимости от временного промежутка и шага
 # К примеру храним по 1 элементу каждые 5 минут в 1200 ячейках =
 # 1200*5/1 = 100 часов размер RRD базы
 rrdtool create $rrdfile --start $START --step $STEP \
        DS:$NAME:GAUGE:$HEARTBEAT:U:U \
        RRA:AVERAGE:0.5:1:1200
 
 if [ $? != 0 ] ; then
        echo "ERROR creating DB $rrdfile"
        exit 1
 fi
 
 # Наполнение базы данных
 while read line 
 do
        T=$(echo $line | awk '{print $1}')
        V=$(echo $line | awk '{print $2}')
        rrdtool update --template "$NAME" $rrdfile $T:$V
 
 done < <(cat $INF)

Теперь можете проверить что получилось в вашей базе, используя команды:

rrdtool dump file.rrd | less


rrdgraph

Отрисовываем нашу базу

 #!/bin/bash
 
 # проверка входных параметров
 INF="$1"
 if [ ! -f "$INF" ]; then
        echo "Use $0 <input_file.rrd> [value_name=val]"
        exit 1
 fi
 NAME="val"
 if [ ! -z "$2" ]; then
        $NAME="$2"
 fi
 
 # Получаем начало и конец графика
 # Начало получить сложнее, т.к. данные заполняются с конца по принципу fifo, 
 # по этому можно использовать конструкцию получения его из
 # предыдущего текстового файла, или поиска первого не NaN значения
 # в дампе базы
 # START=$(head -n 1 file.txt | awk '{print $1}');
 START=$(rrdtool dump $INF | grep "<row>" | grep -v NaN | head -n1 | grep -Po "\d{10} ")
 END=$(rrdtool last $INF)
 
 # Собственно сама отрисовка графика в файл
 rrdtool graph "${TITLE}_${START}-${END}.png"  --end $END --start $START \
    --width 640 --height 480 --imgformat PNG \
    --title $TITLE --rigid  --color BACK#FAFAFA  \
    DEF:${NAME}1=$RRD:$NAME:AVERAGE   \
    VDEF:${NAME}max=${NAME}1,MAXIMUM                   \
    VDEF:${NAME}avg=${NAME}1,AVERAGE                   \
    AREA:${NAME}1#00FF00:"$NAME"           \
    GPRINT:${NAME}max:"Max=%lf%s"          \
    GPRINT:${NAME}avg:"Avg=%lf%s"          \
    --vertical-label "$(date -d \@${START}) -  $(date -d \@${END})"

Несколько параметров

При построении нескольких параметров на одном графике (в одной базе данных) принцип остается тем же, только указывается несколько переменных. К примеру для создания базы на 2 графика disk0 и disk1:

rrdtool create disk.rrd --start $START --step $STEP \
        DS:disk0:GAUGE:$HEARTBEAT:U:U \
        DS:disk1:GAUGE:$HEARTBEAT:U:U \
        RRA:AVERAGE:0.5:1:500

При добавлении данных - тоже указывается сразу два значения для одного времени, указывая и в шаблоне (template) и в данных через знак :

 rrdtool update --template "disk0:disk1" disk.rrd N:$RES0:$RES1

При отрисовке так же указывается несколько источников:

DEF:disk01=disk.rrd:disk0:AVERAGE
LINE1:disk01#00FF00:"disk0" 
...
DEF:disk11=disk.rrd:disk1:AVERAGE
LINE1:disk11#0000FF:"disk1" 


Ссылки

Личные инструменты