Суть
Zabbix-сервер через механизм внешних проверок при помощи APCupsd и нехитрого скрипта собирает информацию о работе бесперебойника с ряда машин (как c Windows, так и Linux), обрабатывает и представляет ее нам в удобочитаемом виде.
Предистория
Исторически так сложилось что на ввереном мне обьекте все время было что-то не в порядке с энергоснабжением. С перебоями не справлялись ни система АВР, ни древние упсы из автомобильных аккумуляторов и хэнд-мэйд стабилизатора. И вот настал счастливый день, когда нам привезли новенькие мощные умные APC Smart-UPS. Сразу же захотелось сделать все «как положено»: с системой аварийного завершения работы и мониторинга состояния системы. Однако при первой же попытке установить комплектный софт от APC выяснилось, что он ни в какую не хочет работать с Windows Hyper-V серверами, а нехитрый установщик предложил мне перейти на сайт и приобрести (!) необходимую версию ПО. Такой поворот был недопустим. Вот тогда и родилась идея (не без помощи Google) о сторонних утилитах. Во что это вылилось — читайте дальше.
APCUPSD
APCUPSD — это кросcплатформенная опенсорсная утилита, а точнее комплекс утилит для работы с ИБП APC и другими, созданная в лучших традициях POSIX. Сама по себе она умеет получать данные упса, выключать компьютер при потере питания, и, что самое важное для нас — давать знать о состоянии ИБП всем желающим по сети. Это, в свою очередь, дает возможность работать нескольким машинам от одного ИБП, ровно как и получать необходимую статистическую информацию.
С сайта можно скачать версию как для *NIX, так и для Win и Mac. Компилятся и ставятся все они без проблем. Все настройки находятся в одном конфигурационном файле, отлично раскоменченом и не вызывающем вопросов. Нас в нем интересуют следующие строки:
# Настраиваем соединение с ИБП (зависит от вашей модели
)
UPSCABLE usb
UPSTYPE usb
DEVICE
# Частота опроса ИБП. Мы же не хотим узнать что упс отключился только # когда он уже отключился?
POLLTIME 25
# Разрешаем отправлять состояние упса по сети
NETSERVER on
# Указываем интерфейс и порт для отправки
NISIP 0.0.0.0
NISPORT 3551
Поставить и настроить демон потребуется на всех машинах, которые мы хотим мониторить. В его состав входят несколько вспомогательных утилит. На самом Zabbix-сервере достаточно будет бинарника apcaccess, входящего в сабжевый пакет.
Скрипт
Скрипт использует для своей работы утилиты linux sed, stat, date и бинарник apcaccess из пакета apcupsd. Последний применяется для получения информации через сеть от демона apcupsd. Чтобы узнать на что способен ваш упс и что впоследствии придется распарсить введем следующее:
apcaccess status host_ip
где host_ip — адрес машины с работающим упсом и apcupsd на ней.
В моем случае вывод был впечатляющим, но меня заинтересовали только несколько ключевых строк:
APC : 001,053,1301
DATE : 2010-11-25 21:18:36 +0200
UPSNAME : MysuperUPS100500
...
CABLE : APC Cable 940-0024C
MODEL : Smart-UPS RT 2000 XL
STATUS : ONLINE
LINEV : 227.5 Volts
LOADPCT : 12.0 Percent Load Capacit
BCHARGE : 100.0 Percent
TIMELEFT : 77.0 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME : 0 Seconds
MAXLINEV : 228.9 Volts
MINLINEV : 226.0 Volts
OUTPUTV : 230.4 Volts
....
Что ж, текст у нас есть, теперь дело за малым — распарсить его и передать интересующие нас вещи в Zabbix. Для этого создадим в директории, определенной в Zabbix_server.conf в параметре ExternalScripts, файл apcupsdsh следующего содержания:
#!/bin/bash
# Сохраняем вывод apcaccess в промежуточный файл не чаще чем раз в
# delay секунд. Это резко уменьшает объем трафика и количество
# обращений к не шибко быстрой apcaccess, сделано в целях оптимизации.
delay=25
M=$(stat --format=%Y /etc/zabbix/sh/tmp.$1)
D=$(date +%s)
let d=$D-$delay
if [ $d -gt $M ];
then
# В $1 заббикс передает адрес хоста
apcaccess status $1 > /etc/zabbix/sh/tmp.$1 ;
fi
# В $3 - параметр ключа, который нужно распарсить
case "$3" in
# Здесь берем временный файл и парсим по необходимому нам параметру при
# помощи регекспа sed. Я
# реализовал на мой взгляд самое необходимое.
# Заряд батареи
bcharge) sed -n 's/BCHARGE.*[:].\([0-9]*\).*$/\1/p' /var/zabbix/tmp.$1 ;;
# Состояние электросети
status) s=$(sed -n 's/STATUS.*[:].\([A-Z]*\).*$/\1/p' /var/zabbix/tmp.$1) ;;
# Так как статус - текстовый параметр, а нам проще работать с числом, преобразуем его! Если все хорошо и упс ONLINE - выдаем 1
if [ $s == "ONLINE" ];
then
echo 1 ;
else
# Если что-то не так - ноль
echo 0;
fi
;;
# Нагрузка
loadpct) sed -n 's/^LOADPCT.*[:][ ]*\([0-9]*\.[0-9]*\).*$/\1/p' /var/zabbix/tmp.$1 ;;
# Напряжение питания
linev) sed -n 's/^LINEV.*[:][ ]*\([0-9]*\.[0-9]*\).*$/\1/p' /var/zabbix/tmp.$1 ;;
# Время до отключения (при пропадании питания)
timeleft) sed -n 's/^TIMELEFT.*[:][ ]*\([0-9]*\).*$/\1/p' /var/zabbix/tmp.$1 ;;
# Если нужно - можно продолжить
esac
exit 0
Теперь присвоим необходимые права и владельца для скрипта и временных файлов (временные файлы лучше создать сразу для каждого из хостов, чтобы потом не тратить процессорное время на проверку существования файлов):
touch /etc/zabbix/sh/tmp.host_ip
chown zabbix:zabbix /etc/zabbix/sh/tmp.host_ip
chmod +x /usr/local/etc/zabbix/apcupsdsh
ZABBIX-сервер
Не буду останавливаться на установке Zabbix, благо мануалов в сети предостаточно. Нам потребуется лишь подправить параметр ExternalScripts в конфигурационном файле zabbix_server.conf:
ExternalScripts=/usr/local/etc/zabbix
Именно в эту папку необходимо поместить созданный нами скрипт.
Теперь идем в веб-админку и создаем новый шаблон. (Настройка -> Шаблоны->Создать шаблон)
Сама структура шаблона: элементы данных и триггеры — зависит от ваших потребностей, возможностей вашего ИБП, и вашей фантазии.
У меня это выглядит примерно так:

