Рейтинг@Mail.ru
[Войти] [Зарегистрироваться]

Наши друзья и партнеры

UnixForum



Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Ошибка базы данных:
На главную -> MyLDP -> Тематический каталог -> Решение административных задач в Linux

Munin - отчеты от "ворона"

Оригинал: Munin - the Raven Reports
Автор: Patricia Jung
Дата: 1 апреля 2009
Перевод: Александр Тарасов aka oioki
Дата перевода: 12 сентября 2009 г.

Средство долговременного мониторинга Munin было разработано в Норвегии, его название позаимствовано из норвежской мифологии. Согласно легенде, бог Один получал вести о том, что творится в мире, от двух воронов - одного звали Мунин, другого Хугин. Мунин означает "память", а Хугин - "мысль".

Приятным свойством средства мониторинга Munin является то, что объект наблюдения не ограничивается какой-либо однотипной системой или сетевыми параметрами. К примеру, можно с легкостью приспособить его к отделу маркетинга и отслеживать с его помощью объемы продаж. Все, что нужно будет сделать - написать скрипт или программу на вашем любимом языке, лишь бы она возвращала на стандартный вывод текущее значение наблюдаемой величины в виде параметр.value значение и вывести в конце символ новой строки.

В старых главах официальной документации (в том числе в исходном коде, написанном на языке Perl) пишут, что Munin - это клиент-серверное приложение, что сбивало с толку. Недавно разработчики Munin стали утверждать, что Munin обладает архитектурой "мастер и узлы" (master-node), что намного более соответствует истине.

Мастер собирает, хранит и представляет данные

Чтобы воспользоваться этим программным пакетом, вам потребуется машина с установленным веб-сервером и средством RRDtool от Tobias Oetiker. На этой машине будет работать центральная часть Munin, называемая мастером. Пользователи дистрибутивов Debian и Ubuntu могут найти его в пакете munin. Он состоит из набора скриптов на языке Perl, которые запускаются по расписанию cron с интервалом в 5 минут. Эти скрипты собирают данные с нескольких узлов Munin, архивируют их в циклической базе данных (round-robin database, RRD), генерирует диаграммы и обновляет отображающие их веб-страницы. Один из этих скриптов под названием munin-limits также предупреждает пользователя о значениях, которые превышают допустимые пределы.

У циклических баз данных (RRD) есть неоспоримое преимущество, что они не увеличиваются в размере с течением времени. Время проходит - старые данные сжимаются и хранятся в менее подробной форме, пока не будут исключены полностью. В Munin используется база RRD. Данные за последние 48 часов в ней хранятся с 5-минутным разрешением. Средние значения за последние десять дней хранятся с разрешением в полчаса, средние значения за последние 46 дней хранятся с разрешением в 2 часа, а средние значения за последние 449 дней хранятся с разрешением в одни сутки.

Мастер Munin считывает конфигурационный файл munin.conf, который по умолчанию хранится в /etc/ (в системах Debian/Ubuntu конкретно /etc/munin/munin.conf). Там записано, каковы источники данных и с каким именем хоста показывать эти данные в веб-интерфейсе. Типичная запись в конфигурационном файле имеет следующий вид:

[Airport;localhost.localdomain]
    address 127.0.0.1
    use_node_name yes

В квадратных скобках записывается имя наблюдаемой машины (в данном случае, localhost.localdomain). Если вы запишете полное имя хоста с доменом (FQDN), Munin автоматически поместит эту машину в группу, названную по доменной части. Если предпочитаете сгруппировать машины по-своему, напишите имя этой новой группы перед именем хоста в квадратных скобках (в данном случае - Airport; результат можно увидеть на рисунке 1).

Только обязательно нужно поставить точку с запятой в качестве разделителя, безо всяких пробелом перед ним и после него. Лучше всего определиться с группами в самом начале, ведь Munin использует имя группы в качестве имени каталога, в котором находятся циклические базы данных и диаграммы (для нашего примера в системе Ubuntu таким каталогом будет /var/www/munin/Airport/).


