Простейшая задача, казалось бы. Однако, я столкнулся с рядом проблем при её решении.
Нужно было мониторить загрузку ядер процессора Intel Core 2 DUO через Zabbix на системе FreeBSD 8.0.
Пробуем через агента:
Создаём Item для ядра 0. Пока нам достаточно получать время простоя:
Configuration → Hosts → Items → Create Item
Host – имя_хоста
Description – cpu0 idle
Type - Zabbix agent
Key – system.cpu.util[0,idle,avg1]
Type of information – Numeric (float)
Use multiplier – No
Update interval (in sec) – 5
Store value – As is
Создаём Item для ядра 1:
Configuration → Hosts → Items → Create Item
Host – имя_хоста
Description – cpu1 idle
Type - Zabbix agent
Key – system.cpu.util[1,idle,avg1]
Type of information – Numeric (float)
Use multiplier – No
Update interval (in sec) – 5
Store value – As is
Создаём график, на котором будут отображаться оба этих значения.
Тестируем (запускаем процесс dd на ядре 0):
# cpuset -c -l 0 dd if=/dev/zero of=/dev/null
top -P показывает правильную информацию - CPU0 загружен на 100%, а CPU1 - почти на 0.
График показывает, что загрузка CPU0 и CPU1 равна (60% процентов)
Ок, делаем вывод, что через system.cpu.util нельзя мониторить загрузку по ядрам.
Пробуем по SNMP. Счётчики hrProcessorLoad и ssCpuRawIdle показывают только общую загрузку процессора.
Жаль, а я так надеялся на ssCpuRawIdle... Тут моё сердце начало чувствовать, что не обойтись без exec в агенте snmp или без UserParameter в агенте Zabbix'a.
До последнего не хотел прибегать к их использованию (по религиозным соображениям), однако пришлось. Поставил из портов утилиту pcpustat.
Запускаем pcpustat:
# pcpustat -w 3 -c 1
cpu 0 cpu 1
us ni sy in id us ni sy in id
5 0 1 0 94 10 0 1 0 89
-w 3 - собирать статистику за 3 секунды
-с 1 - повторить один раз
# pcpustat -w 3 -c 1 -p 1 -i
1
id
98
-p 1 - ядро 1
-i - показывать только idle time
# pcpustat -w 3 -c 1 -p 1 -i -x
1
!id
2
-x - операция (100-idle time) = utilization time
Нам нужно получать только число без "1" и "!id":
# pcpustat -w 3 -c 1 -p 1 -i -x | | grep -A 1 id | grep -v id
2
Добавляем UserParameter в zabbix_agentd.conf:
UserParameter=system.cpu.core1util,pcpustat -w 3 -c 1 -p 1 -i -x | grep -A 1 id | grep -v id
Теперь перед нами стоит вопрос - каким способом получать данные от агента?
Варианты: zabbix agent или zabbix agent (active).
Если выбрать способ zabbix agent, то сервер будет подключаться к агенту и просить отдать данные.
Агент быдет запускать pcpustat -w 3 -c 1 -p 1 -i -x | grep -A 1 id | grep -v id , а сервер будет ждать ответа.
Если мы установили -w 3 в pcpustat, то должны позаботиться о том, чтобы в zabbix_server.conf параметер Timeout
был не меньше 4 секунд. Этот вариант плох тем, что нам нужно контролировать Timeout и мы будем получать данные
с запозданием в 3 секунды.
Если бырать способ zabbix agent (active), то агент будет инициировать подключение к серверу и отдавать данные.
В этом случае описанные выше проблемы решаются сами собой.
При создании item'a указываем update interval = 1 и агент будет отправлять серверу данные каждые 4 секунд (3
секунды он думает сам и через 1 отправляет данные).
Однако, этот способ тоже немного кривой, т.к. втечение каждого update interval мы не мониторим загрузку.
На мой взгляд, самый адекватный выход в данной ситуации - это использовать zabbix trapper.
Создаём item:
Host имя_хоста
Description core1 util
Type Zabbix trapper
Key trapper.core1util
Type of information Numeric (unsigned)
Остальное - по умолчанию
Пишем скрипт на хосте, с которого хотим снимать показания о загрузке процессора:
#!/bin/sh
AGENTD_CONFIG=/usr/local/etc/zabbix/zabbix_agentd.conf
KEY=trapper.core1util
#zabbix_sender -c $AGENTD_CONFIG -k $KEY -o $VALUE
case "$1" in
'start')
echo 'monitoring script started.'
while (true)
do
VALUE=`pcpustat -x -i -w 3 -c 1 -p 1 | grep -A 1 id | grep -v id`
zabbix_sender -c $AGENTD_CONFIG -s $HOSTNAME -k $KEY -o $VALUE
done&
exit 0
;;
'stop')
echo 'monitoring script stopped.'
kill -9 `ps ax | grep zabbix_trap_send.sh | grep -v grep | awk '{print $1}' | tr "\n" " "` 2>/dev/null
exit 0
;;
*)
echo "Usage: $0 { start | stop }"
exit 1
;;
esac
При использовании zabbix trapper, интервал времени, втечение которого мы не снимаем
показания сокращается с 1 секунды (по сравнению с zabbix agent (active)) до тысячной
доли секудны(то есть можно считать до нуля). С помощью утилиты zabbix_sender мы
посылаем серверу сообщения в асинхронном режиме.