Вся магия происходит в элементах данных. Чтобы zabbix начал взаимодействовать со скриптом необходимо создать элемент данных типа «Внешняя проверка». Поле ключ должно иметь следующий вид:
apcupsdsh[{HOST.CONN} status]
где:
apcupsdsh — имя внешней команды (то есть имя скрипта);
{HOST.CONN} — макрос Zabbix, который преобразуется в адрес хоста в при выполнении проверки;
status — один из параметров, которые может принимать скрипт.
К слову можно сказать что параметров может быть больше, но нас сейчас это интересует.
Дальше выбираем тип данных, который должен возвращать скрипт. В случае status это целое (0 или 1). Остальное можно заполнить по вкусу.
Также к шаблону можно добавить триггеры и графики. Я, к примеру, сделал триггер на потерю питания, и график напряжений, а затем вывел его на Dashboard. Принцип создания триггеров базируется на элементарной логике — если Выражение становится true, то выстреливает событие назначенной важности с назначенным сообением. Выражение можно написать вручную:
{APCUPSD:apcupsdshHOST.CONN} status].last(0)}=0
Или воспользоваться мастером, что гораздо проще:

Собственно все, шаблон создан, теперь осталось только добавить к нему узлы и система начнет работу. Теперь в любое время можно посмотреть как себя вела сеть в тот или иной период, а в случае настроенных оповещений еще и вовремя узнать о неполадках.
Резюме
Данный метод несет в себе больше образовательный смысл, нежели практический. Хотя в некоторых случаях он и может стать реальным решением проблемы. Естественно ставить такой комплекс как Zabbix только для мониторинга ИБП было бы излишеством. Кроме того под вопросом производительность данного решения — в моем случае сервер легко с этим справился, однако насколько это масштабируемо мне неизвестно. В мануалах Zabbix не рекомендуют злоупотреблять внешними проверками. В принципе это возможно было бы положить на плечи zabbix-агентов, однако тут налицо увеличение количества работы над скриптами. В любом случае целью было познакомиться с возможностями zabbix, а также попрактиковаться в написании скриптов, а уж никак не придумать универсальное средство.
Источники
1.APCUPSD
2.Zabbix server