Рисунок 1. Главная страница Munin отображает все модули, упорядоченные по группе и по имени хоста. Категории каждого хоста заключены в квадратных скобках.

Имена файлов баз данных и диаграмм содержат имя хоста в квадратных скобках. Если вы все-таки решитесь изменить строку в квадратных скобках в конфигурационном файле, тогда нужно будет соответствующим образом переименовать имена каталогов и находящихся внутри них файлов. Это нужно проделать в тот 5-минутный промежуток времени, когда Munin ничего не делает. Иначе Munin создаст новую базу данных, и старые данные потеряются.

Где взять данные?

Чтобы указать мастеру Munin, откуда брать данные по конкретной машине, нужно воспользоваться параметром address - указать в нем IP-адрес машины. Таким образом, можно заставить Munin, к примеру, собирать данные о машине с другой промежуточной машины.

Казалось бы, это только усложняет нам жизнь. Однако на самом деле это очень полезная функция, ведь она позволяет использовать открытые коммуникации протокола Munin лишь среди своих машин, которым вы доверяете. В дополнение к этому, у вас не всегда есть возможность установить узловую программу Munin на непосредственно целевую машину, к примеру, когда узел Munin собирает данные по протоколу SNMP. В этом случае, нужно присвоить параметру use_node_name значение no.

На каждой машине, для которой вы указали параметр address, нужно установить узловую программу Munin. В противном случае соответствующие веб-страницы будут оставаться пустыми. В системах Debian/Ubuntu соответствующий пакет называется munin-node.

Узел Munin состоит из демонов, которые по запросу от мастера Munin запускают модули, ответственные за сбор каких-либо данных. Его конфигурационный файл munin-node.conf хранится в том же каталоге, что и munin.conf. Пусть вас не смущает наличие сразу двух этих файлов - вполне возможно, что ваш компьютер является как мастером, так и узлом. Помимо всего прочего, в файле munin-node.conf определяется файл журнала и уровень журналирования, номер слушающего порта (по умолчанию 4949) и, самое главное, машины, которым разрешено подключаться к демону:

allow ^127\.0\.0\.1$

В данном случае регулярное выражение ^127\.0\.0\.1$ запрещает доступ всем компьютерам, кроме мастера Munin, работающего на этой же машине localhost.

Первый контакт - через Telnet

Если устанавливать узловую программу Munin с помощью пакетного менеджера, то уже будет активировано множество модулей. В этом случае, нужно подключиться telnet'ом на порт 4949 требуемого узлового компьютера. Вот примерно что вас ждет:

$ telnet localhost 4949
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
$ munin node at extrablatt.trish.de
help
$ Unknown command. Try list, nodes, config, fetch, version or quit
list
  open_inodes         if_err_eth0  irqstats
  entropy             processes    postfix_mailqueue
  if_eth0 df          netstat      interrupts
  swap                load         cpu
  df_inode            if_eth1      if_err_eth1
  postfix_mailvolume  forks        iostat
  open_files          memory       vmstat

fetch open_inodes
used.value 67839
max.value 68094
.
Connection closed by foreign host.

Команда list печатает имена всех активных модулей на этом узле. Команда fetch с указанием имени модуля в качестве аргумента, возвращает значения параметров, соответствующих модулю (в данном случае, used и max). Если вы не изменяли директиву timeout в конфигурационном файле munin-node.conf (к примеру, увеличить до 20 секунд: timeout 20), тогда нужно будет поспешить набрать все эти команды, ведь демон закрывает соединения спустя 10 секунд.

Если команда list ничего не вывела (это возможно, если вы устанавливаете программу из исходников), необходимо их активировать. Для этого нужно создать символьную ссылку на них в каталоге plugins (в системах Debian/Ubuntu это каталог /etc/munin/plugins) на узловой машине и перезапустить демона с помощью init-скрипта.

Шаблонные модули и модули autoconf

