null

Мониторинг загрузки ядер на FreeBSD через Zabbix

Простейшая задача, казалось бы. Однако, я столкнулся с рядом проблем при её решении.
Нужно было мониторить загрузку ядер процессора 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 мы
посылаем серверу сообщения в асинхронном режиме.
 

Вперед

О себе

В компании TUNE IT я занимаю должность инженера. В сферу моих профессиональных интересов входят следующие направления:

  • Администрирование UNIX систем (Solaris, Freebsd);
  • Обслуживание серверов и систем хранения данных фирмы Sun Microsystems;
  • Обеспечение безопасности вычислительных систем и сетей;
  • Виртуализация вычислительных инфраструктур.