Pull to refresh

Приручение py-rrdtool

Reading time 4 min
Views 13K
Как говорится в одной древней мудрости: можно вечно наблюдать три вещи: как горит огонь, как течёт вода и как рисует графики rrdtool. Этот пост как раз о последнем.
И так, что же такое rrdtool? rddtool — замечательная утилита, которая позволяет управлять данными, хранимыми в формать rrd (round-robin database). Данный формат примечателен тем, что изначально предназначен для хранения периодичной информации, причём так, что размер самой БД получается фиксированным (довольно небольшим) независимо от количества данных. При этом сохраняется возможность получать отчёты за продолжительные отрезки времени с произвольной точностью. Наибольшее распространение данная система нашла в системах мониторинга, где, как говорится, лучше один раз увидеть картинку, чем 7 раз прочитать логи. В конце статьи Вы сможете получить нечто, похожее на

пример




Для этого потребуется: python, rrdtool, py-rrdtool.
После установки необходимых компонент получим готовые python-биндинги к rrdtool, с которыми можно дальше продолжать фантазировать. Конечно, количество возможностей rrdtool может поначалу отпугнуть, но я попробую рассмотреть несколько базовых действий + приведу немного собственного кода, который можно прямо запускать и наслаждаться.

Говорят, что настоящие гики рисуют графики всего, чего только можно, вплоть до ежедневного количества прогулок их собаки. Для примера я рассматриваю два типа хранимой-анализируемой информации:

  1. информация, автоматически подсчитываемая аппроксимацией производной входных значений (например скорость на сетевом интерфейсе по значениям количества переданных байт)
  2. простая информация, которая заносится и хранится в виде отдельных, независимых значений (температура hdd, количество подписчиков ленты и т. д)

Работа с rrd, как и с любой другой БД, начинается с определения структуры хранимых данных.
Из python это выглядит приблизительно следующим образом: первым делом импортируем необходимый модуль и указываем имя файла БД:

from rrdtool import *
fname = 'database.rrd'
rrd = RoundRobinDatabase(fname)
далее, собственно, создаём БД, задавая структуру.


rrd.create(
   # БД будет содержать два независимых источника данных (`rrdtool.DataSource`),
   # названных 'in' и 'out', типа DeriveDST — производная. Тут же задаются предельные
   # значения этих показателей:
   DataSource(«in», type=DeriveDST, heartbeat=600, min=0, max=12500000),
   DataSource(«out», type=DeriveDST, heartbeat=600, min=0, max=12500000),
   # описываем какие отчёты хотим хранить в БД.
   # последние 48 часов, каждые 5 мин
   RoundRobinArchive(cf=AverageCF, xff=0.5, steps=1, rows=576),
   # последние 2 недели, среднее зн. за 30
   RoundRobinArchive(cf=AverageCF, xff=0.5, steps=6, rows=672),
   # последние 2 месяца, средне за каждые 2 часа
   RoundRobinArchive(cf=AverageCF, xff=0.5, steps=24, rows=732),
   # последние 2 года, среднее за 12 часов
   RoundRobinArchive(cf=AverageCF, xff=0.5, steps=144, rows=1460),
   # шаг 300с — данные, хранимые в БД будут привязаны к «сетке», шагом в пять минут
   step=300
   )


Пример 2 будет отличаться лишь строками с DataSource:

DataSource(«value», type=GaugeDST, heartbeat=600, min=_min, max=_max)

Теперь у нас есть БД, в которую с периодичностью 5 минут нужно вносить данные из двух источников — in и out.

Для этого используется метод rrd.update(), который в качестве аргумента принимает значение (класса rrd.Val) и необязательный шаблон, необходимый для того, чтобы задавать данные в порядке отличном от умолчания.

Например:


values=(323132312, 128539593)
template = («in», «out»)
rrd.update(Val(*values), template=template)
Это действие логично оформить в виде отдельного скрипта и запускать кроном с пятиминутной периодичностью для этого примера.

Следующий шаг — собственно создание самой картинки c информацией за период period (day, week, month, year) из БД в файле fname


graph = RoundRobinGraph('eth0-%s.png' % (period))
  

graph.graph(
  
Def(«in», fname, data_source=«in», cf=AverageCF),
  

Def(«out», fname, data_source=«out», cf=AverageCF),
  

Cdef(«out_neg», «out,-1,*»),
  
AREA(«in», rrggbb=«32CD32», legend=«Incoming»),
  

LINE1(«in», rrggbb=«336600»),
  
GPRINT(«in», cf=MaxCF, format=r" Max\: %5.1lf %S"),
  

GPRINT(«in», cf=AverageCF, format=r" Avg\: %5.1lf %S"),
  

GPRINT(«in», cf=LastCF, format=r" Current\: %5.1lf %Sbytes/sec\n"),
  

AREA(«out_neg», rrggbb=«4169E1», legend=«Outgoing»),
  

LINE1(«out_neg», rrggbb=«0033CC»),
  
GPRINT(«out», cf=MaxCF, format=r" Max\: %5.1lf %S"),
  

GPRINT(«out», cf=AverageCF, format=r" Avg\: %5.1lf %S"),
  

GPRINT(«out», cf=LastCF, format=r" Current\: %5.1lf %Sbytes/sec\n"),
  

HRULE(«0», rrggbb=«000000»),
  

vertical_label=«bytes/sec»,
  

lower_limit=0,
  
start="-1%s" % (period,),
  

title=title,
  
width=600,
  
height=80,
  

lazy=None,
  
)
  

В двух словах — здесь задаются данные из базы, которые необходимо отобразить и детали оформления, как то: линии, залитые участки, их цвета и пр.

В результате работы этого куска можем получить что-то, напоминающее

my_example

или для примера 2 — график количества подписчиков на ленту из google reader:

subscribers_example

Я попытался оформить данные действия в более комфортную для использования (хотя, похоже, хреновом для расширения) библиотечку, которая включает в себя несколько готовых счётчико-рисовалок (для трафика, температуры hdd, количества клиентов на wifi интерфейсе, кол-во подписчиков) и пригодный для расширения простейший класс GaugeRRD, при помощи которого можно самостоятельно создавать свои классы для работы с py-rrdtool.

Примеры использования можно найти на http://undefined.org.ua/static/rrdtool/src.
Мой пример работы скриптов, оформленный в “аналитический центр” лежит на http://xa4a.org.ua/rrdtool.

В заключение хочу отметить, что целью статьи было показать возможность использования такого инструмента, как rrdtool, для анализа нетривиальных данных, или в своих python-приложений. Если же Вам необходим инструмент мониторинга системы, который готов к работе из коробки, — существует уже множество готовых проектов, например: munin, mrtg, cacti и другие.


Оригинал статьи находится в личном блоге по адресу: http://undefined.org.ua/blog/2008/08/05/py-rrdtool/
Tags:
Hubs:
+28
Comments 12
Comments Comments 12

Articles