Существует два типа модулей. У модулей, независимых от дополнительных параметров, имя символьной ссылки на него в /etc/munin/plugins соответствует имени самого плагина. Однако иногда модуль может наблюдать за несколькими элементами одного типа, например, за несколькими сетевыми интерфейсами, скажем, eth0 и eth1.

В этом случае было бы глупо жестко прописывать имя интерфейса в модуле. Вместо этого мы даем имя интерфейса как часть имени ссылки. Модули, способные воспринимать подобным образом аргументы, называются шаблонными модулями, их имена заканчиваются символом подчеркивания. К примеру, если вы хотите наблюдать за интерфейсом eth0 с помощью шаблонного модуля if_, потребуется создать символьную ссылку на if_ с именем ссылки if_eth0:

$ ls -al /etc/munin/plugins/if_eth*
lrwxrwxrwx 1 root root 28 2008-06-27 23:53
 ↪/etc/munin/plugins/if_eth0 -> /usr/share/munin/plugins/if_

lrwxrwxrwx 1 root root 28 2008-06-27 23:53
 ↪/etc/munin/plugins/if_eth1 -> /usr/share/munin/plugins/if_

Практически все модули из пакета Munin принадлежат семейству модулей auto и могут быть запущены с аргументом autoconf. В этом случае модуль проверит, может ли он выдавать осмысленные результаты. К примеру, запуск модуля мониторинга почтового агента Exim имеет смысл лишь тогда, когда у вас действительно работает почтовый сервер Exim. Если система не удовлетворяет требованиям конкретного autoconf-модуля, будут выведены рекомендации по исправлению ситуации, к примеру:

$ /usr/share/munin/plugins/exim_mailqueue autoconf
no (exim not found)

Сделать обзор всех предустановленных модулей, реализующих метод autoconf, можно с помощью команды:

# munin-node-configure --suggest
Plugin                      -  Used  -  Suggestions
------                      -  ----  -  -----------
[...]
exim_mailqueue              -  no    -  [exim not found]
[...]
if_                         -  yes   - 
[...]

Если у вас возникло желание написать свой модуль и поделиться с другими, например, на сайте Munin Exchange, рекомендуем вам взглянуть сначала на официальные модули. Посмотрите, как там реализован метод autoconf.

Улетаем

В качестве примера будем отслеживать отправления в Мюнхенском аэропорту с обычным 5-минутным интервалом. Расписание отправлений доступно на веб-сайте. Напишем скрипт, который будет обрабатывать соответствующую веб-страницу. Для начала сделаем дамп нужной веб-страницы с помощью текстового браузера Links, сохраним ее содержимое во временном файле:

#!/bin/sh

SITE=http://www.munich-airport.de
DEP_URL=$SITE/en/consumer/fluginfo/abflug/index.jsp?viewType=t
TMP_FILE=/tmp/.muc_flights

links -dump $DEP_URL > $TMP_FILE

Теперь в этом файле содержатся следующие строки:

[...]
 [ LH 3464 ] [ Budapest ]   [ 21:30 ] [  ]   [ T2 ]   [ departed ]
 [ LH  726 ] [ Shanghai ]   [ 21:30 ] [  ]   [ T2 ]   [ boarding ]
[...]

Всего есть 5 состояний отправлений: ожидание (calling), посадка (boarding), отправлено (departed), отложено (planned) и отменено (cancelled). Будем подсчитывать их количество на текущем интервале времени и возвращать эти значения на стандартный вывод, примерно так:

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

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

$ date +%H:%M
21:30

и отфильтровать с помощью grep эту строку в дампе веб-страницы. К сожалению, все немного сложнее, чем мы задумывали. В расписании отправлений аэропорта все полеты распределены по 5-минутным слотам. Однако хотя задача cron на мастере Munin настроена на запуск в 0, 5, 10 и т.д. минут каждого часа, но мы не можем быть уверены, что задача будет выполнена ровно в это время. Вот почему нашему модулю требуется операция округления (реализуемая с помощью bc) до текущих минут. После этого скомбинируем минуты и часы:

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

Теперь переменная TIME содержит лишь пары вида час:минута, в которых минуты кратны 5.

