Что побудило меня написать данную статью? Поискав на просторах интернета по запросу «мониторин ippon winner 3000». Интернет выдавал как правило статьи про настройку NUT. Проект действительно интересный, имеет много возможностей. Но есть одно маленькое НО! Не поддерживается ippon winner 3000 по USB. По COM-порту все работает замечательно. Видел конфиги подключение по USB, но мне кажется это копипаст без практической проверки. Хотя может я и ошибаюсь. Я по крайней мере убил пол дня на попытки заставить это рабоатать, но тщетно.
Нашел альтернативный проект apcupsd, завелось все из коробки с небольшими настройками. У меня к одному компьютеру, задача которого отвечать за мониторинг, поключены по USB оба бесперебойника ippon winner 3000. На нем же находится и Zabbix. В детали Zabbix-а вдаваться не будем, скажу лишь что он достоен отдельной статьи и не одной. Процесс расписывать не вижу смысла, таких статей предостаточно. Просто приведу готовые конфиги. Устанавливаем сам пакет:
$sudo apt-get install apcupsd
Все файлы настройки и скрипты по умолчанию находятся по умолчанию в /etc/acpupsd/ Прошу особое внимание обратить на названия статус и конфиг файлов.
UPSTYPE usb
DEVICE /dev/usb/hiddev0
LOCKFILE /var/lock
SCRIPTDIR /etc/apcupsd
PWRFAILDIR /etc/apcupsd
NOLOGINDIR /etc
ONBATTERYDELAY 6
BATTERYLEVEL 5
MINUTES 3
TIMEOUT 0
ANNOY 300
ANNOYDELAY 60
NOLOGON disable
KILLDELAY 0
NETSERVER on
NISIP 127.0.0.1
NISPORT 3551
EVENTSFILE /var/log/apcupsd/apcupsd-ippon0.events
EVENTSFILEMAX 10
UPSCLASS standalone
UPSMODE disable
STATTIME 60
STATFILE /var/log/apcupsd/apcupsd-ippon0.status
LOGSTATS off
DATATIME 0
UPSTYPE usb
DEVICE /dev/usb/hiddev1
LOCKFILE /var/lock
SCRIPTDIR /etc/apcupsd
PWRFAILDIR /etc/apcupsd
NOLOGINDIR /etc
ONBATTERYDELAY 6
BATTERYLEVEL 5
MINUTES 3
TIMEOUT 0
ANNOY 300
ANNOYDELAY 60
NOLOGON disable
KILLDELAY 0
NETSERVER on
NISIP 127.0.0.1
NISPORT 3552
EVENTSFILE /var/log/apcupsd/apcupsd-ippon1.events
EVENTSFILEMAX 10
UPSCLASS standalone
UPSMODE disable
STATTIME 60
STATFILE /var/log/apcupsd/apcupsd-ippon1.status
LOGSTATS off
DATATIME 0
Для запуска использую простой скрипт
#!/bin/bash
[ -n "`pgrep apcupsd`" ] && killall apcupsd ;
sleep 5 ;
UPS_DAEMON="/sbin/apcupsd"
for CONF_FILE in /etc/apcupsd/apcupsd*conf
do
$UPS_DAEMON -f $CONF_FILE
echo $UPS_DAEMON -f $CONF_FILE
done
Он запускает демон apcupsd с каждым конфигурационным файлом «apcupsd*conf». Идем в каталог /var/log/apcupsd и изучаем его содержимое, если все прошло успешно, содержимое его должно выглядеть так:
apcupsd-ippon0.events
apcupsd-ippon0.status
apcupsd-ippon1.events
apcupsd-ippon1.status
Из названий понятно что файлы с расширением events отвечает за события демона, аля запуск-остановка и т.д. Для нас больший интерес представляет файлы с расширениями status. Приведу содержимое с пояснениями одного из них. Забегая вперед скажу что внешняя обработка заббих будет брать информацию именно из этих файлов.
APC : 001,031,0762 - номер-версии,количество-строк,количество-байт DATE : 2016-01-19 20:25:01 +0300 - время получения информации от ИБП HOSTNAME : zavdiag - DNS имя сервера VERSION : 3.14.10 (13 September 2011) debian - версия сборки apcupsd UPSNAME : zavdiag - имя из apcupsd.conf CABLE : USB Cable - тип управляющего кабеля DRIVER : USB UPS Driver - имя драйвера UPSMODE : Stand Alone STARTTIME: 2016-01-19 14:40:36 +0300 - Когда стартовал демон apcupsd MODEL : HID UPS - Модель STATUS : ONLINE - текущее состояние (ONLINE, ONBATT, NOBATT и т.д.), извлекается из ИБП LOADPCT : 12.0 Percent Load Capacity - уровень нагрузки в процентах от VA, извлекается из ИБП BCHARGE : 100.0 Percent - процент зарядки батареи извлекается из ИБП TIMELEFT : 62.4 Minutes - предполагаемое время работы на батарее, извлекается из ИБП MBATTCHG : 5 Percent - значение BATTERYLEVEL в apcupsd.conf MINTIMEL : 3 Minutes - значение MINUTES в apcupsd.conf MAXTIME : 0 Seconds - значение TIMEOUT в apcupsd.conf OUTPUTV : 216.0 Volts - выходное напряжение, извлекается из ИБП DWAKE : -01 Seconds - сколько секунд будет ждать UPS после возобновления питания до включения нагрузки, извлекается из ИБП (думаю что отображается неверно) LOTRANS : 176.0 Volts - нижняя граница допустимого напряжения, извлекается из ИБП HITRANS : 264.0 Volts - верхняя граница допустимого напряжения, извлекается из ИБП ALARMDEL : 30 seconds - период задержки подачи сигнала при пропадании питания, извлекается из ИБП LINEFREQ : 50.0 Hz - частота входного напряжения, извлекается из ИБП NUMXFERS : 0 - количество изменений состояния, извлекается из ИБП TONBATT : 0 seconds - время работы от батареи текущее, извлекается из ИБП CUMONBATT: 0 seconds - время работы от батареи суммарное, извлекается из ИБП XOFFBATT : N/A - время последнего перехода на работу с батареи на сеть SELFTEST : NO - результат самотестирование ИБП (OK, BT - мал заряд, BG - перегрузка, NO - не запускался последние 5 минут), извлекается из ИБП STATFLAG : 0x07000008 Status Flag - битовая строка состояния, извлекается из ИБП SERIALNO : S42140618978 - серийный номер ИБП, извлекается из ИБП NOMPOWER : 2700 Watts - номаинальная мощность в Ваттах (активная?), извлекается из ИБП END APC : 2016-01-19 20:25:02 +0300 - время выдачи состояния</blockquote>
Более полную информацию можно посмотреть здесь
Там же можно найти подробности по конфигурации apcupsd.
Редактируем файлы скриптов, вписываем свой адрес электронной почты:
Вкратце опишу назначения скриптов:
changeme — вызывается когда батарея требует замены
commfailure — вызывается когда связь с блоком утеряна
commok — вызывается когда связь с блоком восстановлена
onbattery — вызывается при переходе на питание от бараеи
offbattery — вызывается при переходе с батареи
killpower — вызывается перед выключением
На этом настройка apcupsd закончена. Если в кратце то процесс происходит так: демон опрашивает устройства UPS, вызывает соответствующий скрипт при изменении состояния и формирует файлы состояния. Теперь осталось все это привязать к Zabbix-у.
Единственный логичный способ, на мой взгляд, занести данные в заббих используя внешнюю проверку.
Для этого используем скрипт который будет парсить файл состояния и получать значения заданных параметров. В моем случае и агент и сервер заббикса будут находится на одном компьютере. Агент слушает порт 10050 сервер 10051. Нам необходимо выяснить каталог где рассполагаются файлы внешних проверок. Для этого ищем в файле конфигурации сервера /etc/zabbix/zabbix_server.conf строку ExternalScripts=/usr/lib/zabbix/externalscripts. В этот каталог и ложим файл проверок. Не используйте не вкоем случае в имени файла точки, даже если это bash-скрипт! Сначала я написал скрипт вот такого вида:
#!/bin/bash
if [[ $1 == ippon? ]] && [ -f "/var/log/apcupsd/apcupsd-$1.status" ] ;
then
case $2 in
BCHARGE)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'BCHARGE' | awk '{print $3}'
;;
OUTPUTV)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'OUTPUTV' | awk '{print $3}'
;;
LOADPCT)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'LOADPCT' | awk '{print $3}'
;;
DWAKE)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'DWAKE' | awk '{print $3}'
;;
STATFLAG)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'STATFLAG' | awk '{print $3}'
;;
STATUS)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'STATUS' | awk '{print $3}'
;;
XOFFBATT)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'XOFFBATT' | awk '{print $3}'
;;
TONBATT)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'TONBATT' | awk '{print $3}'
;;
TIMELEFT)
cat /var/log/apcupsd/apcupsd-$1.status | grep 'TIMELEFT' | awk '{print $3}'
;;
esac
fi
В каталоге /etc/zabbix/zabbix_agentd.d создаем файл userparameter_apcupsd.conf с содержимым
UserParameter=apcupsd[*],/usr/lib/zabbix/externalscripts/apcupsd $1 $2
Перезапускаем агента:
$sudo service zabbix-server restart
Однако на оффсайте Zabbix-а есть предупреждение
Не злоупотребляйте внешними проверками! Они могут привести к значительному снижению производительности Zabbix системы.
А поскольку я не только админ, но еще и пописываю, было решено переписать внешнюю проверку на Cи. А кто его знает когда мы в эту производительность упремся.
Создаем файл apcups.c с содержимым:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
char ValueParam[30];
char *GetValue(char *NameVar, char *FileName)
{
FILE *fconfig=fopen(FileName,"r");
char fileline[255];
unsigned char FLAGDDOT=0,FLAGSPACEB=0;
memset(ValueParam,0,sizeof(ValueParam));
while(!feof(fconfig))
{
fgets (fileline, 255, fconfig);
if(strncmp(fileline,NameVar,strlen(NameVar))==0)
{
for(int i=0;i<strlen(fileline);i++)
{
if(fileline[i]!=':' && FLAGDDOT==0) continue;
if(FLAGDDOT==0)
{
FLAGDDOT=1;
continue;
}
if(fileline[i]==' ' && FLAGSPACEB==0) continue;
if(fileline[i]==' ' && FLAGSPACEB==1) break;
if(FLAGSPACEB==0) FLAGSPACEB=1;
ValueParam[strlen(ValueParam)]=fileline[i];
ValueParam[strlen(ValueParam)+1]=0;
}
if(strlen(ValueParam)>0) break;
}
}
fclose(fconfig);
return ValueParam;
}
void main(int argc, char* argv[])
{
//argv[1] - hostname argv[2] - param
char fname[255];
//Проверяем начинается ли имя хоста с "ippon" и предано ли 2 аргумента
if((strncmp(argv[1],"ippon",5)==0) && (argc==3))
{
memset(fname,0,sizeof(fname));
strcpy(fname,"/var/log/apcupsd/apcupsd-");
strcat(fname,argv[1]);
strcat(fname,".status");
//Проверяем есть ли соответствующий конфигурационный файл
// /var/log/apcupsd/apcupsd-ipponX.status
if(access( fname, F_OK ) != -1)
{
puts(GetValue(argv[2],fname));
}
}
return;
}
Компиляцию производим так:
gcc apcupsd.c -o apcupsd -std=c99
Скомпилированный файл ложим в /usr/lib/zabbix/externalscripts.
Всё, осталось только импортировать шаблон для Zabbix-а.
Я не ставил себе цель сделать что то универсальное, как раз наоборот, стремился сделать необходимый минимум.
В шаблоне присутствуют (описание параметров см выше):
Для графиков сделал всего 4 параметра:
заряд батареи, текущая нагрузка, выходное напряжение и остаточное время работы на батареях.
Тригеры не вижу смысла заводить, так как скрипты демона apcupsd сами отсылают уведомление на почту. А телефон с интернетом всегда с собой. На этом все, буду рад ответить на ваши вопросы.
Автор: big-town