Интерполировать не надо

Есть еще одна сложность - когда мастер Munin сохраняет полученные от модулей данные в RRD в момент времени, отличный от точного запланированного времени, поэтому RRDtool вынужден интерполировать значения. Поэтому в базе данных редко содержатся целые числа, которые возвращает наш модуль, а чаще всего - слегка отклоняющиеся числа с плавающей запятой.

Хорошо, что RRDtool может принимать пары "время, значение". В таком случае интерполяции удастся избежать. Время должно быть записано в виде числа секунд от 1 января 1970 года 00:00:00 UTC. Между временем и значением должен стоять разделитель - двоеточие (:), вот пример вывода нашего модуля:

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

(1230841800 означает 1 января 2009 года, 21:30). Обратите внимание, что Munin старых версий (до 1.3.4) не понимал подобный формат вывода модулей. Таким образом, следующий код становится несовместимым со старыми версиями Munin:

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)"

Метод config

Помимо текстового вывода при простом запуске модуля без аргументов, в каждом модуле должен быть реализован метод config, который выполняется при запуске модуля со строковым аргументом config. Пусть наш скрипт называется muc (сокращение от Мюнхен). Если запустить его с аргументом config, он должен вывести, к примеру, такой текст:

$ ./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

Каждый раз, когда мастер Munin обращается к узловому демону для запуска модуля с помощью команды fetch (она была показана чуть выше в telnet-сессии), он также вызывает метод config, чтобы понять, как следует отображать полученные данные на диаграмме. В этом примере, график должен быть озаглавлен "Departures Munich Airport" (см. рисунок 2), а ось Y должна быть подписана Number (количество).


Рисунок 2. Отправления из аэропорта Мюнхена. 2 января 2009 года

Переменная graph_args позволяет модулю передавать аргументы для утилиты отображения графиков RRDtool (см. man-страницу по слову rrdgraph). Если передать аргумент --base 1000, тогда модуль muc будет знать, что префиксу k (кило) соответствует значение 1000, а не 1024. Аргумент -lower-limit 0 включает авто-масштабирование RRDtool. При этом ось Y всегда будет начинаться со значения 0.

Переменная graph_category указывает мастеру Munin, в какую категорию (см. рисунок 1) должны быть помещены соответствующие диаграммы. Это позволяет вам логически группировать диаграммы. Диаграммы модулей, для которых не указана переменная graph_category, помещаются в категорию "Other". Данные muc будут представлены в нашей собственной категории под названием Departures.

Как отображаются отдельные параметры

В дополнение к этим переменным, относящимся к графику, можно также указать подробности каждого параметра, наблюдаемого модулем. Например, в случае модуля muc - это calling, boarding, departed, planned и cancelled. Переменная параметр.label устанавливает запись легенды для параметра.

параметр.draw обозначает тип диаграммы, в которой будут представлены данные параметра. Тип AREA указывает на то, что мастер Munin должен построить соответствующую кривую и залить все пространство под ней одним цветом. Если выбран тип STACK, тогда данные будут сложены в стопку и аналогично залиты. Таким образом мы сложим все полеты за текущий 5-минутный интервал, которые помечены как calling, boarding или departed. Расписание впоследствии не корректируется, все эти отправления считаются совершенными на данный момент времени.

Полеты, помеченные как planned и cancelled ведут себя по-другому. Для отложенных полетов, аэропорт Мюнхена чуть позже выставит новое время отправления. Таким образом, модуль увидит отложенные полеты дважды: как planned в их временном слоте в соответствии с расписанием, и как calling, boarding или departed в тот временной интервал, когда самолет действительно отправится. Вот почему мы рисуем отложенные полеты отдельной линией типа LINE2. Число означает толщину линии в пикселях. Тип линии LINE1 имеет толщину в один пиксель; LINE2 - два пикселя, а LINE3 - три. Отмененные полеты больше не повторятся в расписании, поэтому выделим их пожирнее - отдельной линией толщиной в 2 пикселя.

Этот модуль печатает значения параметров на стандартный вывод. Финальная версия нашего скрипта muc показана в листинге 1.

Листинг 1. Текст модуля muc для Munin

SITE=http://www.munich-airport.de
DEP_URL=$SITE/en/consumer/fluginfo/abflug/index.jsp?viewType=t
TMP_FILE=/tmp/.muc_flights

if test "$1" = "config"; then
    echo graph_title Departures Munich Airport
    echo graph_vlabel Number
    echo graph_args --base 1000 --lower-limit 0
    echo graph_category Departures
    echo calling.label Calling
    echo calling.draw AREA
    echo boarding.label Boarding
    echo boarding.draw STACK
    echo departed.label Departed
    echo departed.draw STACK
    echo planned.label Late
    echo planned.draw LINE2
    echo cancelled.label Cancelled
    echo cancelled.draw LINE2
else
    TIME=$(date +%H)
    MIN=$(echo "($(date +%M)/5)*5" | bc)
    case $MIN in
        0) TIME=$TIME:00 ;;
        5) TIME=$TIME:05 ;;
        *) TIME=$TIME:$MIN ;;
    esac

    TMP_FILE=$TMP_FILE:$TIME
    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)"

    rm $TMP_FILE
fi

Чтобы активировать модуль muc, нужно создать символьную ссылку в каталоге plugins и перезапустить демона Munin:

# ln -s <path/to/>muc /etc/munin/plugins
# /etc/init.d/munin-node restart

Подключившись telnet'ом с мастер-машины на порт 4949 узловой машины, на которой работает модуль muc, мы можем проверить, все ли в порядке. Давайте взглянем, как работает наш метод config:

$ telnet localhost 4949
[...]
config muc
graph_title Departures Munich Airport
graph_vlabel Number
[...]
cancelled.label Cancelled
cancelled.draw LINE2

Раз мы можем вызвать метод config вручную, значит и мастер Munin должен уметь строить графики и показывать их на веб-странице, как показано на рисунке 3.


Рисунок 3. Munin создает дневные, недельные, месячные и годовые графики. Если хотите оставить их для истории, можно написать задачу cron, которая архивирует необходимые PNG и/или RRD-базы в определенные моменты времени.

Недостатки

Простой способ написания и подключения собственных модулей - один из самых больших преимуществ Munin. Даже более сложные шаблонные модули - это не так круто.

К сожалению, "простой" иногда означает "упрощенческий". Хотя и возможно показывать сгенерированные диаграммы на своих веб-страницах, но Munin не предоставляет возможностей по изменению внешнего вида генерируемых веб-страниц. Простой способ, когда на одной странице показываются дневные и недельные графики, вряд ли оправдывает себя на рабочих местах с большим количеством хостов, ведь тогда обзорная страница грузится очень долго.

Другой негативный пример - фиксированное временное разрешение данных. Не все данные настолько быстро меняются, что необходим аж 5-минутный интервал.

К сожалению, возможность настройки отдельных модулей остается лишь строчкой в списке пожеланий. С другой стороны, Munin позволяет настраивать модули достаточно четко с помощью переменных окружения, устанавливаемых в каталоге /etc/munin/plugin-conf.d/.

Несомненно, документация должна быть расширена и углублена. Так как исходный код плохо документирован, остается обращаться к спискам рассылки английских и немецких пользователей системы Munin.

Источники информации

Патрисия Джунг (Patricia Jung, trish+lj@trish.de) работает фрилансером как технический писатель, редактор, менеджер сообществ и системный администратор. Специализируется в проектах с открытым исходным кодом, живет в Мюнхене, Германия.


Если тема вас заинтересовала, вы можете прочитать на этом сайте еще одну статью о мониторинге с помощью Munin: Мониторинг сервера с помощью munin и monit на Fedora 7.


Средняя оценка 4 при 1 голосовавших
Вы сможете оценить статью и оставить комментарий, если войдете или зарегистрируетесь.
Только зарегистрированные пользователи могут оценивать и комментировать статьи.

Комментарии