С помощью утилит OpenHardwareMonitor, LibreHardwareMonitor, hwmonitor (Либо аналогичных программ) какой-то одной или сразу несколько
В предыдущий ветке для 1 программы, более подробно как работает и т.д. Скрипт + Шаблон для Windows LLD Open Hardware Monitor
Изменения:
V3.0 Добавлена информация о железе
V3.1 Добавлено унаследовать родитель для датчиков если он есть
V3.2 Вывод имени материнской платы для всех элементов
V3.3 (разделены процессоры если их больше 1 сделан вывод материнской платы)
V3.4 Добавлено единицы измерения в зависимости от категории датчика
V3.5 Поддержка сразу нескольких программ, Перекодировка Русских слов из windows в utf-8, переменные по умолчанию, фильтра добавляемых элементов в макросах, при необходимости можно задать свой порт в макросе узла.
У hwmonitor я не нашел wmi так что данная программа не работает с zabbix!
Работа через внешнюю проверку , скрипт на заббикс сервере HM.sh
При работе скрипта вся нагрузка выполнения ложится на ресурсы железа Заббикс Сервера!
Скрипт лежит (у вас может быть другой путь) /usr/local/share/zabbix/externalscripts HM.sh
СКАЧАТЬ Изменено 10.11.2021 (Целое число для максимальной температуры)
Требования!
1. На сервере заббикса должен быть установлен zabbix_get, на заббикс агенте разрешено выполнение удаленных команд!
2. На удаленный Хост (узел) который будет мониториться должна(ы) быть запущенна HardwareMonitor виде процесса или службы и Заббикс Агент
3. ВАЖНО!!! между словами в имени должен быть всего 1 пробел в утилите HardwareMonitor (более одного пробела слово будет относится к другому столбцу и все столбцы данной строки сместятся и данные имени элемента будут не верны)
Начиная с версии OpenHardwareMonitor.exe 0.9.5
Приложение перенесено на .NET Framework версии 4.5 (новое минимальное требование). Только для 64 битных систем.
LibreHardwareMonitor зависит от .NET Framework 2.0, 4.5.2, 5.0
Обновление с 0.8.7 до 0.8.8 вводит зависимость от NvAPIWrapper, которая не работает в x86 в среде x64.
ограничение nvapi: https://github.com/falahati/NvAPIWrappe ... cs#L54-L65,
вероятно, не исправимо
HWMonitor и HWMonitor PRO
Версия PRO сканирует скорость сетевого адаптера, тогда как классическая версия - нет.
В остальном две программы имеют одинаковые возможности мониторинга.
Pro версия 30 дней бесплатно, после требует лицензии!
Макросы
Для использования с NAT когда ip один порты различны в узлах
На узле к которому подключен шаблон в разделе макросы {$HOST.PORTS} укажите номер порта который используете, по умолчанию в шаблоне 10050
{$PUTHM} Указать название используемой программы на хосте или сразу несколько через ;
root\OpenHardwareMonitor;root\LibreHardwareMonitor;root\hwmonitor по умолчанию задана OHM
{$FILTRHM} -Какие датчики показывать, по умолчанию все .*
{$HIDEHM} -Какие датчики скрыть из вывода, по умолчанию пропустить все ^$
Clock\|Load\|Control\|Temperature\|Data\|Fan\|Voltage\|Throughput или имена элементов для точного имени ставьте пробел после имени
{$KODR} -кодировка windows cp1251 или cp866 по умолчанию cp866
Системные макросы
{HOST.CONN} - IP DNS Узла
{HOST.HOST} - Имя Узла
Приоритет Макросов Узел - Шаблон - Глобальные , при необходимости задаем макросы свои в узле они будут приоритетнее.
На примере OpenHardwareMonitor
Запрос датчиков WMIC.exe /NAMESPACE:\\root\OpenHardwareMonitor PATH Sensor
Запрос железа WMIC.exe /NAMESPACE:\\root\OpenHardwareMonitor PATH Hardware
Если таблицы с данными есть все ОК!
Идем дальше
На заббикс сервере через команду zabbix_get -s
Запрос всей таблицы (где есть кавычки " ставим до слешь \)
zabbix_get -s 192.168.175.8 -k system.run["WMIC.exe /NAMESPACE:\\\root\OpenHardwareMonitor PATH Sensor"]
Запрос железа
zabbix_get -s 192.168.175.8 -k system.run["WMIC.exe /NAMESPACE:\\\root\OpenHardwareMonitor PATH Hardware"]
Если таблицы с данными есть все ОК!
Идем дальше
Проверяем работу скрипта
Проверка ответа сразу 2х программ
./HM3.5.sh 192.168.175.8 10050 discovery "root\LibreHardwareMonitor;root\OpenHardwareMonitor"
или 3х
./HM3.5.2.sh 192.168.175.8 10050 discovery "root/HWMonitor;root\OpenHardwareMonitor;root\LibreHardwareMonitor" ".*" "^$" cp866 "21Program"
Проверка фильтра выбранных датчиков
./HM3.5.sh 192.168.175.8 10050 discovery "root\LibreHardwareMonitor;root\OpenHardwareMonitor" "Temperature"
Проверка фильтра исключения элементов
./HM3.5.sh 192.168.175.8 10050 discovery "root\LibreHardwareMonitor;root\OpenHardwareMonitor" ".*" "Download Speed"
Кодировка cmd
./HM3.5.sh 192.168.175.8 10050 discovery "root\LibreHardwareMonitor;root\OpenHardwareMonitor" ".*" "^$" cp866 "ИМЯ Узла"
Запрос процессов
./HM3.5.4.sh 192.168.175.8 10050 processes "root/HWMonitor;root\OpenHardwareMonitor;root\LibreHardwareMonitor" ".*" "^$" cp866 "21Program"
Листинг таблицы Инфо
./HM3.5.sh 192.168.175.8 10050 info "root\LibreHardwareMonitor;root\OpenHardwareMonitor" ".*" "^$" cp866 "ИМЯ Узла"
Максимальная температура
./HM3.5.sh 192.168.175.8 10050 maxtemp "root\LibreHardwareMonitor;root\OpenHardwareMonitor" ".*" "^$" cp866 "ИМЯ Узла"
Если получаем данные в ответ все ОК, цепляем шаблон к узлу, прописываем макросы если не обходимо, правило обнаружения проверить сейчас, должны создастся элементы данных.
Clock\Часы в MHz
***Bus Speed частота системной шины, на которой работает процессор
***CPU Core - текущая частота работы ядра процессора
-Load\Загрузка в %
***CPU Total - сумарная Зарузка на процессор всех ядер-------------------------Элемент system.cpu.load[percpu,avg1] Загрузка процессора (1 мин в среднем)
***CPU Core #1 - конкретная Загрузка на 1 ядро------------------------------------Элемент ?
***+Memory - Загрузка(использование оперативной памяти)------------------------Элемент vm.memory.size[pused] Используемая память RAM в%
***+Virtual Memory - Загрузка(использование файла подкачки памяти)-----------Элемент system.swap.size[,pfree] Свободное место подкачки в файле %
***Used Space - Используемое Пространство (занято на) Диске(физически)-----------------Элемент vfs.fs.size[{#FSNAME},pused] Использовано место на диске {#FSNAME} (в процентах) раздельно по C D
***Write Activity - активная запись на диск (Физический для дисков)--------------------------Элемент perf_counter_en[\234({#DISKNUMLET})\204] Общей загруженность записью Физического диска в % {#DISKNUMLET} perf_counter_en[\236({#FSNAME})\204] Общей загруженность записью Логического диска в % {#FSNAME}
***Total Activity - Общая Активность Диска (Физический для дисков)------------------------Элемент perf_counter_en[\234_Tota\204] Общей загруженность записью Физических дисков в % perf_counter_en[\236_Tota\204] Общей загруженность записью Логического диска в % {#FSNAME}
***Network Utilization - Использование Сети (суммарная нагрузка на порт)----Элемент net.if.total[{#IFNAME}] Сумарный сетевой трафик {#IFNAME} не в % , в байтах или пакетах net.if.total[{#IFNAME},packets]
Control\Контроль в %
***Fan Control #1
+ Temperature\Температура в °C
***CPU Core - Текущая температура ядра
***CPU Distance to TjMax - обратная температура от 100 (при 30 °C значит 70 °C) Distance to TJ Max - показывает сколько осталось запаса до критической температуры, при которой процессор начнет уходить в троттлинг (снижать частоту)
-Data\Данные в GB
***Memory Used - Используемая (оперативная) память--------------------------------Элемент vm.memory.size[used] Используемая память RAM
***Memory Available - Доступная (оперативная) память--------------------------------Элемент vm.memory.size[available] Доступная RAM память
***Virtual Memory Used - Используемая Виртуальная Память (файл подкачки)--Элемент system.swap.size[,used] Используется места в файле подкачки
***Virtual Memory Available - Доступная Виртуальная Память (файл подкачки)--Элемент system.swap.size[,free] Свободное место подкачки
***Data Uploaded - Загруженные Данные (Сеть) ----------------------------------------Элемент net.if.out[{#IFNAME}] Исходящий сетевой трафик {#IFNAME}
***Data Downloaded - Загруженные данные (Сеть)--------------------------------------Элемент net.if.in[{#IFNAME}] Входящий сетевой трафик {#IFNAME}
+ Fan\Кулера в RPM
***Fan - Кулер обороты (скорость вращения)
+ Voltage\Напряжение в V
***VBat - Батарейка биос (текущее напряжение, заряд)
***Vcore
***DIMM - питание оперативной память
***+3.3V - Напряжение линии 3В
***+5V - Напряжение линии 5В
***+12V - Напряжение линии 12В
***И другие
-Throughput\Пропускная способность в KB/s
***Upload Speed - Скорость выгрузки отправки-------------Элемент net.if.out[{#IFNAME}] Исходящий сетевой трафик {#IFNAME}
***Download Speed - Скорость (загрузки) скачивания -----Элемент net.if.in[{#IFNAME}] Входящий сетевой трафик {#IFNAME}
Например мы хотим оставить данные
{$FILTRHM} Clock\|Temperature\|Fan\|Voltage
Исключить данные (ещё обратную температуру TjMax)
{$HIDEHM} Load\|Control\|Data\|Throughput\|TjMax
Так же можно Фильтровать данные стандартно Правило обнаружения вкладка Фильтры
Её можно задать в шаблоне
Либо в Узле под конкретный узел создать.
Так же можно создать глобальные регулярные выражения
Администрирование - Общие - Регулярные выражения
Более подробно Низкоуровневое обнаружение
Визуально OpenHardwareMonitor, LibreHardwareMonitor, hwmonitor похожи между собой ШАБЛОН Аппаратное обеспечение LLD V3.5 PORT Windows HardwareMonitor Обычные Элементы Аппаратное обеспечение LLD V3.5 PORT Windows HardwareMonitor Обнаружение датчиков Прототип элемента данных Аппаратное обеспечение LLD V3.5 PORT Windows HardwareMonitor Прототипы триггеров Аппаратное обеспечение Обнаружение процессов HardwareMonitor СКРИПТ HM3.5.4.SH
#2021/09/20 v3.5.4
#При работе скрипта вся нагрузка выполнения ложится на ресурсы железа Заббикс Сервера!
#Скрипт мониторинга для HardwareMonitor с LLD для Zabbix (серверный вариант)
# Автор Мамзиков Артём Андреевич Описание по скрипту Скрипт + Шаблон для Windows LLD Open Hardware Monitor
#Автообнаружение параметров из HardwareMonitor и его разновидностей (OpenHardwareMonitor, LibreHardwareMonitor, hwmonitor)
# Объявим входные переменные(variable) и если входная переменная пустая задаем дефолтные настройки для некоторых переменных
IP=$1
PORT=${2:-10050}
BLOCSCRIPT=$3
PUT="${4:-root\OpenHardwareMonitor}"
FILTR=${5:-.*}
HIDE=${6:-^$}
KODR="${7:-cp866}"
HOSTNAME=$8
# Проверка входных переменных, вывод в лог что пришло с узлов
STV=$(date "+%F %T")
#echo $STV $IP $PORT $BLOCSCRIPT $PUT $FILTR $HIDE $KODR >> HWLog
IFS=$'\n'
SL='\\\'
if [[ $BLOCSCRIPT = "discovery" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Для создания ключа нам надо название ПО
shopt -s nocasematch #shopt - приводим к одному регистру
if [[ ${puti} == *Open* ]]; then Emkey="root"${SL}"OpenHardwareMonitor"
elif [[ ${puti} == *Libre* ]]; then Emkey="root"${SL}"LibreHardwareMonitor"
elif [[ ${puti} == *HWM* ]]; then Emkey="root"${SL}"HMMonitor"
shopt -u nocasematch
else Emkey="${puti}"; fi
get=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8`
# если требуется включение " двойных кавычек, то они должны быть экранированы обратной наклонной чертой \ потому так много слешей верху нужно по сути 2
# Запуск переменной get команды OpenHardwareMonitor |Сетевые карточки могут содержать русское название по этому декодируем из cp866 или cp1251
# Запрос имен и типа железа
gethd=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Hardware"]|iconv -f "${KODR}" -t utf8`
# Оставляем нужные нам столбцы по железу (делаем между ними 2 пробела)
obrtablhd=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $1" "$2" "$4}')
# Пришлось сделать отдельную переменую так как в родитель попадает параметр Процесс ИД когда столбец родитель пустой
# С последним столбцом по железу (делаем между ними 2 пробела)
obrhartabl=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $1" "$2" "$4" "$5" "$6}')
# Выбираем родителя датчика который показывает параметры смотрим 2 и 5 таблицу
tablparent=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $2" "$5}')
# Если ошибка в черную дыру | удаление первой строки шапки таблицы | Поиск строк более чем 2 пробела, за которой следовал не пробел,
# добавил разделители табуляции, обработка первой строки данных | вывод 3 6 и 9 (можно 9 так $(NF-2)но последняя строка с таблицы работает не так как надо) стoлбцов
obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|sed -n '/'$FILTR'/Ip'|sed -e '/'$HIDE'/d'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
# Если нужно не выводить поиск элементов в которых именах присутствует # раскомментировать строку ниже, а выше закомментировать
#obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|sed -E '/#/d'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
# А если нужно выбрать только строки с определёнными параметрами например температуру напряжение
#obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|grep -E 'Temperature|Voltage'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
#Вывод для тестов настроек
#echo "${get}"
#echo "${obrtabl}"
#echo "${obrtablhd}"
#fi
for element in $(echo "${obrtabl}" 2>/dev/null);
# 1 шаг Перебор строк в таблице в переменную element если ошибка отправка в черную дыру
do
# 2 шаг каждый столбец идет для своей переменной
# Получаем Идентификаторы номера ID датчиков первый столбец
InstanceId=`echo "${element}"|awk '{print $1}'`
# Получаем имена датчиков средний 2 столбец самый муторный из-за пробелов)
Name=$(echo "${element}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $2}'|sed 's/[ \t]*$//')
# Получаем категорию/группу датчиков последний столбец
SensorType=`echo "${element}" |awk '{print $(NF)}'`
# Получаем Parent для подстановки имен железа
Parent=`echo "${element}"|awk '{print $(NF-2)}'`
# Добавление проверки по ИД для серверов 2 процессора иначе оба имени попадают в один ответ(
Processid=`echo "${element}"|awk '{print $(NF-1)}'`
# Получаем Тип оборудования работа со 2 таблицей
HardwareType=`echo "${obrhartabl}"|grep -E "${Parent}".*"${Processid}"|awk '{print $1}'`
# Получаем имя железа (NF-1 или $3)
Namehd=$(echo "${obrhartabl}"|grep -E "${Parent}".*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
# Выявляем родителя чипа датчиков если он есть
# Берем со 2 таблицы 2 и 5 столбец (хотя в 5 попадет 6) в сравнении со столбцом-7 1-таблицы получаем ответ 5 столбца 2 таблицы
sopost=`echo "${tablparent}"|grep -E "${Parent}"|awk '{print $2}'`
# Во второй таблице ищем соответствие к имени из параметра выше
roditel=$(echo "${obrtablhd}"|grep -E "${sopost}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $(NF)}'|sed 's/[ \t]*$//')
# Тип родителя
rodtip=`echo "${obrtablhd}"|grep -E "${sopost}"|awk '{print $1}'`
case $SensorType in
*Clock*)
UINTS="MHz"
;;
*Load*|*Control*)
UINTS="%"
;;
*Temperature*)
UINTS="°C"
;;
*Data*)
UINTS="GB"
;;
*Fan*)
UINTS="RPM"
;;
*Voltage*)
UINTS="V"
;;
*Throughput*)
UINTS="KB/s"
;;
esac
# Модель Материнской платы выводить всегда mainboard
#mainboard=$(echo "${obrhartabl}"|grep -E Mainboard.*/mainboard.*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
# если есть родитель в не учитываем материнку выйдет как родитель
if [ -z "${roditel}" ]; then
mainboard=$(echo "${obrhartabl}"|grep -E Mainboard.*/mainboard.*/Motherboard.*/motherboard.*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
else
mainboard=
fi
JSON=$JSON"$SEP\n{\"{#EMKEY}\":\"$Emkey\", \"{#ID}\":\"$InstanceId\", \"{#NAME}\":\"$Name\", \"{#SENSORTYPE}\":\"$SensorType\", \"{#UINTS}\":\"$UINTS\", \"{#HARDTYPE}\":\"$HardwareType\", \"{#HARDNAME}\":\"$Namehd\", \"{#RODITEL}\":\"$roditel\", \"{#RODTIP}\":\"$rodtip\", \"{#MAINBOARD}\":\"$mainboard\"}"
SEP=", "
done
# Проверка на ошибки, так как для 1 узла одновременно могут быть указаны несколько программ одна из них может давать ошибку в этом случае от другой программы JONS не примется, поэтому скрываем ошибки
# Ответы с хоста|Преобразуем в 1 строку|Ищем регуляркой ошибки, если найдено выводим ERROR и убираем из вывода HW с ошибкой. А ошибки отправляем траппером в элемент "Ошибки Правила Обнаружения HM"|Скрыть вывод
check=$(echo "${get}""${gethd}"|tr -d '\r\n'| sed -n 's/No Instance(s) Available.*\|Node.*\|ERROR.*\|Invalid.*\|fatal:.*\|команда не найдена.*/ERROR/Ip')
# Указываем IP или DNS Заббикс сервера, по умолчанию должно работать localhost так как скрипт находится на самом сервере заббикс.
IPZBXSERVER=localhost
# Очистить строки если ошибка в ПО, по имени программы удалим строки из вывода содержащие ее.; отправить траппер с ошибкой.
if [[ ${check} == *ERROR* ]]; then hwnamep=$(echo "${Emkey}"|sed -e 's/^.*\\//g');JSON=$(echo -e $JSON|sed -e '/'$hwnamep.*'/d');zabbix_sender -z $IPZBXSERVER -p 10051 -s "${HOSTNAME}" -k errordiscoveryhm -o ""${hwnamep}" "${get}"" > /dev/null;fi
done
# Выводим результат в json
JSON="["$JSON"\n]"
echo -e "${JSON}"
elif [[ $BLOCSCRIPT = "processes" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Для создания ключа нам нужно название ПО
shopt -s nocasematch #shopt - приводим к одному регистру
if [[ ${puti} == *Open* ]]; then namehw="OpenHardwareMonitor"
elif [[ ${puti} == *Libre* ]]; then namehw="LibreHardwareMonitor"
elif [[ ${puti} == *HWM* ]]; then namehw="HMMonitor";fi
shopt -u nocasematch
# Накопительная переменная для нескольких циклов имен процесса.
HWNAME=$HWNAME"$SEP\n{\"{#NAMEHW}\":\"$namehw\"}"
SEP=", "
done
# Выводим результат
HWNAME="["$HWNAME"\n]"
echo -e "${HWNAME}"
fi
# Получение полной информации всей таблицы ./OHM.sh[{HOST.CONN},info] смысла в этом особого нет конечно, так как данные постоянно меняются смысл например запрашивать раз в сутки весь листинг но пусть будет)
if [[ $BLOCSCRIPT = "info" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
get=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8`
out=$out echo -e "\n${puti}\n""${get}"
done
echo -e "${out}"
elif [[ $BLOCSCRIPT = "maxtemp" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Запрашиваем таблицу|перекодируем|выбираем строки с температурой|показать столбец значения|Исключаем обратную температуру|Вывод только числового значения|Сортировка от меньшего к большему|вывод последней строки
maxtemperature=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8|sed -n '/'Temperature'/Ip'|sed -e '/'TjMax'/d'|awk '{print $(NF-1)}'|sed -E 's/\.[0-9]+|\,[0-9]+//g'|egrep -o '[0-9]+'|sort -n| tail -n1`
# Для нескольких ПО
maxtemp=$maxtemp"\n${maxtemperature}"
done
# Выводим максимальный результат
echo -e "${maxtemp}"|sort -n| tail -n1
fi
Пример Графики
проще на дашборте добавляем График и делаем его по регулярному выражению например * Temperature : CPU *
Либо создаём вручную в узле, если сделать прототипом для каждого элемента будет свой график. Пример последние данные сразу с 2х программ
Если процесс остановился Автоматический запуск Действием (либо перестали идти данные перезапуск)
Перезапуск Процесса HardwareMonitor
A or B or C or D or E or F
Условия
Подпись Имя
A Имя триггера содержит Процесс OpenHardwareMonitor
B Имя триггера содержит Процесс LibreHardwareMonitor
C Имя триггера содержит Процесс HMMonitor Удалить
D Имя триггера содержит Нет Данных HM-LLD-JONS-data
E Имя триггера содержит HighTemp CPU
F Имя триггера содержит ExtremHighTemp CPU Операции
Длительность шага операции по умолчанию 1m
Приостановить операции для подавленных проблем V
1 Выполнить удаленные команды на текущем узле сети Незамедлительно
Шаги 1 1
Тип операции Удаленная команда
Цель Текущий узел сети
Тип пользовательский скрипт
Zabbix Агент
SCHTASKS /End /TN "\{EVENT.TAGS}\Startup"
SCHTASKS /End /TN "{EVENT.TAGS}"
TASKKILL /IM {EVENT.TAGS}.exe /T /F
2 Выполнить удаленные команды на текущем узле сети 00:01:00
SCHTASKS /Run /I /TN "\{EVENT.TAGS}\restart-hm.bat"
SCHTASKS /Run /TN "restart-hm.bat"
3 Выполнить удаленные команды на текущем узле сети 00:02:00
SCHTASKS /Run /I /TN "\{EVENT.TAGS}\restart-hm.bat"
SCHTASKS /Run /TN "restart-hm.bat"
4 Выполнить удаленные команды на текущем узле сети 00:03:00
SCHTASKS /Run /I /TN "\{EVENT.TAGS}\restart-hm.bat"
SCHTASKS /Run /TN "restart-hm.bat"
[
{"{#NAMEHW}":"OpenHardwareMonitor.exe"},
{"{#EMKEY}":"root\OpenHardwareMonitor", "{#ID}":"3872",........
]
Элементы создаются все хорошо но правило обнаружения ругается
Cannot create item: item with the same key "wmi.get[{#EMKEY},SELECT Value FROM Sensor WHERE InstanceId={#ID}]" already exists.
Cannot create item: item with the same key "proc.num[{#NAMEHW}]" already exists.
мол ключ уже есть
Почему сразу на 3х версиях ? Понятно же с 1 что так нельзя) изначально не проверено на узлах переделывался вывод его последовательность, скрытие ошибок и т.п.
Сравнение выводов таблиц и отображение русского названия сетевого адаптера
Open Libre HardwereMonitor Hardware Open Libre HardwereMonitor
3.5.0 - выдает данные, не отправляет и не скрывает ошибки, показывает программы для всех процессов даже если нет данных для них
#2021/09/11 v3.5.0
#При работе скрипта вся нагрузка выполнения ложится на ресурсы железа Заббикс Сервера!
#Скрипт мониторинга для HardwareMonitor с LLD для Zabbix (серверный вариант)
# Автор Мамзиков Артём Андреевич Описание по скрипту Скрипт + Шаблон для Windows LLD Open Hardware Monitor
#Автообнаружение параметров из HardwareMonitor и его разновидностей (OpenHardwareMonitor, LibreHardwareMonitor, hwmonitor)
# Объявим входные переменные(variable) и если входная переменная пустая задаем дефолтные настройки для некоторых переменных
IP=$1
PORT=${2:-10050}
BLOCSCRIPT=$3
PUT="${4:-root\OpenHardwareMonitor}"
FILTR=${5:-.*}
HIDE=${6:-^$}
KODR="${7:-cp866}"
HOSTNAME=$8
# Проверка входных переменных, вывод в лог что пришло с узлов
STV=$(date "+%F %T")
#echo $STV $IP $PORT $BLOCSCRIPT $PUT $FILTR $HIDE $KODR >> HWLog
IFS=$'\n'
SL='\\\'
if [[ $BLOCSCRIPT = "discovery" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Для создания ключа нам надо название ПО
shopt -s nocasematch #shopt - приводим к одному регистру
if [[ ${puti} == *Open* ]]; then Emkey="root\OpenHardwareMonitor"
elif [[ ${puti} == *Libre* ]]; then Emkey="root\LibreHardwareMonitor"
elif [[ ${puti} == *HWM* ]]; then Emkey="root\HMMonitor"
shopt -u nocasematch
else Emkey="${puti}"; fi
get=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8`
# если требуется включение " двойных кавычек, то они должны быть экранированы обратной наклонной чертой \ потому так много слешей верху нужно по сути 2
# Запуск переменной get команды OpenHardwareMonitor |Сетевые карточки могут содержать русское название по этому декодируем из cp866 или cp1251
# Запрос имен и типа железа
gethd=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Hardware"]|iconv -f "${KODR}" -t utf8`
# Оставляем нужные нам слобцы по железу (делаем между ними 2 пробела)
obrtablhd=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $1" "$2" "$4}')
# Пришлось сделать отдельную переменую так как в родитель попадает параметр Процесс ИД когда столбец родитель пустой
# С последним столбцом по железу (делаем между ними 2 пробела)
obrhartabl=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $1" "$2" "$4" "$5" "$6}')
# Выбираем родителя датчика который показывает параметры смотрим 2 и 5 таблицу
tablparent=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $2" "$5}')
# Если ошибка в черную дыру | удаление первой строки шапки таблицы | Поиск строк более чем 2 пробела, за которой следовал не пробел,
# добавил разделители табуляции, обработка первой строки данных | вывод 3 6 и 9 (можно 9 так $(NF-2)но последняя строка с таблицы работает не так как надо) стoлбцов
obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|sed -n '/'$FILTR'/Ip'|sed -e '/'$HIDE'/d'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
# Если нужно не выводить поиск элементов в которых именах присутствует # раскомментировать строку ниже, а выше закомментировать
#obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|sed -E '/#/d'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
# А если нужно выбрать только строки с определеными параметрами например температуру напряжение
#obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|grep -E 'Temperature|Voltage'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
#Вывод для тестов настроек
#echo "${get}"
#echo "${obrtabl}"
#echo "${obrtablhd}"
#fi
for element in $(echo "${obrtabl}" 2>/dev/null);
# 1 шаг Перебор строк в таблице в переменную element если ошибка отправка в черную дыру
do
# 2 шаг каждый столбец идет для своей переменной
# Получаем Идентифика́торы номера ID датчиков первый столбец
InstanceId=`echo "${element}"|awk '{print $1}'`
# Получаем имена датчиков средний 2 столбец самый муторный из-за пробелов)
Name=$(echo "${element}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $2}'|sed 's/[ \t]*$//')
# Получаем категорию/группу датчиков последний столбец
SensorType=`echo "${element}" |awk '{print $(NF)}'`
# Получаем Parent для подстановки имен железа
Parent=`echo "${element}"|awk '{print $(NF-2)}'`
# Добавление проверки по ИД для серверов 2 процессора иначе оба имени попадают в один ответ(
Processid=`echo "${element}"|awk '{print $(NF-1)}'`
# Получаем Тип оборудования работа со 2 таблицей
HardwareType=`echo "${obrhartabl}"|grep -E "${Parent}".*"${Processid}"|awk '{print $1}'`
# Получаем имя железа (NF-1 или $3)
Namehd=$(echo "${obrhartabl}"|grep -E "${Parent}".*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
# Выявляем родителя чипа датчиков если он есть
# Берем со 2 таблицы 2 и 5 столбец (хотя в 5 попадет 6) в сравнении со столбцом-7 1-таблицы получаем ответ 5 столбца 2 таблицы
sopost=`echo "${tablparent}"|grep -E "${Parent}"|awk '{print $2}'`
# Во второй таблице ищем соответсвие к имени из параметра выше
roditel=$(echo "${obrtablhd}"|grep -E "${sopost}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $(NF)}'|sed 's/[ \t]*$//')
# Тип родителя
rodtip=`echo "${obrtablhd}"|grep -E "${sopost}"|awk '{print $1}'`
case $SensorType in
*Clock*)
UINTS="MHz"
;;
*Load*|*Control*)
UINTS="%"
;;
*Temperature*)
UINTS="°C"
;;
*Data*)
UINTS="GB"
;;
*Fan*)
UINTS="RPM"
;;
*Voltage*)
UINTS="V"
;;
*Throughput*)
UINTS="KB/s"
;;
esac
# Модель Материнской платы выволить всегда mainboard
#mainboard=$(echo "${obrhartabl}"|grep -E Mainboard.*/mainboard.*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
# если есть родитель в не учитываем материнку выйдет как родитель
if [ -z "${roditel}" ]; then
mainboard=$(echo "${obrhartabl}"|grep -E Mainboard.*/mainboard.*/Motherboard.*/motherboard.*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
else
mainboard=
fi
JSON=$JSON"$SEP\n{\"{#EMKEY}\":\"$Emkey\", \"{#ID}\":\"$InstanceId\", \"{#NAME}\":\"$Name\", \"{#SENSORTYPE}\":\"$SensorType\", \"{#UINTS}\":\"$UINTS\", \"{#HARDTYPE}\":\"$HardwareType\", \"{#HARDNAME}\":\"$Namehd\", \"{#RODITEL}\":\"$roditel\", \"{#RODTIP}\":\"$rodtip\", \"{#MAINBOARD}\":\"$mainboard\"}"
SEP=", "
done
# От начала строки любые символы допоследнего \ выводим имя процесса и добавляем окончание в конце строки
namehw=$(echo "${Emkey}"|sed -e 's/^.*\\//g; s/$/.exe/')
# Накопительная переменная для нескольки циклов имен, Добавим к выводу имя процесса
HWNAME=$HWNAME"\n{\"{#NAMEHW}\":\"$namehw\"},"
done
# Добавим к выводу имя процесса
JSON=$HWNAME$JSON
# Выводим результат в json data
JSON="["$JSON"\n]"
echo -e $JSON
fi
# Получение полной информации всей таблицы ./OHM.sh[{HOST.CONN},info] смысла в этом особого нет конечно, так как данные постоянно меняются смысл например запрашивать раз в сутки весь листинг но пусть будет)
if [[ $BLOCSCRIPT = "info" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
get=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8`
out=$out echo -e "\n${puti}\n""${get}"
done
echo -e "${out}"
elif [[ $BLOCSCRIPT = "maxtemp" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Запрашиваем таблицу|перекодируем|выбираем строки с температурой|показать столбец значения|Исключаем обратную температуру|Вывод только числового значения|Сортировка от меньшего к большему|вывод последней строки
maxtemperature=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8|sed -n '/'Temperature'/Ip'|sed -e '/'TjMax'/d'|awk '{print $(NF-1)}'|egrep -o '[0-9]+'|sort -n| tail -n1`
# Для нескольких ПО
maxtemp=$maxtemp"\n${maxtemperature}"
done
# Выводим максимальный результат
echo -e "${maxtemp}"|sort -n| tail -n1
fi
HM3.5.0 Если одна из программ не установлена или не работает передаем ошибки и скрываем их из вывода
Пример ошибки
Нет одной программы 1 ошибка 2 нет 3.5.1 - попытка сделать имя процесса данные, снова имя процесса данные для 2 по (не правильно становятся запятые) Скрытие ошибок работает но при условии первая программа в ошибке вторая нет, если на оборот от первой пере затираются пустой переменной при 2 ошибке
#2021/09/19 v3.5.1
#При работе скрипта вся нагрузка выполнения ложится на ресурсы железа Заббикс Сервера!
#Скрипт мониторинга для HardwareMonitor с LLD для Zabbix (серверный вариант)
# Автор Мамзиков Артём Андреевич Описание по скрипту Скрипт + Шаблон для Windows LLD Open Hardware Monitor
#Автообнаружение параметров из HardwareMonitor и его разновидностей (OpenHardwareMonitor, LibreHardwareMonitor, hwmonitor)
# Объявим входные переменные(variable) и если входная переменная пустая задаем дефолтные настройки для некоторых переменных
IP=$1
PORT=${2:-10050}
BLOCSCRIPT=$3
PUT="${4:-root\OpenHardwareMonitor}"
FILTR=${5:-.*}
HIDE=${6:-^$}
KODR="${7:-cp866}"
HOSTNAME=$8
# Проверка входных переменных, вывод в лог что пришло с узлов
STV=$(date "+%F %T")
#echo $STV $IP $PORT $BLOCSCRIPT $PUT $FILTR $HIDE $KODR >> HWLog
IFS=$'\n'
SL='\\\'
if [[ $BLOCSCRIPT = "discovery" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Для создания ключа нам надо название ПО
shopt -s nocasematch #shopt - приводим к одному регистру
if [[ ${puti} == *Open* ]]; then Emkey="root\OpenHardwareMonitor"
elif [[ ${puti} == *Libre* ]]; then Emkey="root\LibreHardwareMonitor"
elif [[ ${puti} == *HWM* ]]; then Emkey="root\HMMonitor"
shopt -u nocasematch
else Emkey="${puti}"; fi
get=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8`
# если требуется включение " двойных кавычек, то они должны быть экранированы обратной наклонной чертой \ потому так много слешей верху нужно по сути 2
# Запуск переменной get команды OpenHardwareMonitor |Сетевые карточки могут содержать русское название по этому декодируем из cp866 или cp1251
# Запрос имен и типа железа
gethd=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Hardware"]|iconv -f "${KODR}" -t utf8`
# Оставляем нужные нам стлобцы по железу (делаем между ними 2 пробела)
obrtablhd=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $1" "$2" "$4}')
# Пришлось сделать отдельную переменую так как в родитель попадает параметр Процесс ИД когда столбец родитель пустой
# С последним столбцом по железу (делаем между ними 2 пробела)
obrhartabl=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $1" "$2" "$4" "$5" "$6}')
# Выбираем родителя датчика который показывает параметры смотрим 2 и 5 таблицу
tablparent=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $2" "$5}')
# Если ошибка в черную дыру | удаление первой строки шапки таблицы | Поиск строк более чем 2 пробела, за которой следовал не пробел,
# добавил разделители табуляции, обработка первой строки данных | вывод 3 6 и 9 (можно 9 так $(NF-2)но последняя строка с таблицы работает не так как надо) стoлбцов
obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|sed -n '/'$FILTR'/Ip'|sed -e '/'$HIDE'/d'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
# Если нужно не выводить поиск элементов в которых именах присутствует # раскомментировать строку ниже, а выше закомментировать
#obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|sed -E '/#/d'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
# А если нужно выбрать только строки с определенными параметрами например температуру напряжение
#obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|grep -E 'Temperature|Voltage'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
#Вывод для тестов настроек
#echo "${get}"
#echo "${obrtabl}"
#echo "${obrtablhd}"
#fi
JSONP=
for element in $(echo "${obrtabl}" 2>/dev/null);
# 1 шаг Перебор строк в таблице в переменную element если ошибка отправка в черную дыру
do
# 2 шаг каждый столбец идет для своей переменной
# Получаем Идентифика́торы номера ID датчиков первый столбец
InstanceId=`echo "${element}"|awk '{print $1}'`
# Получаем имена датчиков средний 2 столбец самый муторный из-за пробелов)
Name=$(echo "${element}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $2}'|sed 's/[ \t]*$//')
# Получаем категорию/группу датчиков последний столбец
SensorType=`echo "${element}" |awk '{print $(NF)}'`
# Получаем Parent для подстановки имен железа
Parent=`echo "${element}"|awk '{print $(NF-2)}'`
# Добавление проверки по ИД для серверов 2 процессора иначе оба имени попадают в один ответ(
Processid=`echo "${element}"|awk '{print $(NF-1)}'`
# Получаем Тип оборудования работа со 2 таблицей
HardwareType=`echo "${obrhartabl}"|grep -E "${Parent}".*"${Processid}"|awk '{print $1}'`
# Получаем имя железа (NF-1 или $3)
Namehd=$(echo "${obrhartabl}"|grep -E "${Parent}".*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
# Выявляем родителя чипа датчиков если он есть
# Берем со 2 таблицы 2 и 5 столбец (хотя в 5 попадет 6) в сравнении со столбцом-7 1-таблицы получаем ответ 5 столбца 2 таблицы
sopost=`echo "${tablparent}"|grep -E "${Parent}"|awk '{print $2}'`
# Во второй таблице ищем соответсвие к имени из параметра выше
roditel=$(echo "${obrtablhd}"|grep -E "${sopost}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $(NF)}'|sed 's/[ \t]*$//')
# Тип родителя
rodtip=`echo "${obrtablhd}"|grep -E "${sopost}"|awk '{print $1}'`
case $SensorType in
*Clock*)
UINTS="MHz"
;;
*Load*|*Control*)
UINTS="%"
;;
*Temperature*)
UINTS="°C"
;;
*Data*)
UINTS="GB"
;;
*Fan*)
UINTS="RPM"
;;
*Voltage*)
UINTS="V"
;;
*Throughput*)
UINTS="KB/s"
;;
esac
# Модель Материнской платы выводить всегда mainboard
#mainboard=$(echo "${obrhartabl}"|grep -E Mainboard.*/mainboard.*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
# если есть родитель в не учитываем материнку выйдет как родитель
if [ -z "${roditel}" ]; then
mainboard=$(echo "${obrhartabl}"|grep -E Mainboard.*/mainboard.*/Motherboard.*/motherboard.*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
else
mainboard=
fi
JSONP=$JSONP"$SEP\n{\"{#EMKEY}\":\"$Emkey\", \"{#ID}\":\"$InstanceId\", \"{#NAME}\":\"$Name\", \"{#SENSORTYPE}\":\"$SensorType\", \"{#UINTS}\":\"$UINTS\", \"{#HARDTYPE}\":\"$HardwareType\", \"{#HARDNAME}\":\"$Namehd\", \"{#RODITEL}\":\"$roditel\", \"{#RODTIP}\":\"$rodtip\", \"{#MAINBOARD}\":\"$mainboard\"}"
SEP=", "
done
# От начала строки любые символы до последнего \ выводим имя процесса и добавляем окончание в конце строки
namehw=$(echo "${Emkey}"|sed -e 's/^.*\\//g; s/$/.exe/')
# Накопительная переменная для нескольких циклов имен, Добавим к выводу имя процесса
HWNAME=$HWNAME"\n{\"{#NAMEHW}\":\"$namehw\"},"$JSONP
# Указываем IP или DNS Заббикс сервера, по умолчанию должно работать localhost так как скрипт находится на самом сервере заббикс.
IPZBXSERVER=localhost
# Проверка на ошибки, так как для 1 узла одновременно могут быть указаны несколько программ одна из них может давать ошибку в этом случае от другой программы JONS не примется, поэтому скрываем ошибки
# Ответы с хоста|Преобразуем в 1 строку|Ищем регуляркой ошибки, если найдено выводим ERROR и обнуляем JONS . А ошибки отправляем траппером в элемент "Ошибки Правила Обнаружения HM"
check=$(echo "${get}""${gethd}"|tr -d '\r\n'| sed -n 's/No Instance(s) Available.*\|Node.*\|ERROR.*\|Invalid.*\|fatal:.*\|команда не найдена.*/ERROR/Ip')
if [[ ${check} == *ERROR* ]]; then JSON=""; HWNAME=""; zabbix_sender -z $IPZBXSERVER -p 10051 -s "${HOSTNAME}" -k folder[errordiscoveryhm] -o "${get}";fi
done
# Добавим к выводу имя процесса
JSON=$HWNAME
# Выводим результат в json data
JSON="["$JSON"\n]"
echo -e "${JSON}"
fi
# Получение полной информации всей таблицы ./OHM.sh[{HOST.CONN},info] смысла в этом особого нет конечно, так как данные постоянно меняются смысл например запрашивать раз в сутки весь листинг но пусть будет)
if [[ $BLOCSCRIPT = "info" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
get=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8`
out=$out echo -e "\n${puti}\n""${get}"
done
echo -e "${out}"
elif [[ $BLOCSCRIPT = "maxtemp" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Запрашиваем таблицу|перекодируем|выбираем строки с температурой|показать столбец значения|Исключаем обратную температуру|Вывод только числового значения|Сортировка от меньшего к большему|вывод последней строки
maxtemperature=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8|sed -n '/'Temperature'/Ip'|sed -e '/'TjMax'/d'|awk '{print $(NF-1)}'|egrep -o '[0-9]+'|sort -n| tail -n1`
# Для нескольких ПО
maxtemp=$maxtemp"\n${maxtemperature}"
done
# Выводим максимальный результат
echo -e "${maxtemp}"|sort -n| tail -n1
fi
#2021/09/11 v3.5.1
#При работе скрипта вся нагрузка выполнения ложится на ресурсы железа Заббикс Сервера!
#Скрипт мониторинга для HardwareMonitor с LLD для Zabbix (серверный вариант)
# Автор Мамзиков Артём Андреевич Описание по скрипту Скрипт + Шаблон для Windows LLD Open Hardware Monitor
#Автообнаружение параметров из HardwareMonitor и его разновидностей (OpenHardwareMonitor, LibreHardwareMonitor, hwmonitor)
# Объявим входные переменные(variable) и если входная переменная пустая задаем дефолтные настройки для некоторых переменных
IP=$1
PORT=${2:-10050}
BLOCSCRIPT=$3
PUT="${4:-root\OpenHardwareMonitor}"
FILTR=${5:-.*}
HIDE=${6:-^$}
KODR="${7:-cp866}"
HOSTNAME=$8
# Проверка входных переменных, вывод в лог что пришло с узлов
STV=$(date "+%F %T")
#echo $STV $IP $PORT $BLOCSCRIPT $PUT $FILTR $HIDE $KODR >> HWLog
IFS=$'\n'
SL='\\\'
if [[ $BLOCSCRIPT = "discovery" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Для создания ключа нам надо название ПО
shopt -s nocasematch #shopt - приводим к одному регистру
if [[ ${puti} == *Open* ]]; then Emkey="root"${SL}"OpenHardwareMonitor"
elif [[ ${puti} == *Libre* ]]; then Emkey="root"${SL}"LibreHardwareMonitor"
elif [[ ${puti} == *HWM* ]]; then Emkey="root"${SL}"HMMonitor"
shopt -u nocasematch
else Emkey="${puti}"; fi
get=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8`
# если требуется включение " двойных кавычек, то они должны быть экранированы обратной наклонной чертой \ потому так много слешей верху нужно по сути 2
# Запуск переменной get команды OpenHardwareMonitor |Сетевые карточки могут содержать русское название по этому декодируем из cp866 или cp1251
# Запрос имен и типа железа
gethd=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Hardware"]|iconv -f "${KODR}" -t utf8`
# Оставляем нужные нам слобцы по железу (делаем между ними 2 пробела)
obrtablhd=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $1" "$2" "$4}')
# Пришлось сделать отдельную переменую так как в родитель попадает параметр Процесс ИД когда столбец родитель пустой
# С последним столбцом по железу (делаем между ними 2 пробела)
obrhartabl=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $1" "$2" "$4" "$5" "$6}')
# Выбираем родителя датчика который показывает параметры смотрим 2 и 5 таблицу
tablparent=$(echo "${gethd}" 2>/dev/null|awk NR\>1|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $2" "$5}')
# Если ошибка в черную дыру | удаление первой строки шапки таблицы | Поиск строк более чем 2 пробела, за которой следовал не пробел,
# добавил разделители табуляции, обработка первой строки данных | вывод 3 6 и 9 (можно 9 так $(NF-2)но последняя строка с таблицы работает не так как надо) стoлбцов
obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|sed -n '/'$FILTR'/Ip'|sed -e '/'$HIDE'/d'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
# Если нужно не выводить поиск элементов в которых именах присутствует # раскомментировать строку ниже, а выше закомментировать
#obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|sed -E '/#/d'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
# А если нужно выбрать только строки с определеными параметрами например температуру напряжение
#obrtabl=$(echo "${get}" 2>/dev/null|awk NR\>1|grep -E 'Temperature|Voltage'|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3" "$6" "$7" "$8" "$9}')
#Вывод для тестов настроек
#echo "${get}"
#echo "${obrtabl}"
#echo "${obrtablhd}"
#fi
for element in $(echo "${obrtabl}" 2>/dev/null);
# 1 шаг Перебор строк в таблице в переменную element если ошибка отправка в черную дыру
do
# 2 шаг каждый столбец идет для своей переменной
# Получаем Идентифика́торы номера ID датчиков первый столбец
InstanceId=`echo "${element}"|awk '{print $1}'`
# Получаем имена датчиков средний 2 столбец самый муторный из-за пробелов)
Name=$(echo "${element}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $2}'|sed 's/[ \t]*$//')
# Получаем категорию/группу датчиков последний столбец
SensorType=`echo "${element}" |awk '{print $(NF)}'`
# Получаем Parent для подстановки имен железа
Parent=`echo "${element}"|awk '{print $(NF-2)}'`
# Добавление проверки по ИД для серверов 2 процессора иначе оба имени попадают в один ответ(
Processid=`echo "${element}"|awk '{print $(NF-1)}'`
# Получаем Тип оборудования работа со 2 таблицей
HardwareType=`echo "${obrhartabl}"|grep -E "${Parent}".*"${Processid}"|awk '{print $1}'`
# Получаем имя железа (NF-1 или $3)
Namehd=$(echo "${obrhartabl}"|grep -E "${Parent}".*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
# Выявляем родителя чипа датчиков если он есть
# Берем со 2 таблицы 2 и 5 столбец (хотя в 5 попадет 6) в сравнении со столбцом-7 1-таблицы получаем ответ 5 столбца 2 таблицы
sopost=`echo "${tablparent}"|grep -E "${Parent}"|awk '{print $2}'`
# Во второй таблице ищем соответсвие к имени из параметра выше
roditel=$(echo "${obrtablhd}"|grep -E "${sopost}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $(NF)}'|sed 's/[ \t]*$//')
# Тип родителя
rodtip=`echo "${obrtablhd}"|grep -E "${sopost}"|awk '{print $1}'`
case $SensorType in
*Clock*)
UINTS="MHz"
;;
*Load*|*Control*)
UINTS="%"
;;
*Temperature*)
UINTS="°C"
;;
*Data*)
UINTS="GB"
;;
*Fan*)
UINTS="RPM"
;;
*Voltage*)
UINTS="V"
;;
*Throughput*)
UINTS="KB/s"
;;
esac
# Модель Материнской платы выволить всегда mainboard
#mainboard=$(echo "${obrhartabl}"|grep -E Mainboard.*/mainboard.*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
# если есть родитель в не учитываем материнку выйдет как родитель
if [ -z "${roditel}" ]; then
mainboard=$(echo "${obrhartabl}"|grep -E Mainboard.*/mainboard.*/Motherboard.*/motherboard.*"${Processid}"|sed -E 's/ ([^ ])/\t\1/g; s/^1/1\t/;'|awk -F\\t '{print $3}'|sed 's/[ \t]*$//')
else
mainboard=
fi
JSON=$JSON"$SEP\n{\"{#EMKEY}\":\"$Emkey\", \"{#ID}\":\"$InstanceId\", \"{#NAME}\":\"$Name\", \"{#SENSORTYPE}\":\"$SensorType\", \"{#UINTS}\":\"$UINTS\", \"{#HARDTYPE}\":\"$HardwareType\", \"{#HARDNAME}\":\"$Namehd\", \"{#RODITEL}\":\"$roditel\", \"{#RODTIP}\":\"$rodtip\", \"{#MAINBOARD}\":\"$mainboard\"}"
SEP=", "
done
# От начала строки любые символы допоследнего \ выводим имя процесса и добавляем окончание в конце строки
namehw=$(echo "${Emkey}"|sed -e 's/^.*\\//g; s/$/.exe/')
# Накопительная переменная для нескольки циклов имен, Добавим к выводу имя процесса
HWNAME=$HWNAME"\n{\"{#NAMEHW}\":\"$namehw\"},"
# Прверка на ошибки, так как для 1 узла одновременно могут быть указаны несколько программ одна из них может давать ошибку в этом случае от другой программы JONS не примется, поэтому скрываем ошибки
# Ответы с хоста|Преобразуем в 1 строку|Ищем регуляркой ошибки, если найдено выводим ERROR и убираем из вывода HW с ошибкой. А ошибки отправляем траппером в элемент "Ошибки Правила Обнаружения HM"|Скрыть вывод
check=$(echo "${get}""${gethd}"|tr -d '\r\n'| sed -n 's/No Instance(s) Available.*\|Node.*\|ERROR.*\|Invalid.*\|fatal:.*\|команда не найдена.*/ERROR/Ip')
# Указывем IP или DNS Заббикс сервера, по умолчанию должно работать localhost так как скрипт находится на самом сервере заббикс.
IPZBXSERVER=localhost
# Очистить строки если ошибка в ПО, по имени программы удалим строки из вывода содержащие ее.; отправить траппер с ошибкой.
if [[ ${check} == *ERROR* ]]; then hwnamep=$(echo "${Emkey}"|sed -e 's/^.*\\//g');JSON=$(echo -e $JSON|sed -e '/'$hwnamep.*'/d');HWNAME=$(echo -e $HWNAME|sed -e '/'$hwnamep.*'/d');zabbix_sender -z $IPZBXSERVER -p 10051 -s "${HOSTNAME}" -k errordiscoveryhm -o ""${namehw}" "${get}"" > /dev/null;fi
done
# Добавим к выводу имя процесса
JSON=$HWNAME$JSON
# Выводим результат в json data
JSON="["$JSON"\n]"
echo -e "${JSON}"
fi
# Получение полной информации всей таблицы ./OHM.sh[{HOST.CONN},info] смысла в этом особого нет конечно, так как данные постоянно меняются смысл например запрашивать раз в сутки весь листинг но пусть будет)
if [[ $BLOCSCRIPT = "info" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
get=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8`
out=$out echo -e "\n${puti}\n""${get}"
done
echo -e "${out}"
elif [[ $BLOCSCRIPT = "maxtemp" ]]
then
# Проверка нескольких путей ПО на 1 хосте, делим через ;
IFS=';' read -ra sumdir < <(echo "${PUT}")
# Печать разделенной строки
for puti in "${sumdir[@]}"
do
# Запрашиваем таблицу|перекодируем|выбираем строки с температурой|показать столбец значения|Исключаем обратную температуру|Вывод только числового значения|Сортировка от меньшего к большему|вывод последней строки
maxtemperature=`zabbix_get -s $IP -p $PORT -k system.run["WMIC.exe /NAMESPACE:"${SL}""${puti}" PATH Sensor"]|iconv -f "${KODR}" -t utf8|sed -n '/'Temperature'/Ip'|sed -e '/'TjMax'/d'|awk '{print $(NF-1)}'|egrep -o '[0-9]+'|sort -n| tail -n1`
# Для нескольких ПО
maxtemp=$maxtemp"\n${maxtemperature}"
done
# Выводим максимальный результат
echo -e "${maxtemp}"|sort -n| tail -n1
fi
3.5.3 - вывод процесса в общий jons по 1 разу на каждый процесс
Cannot create item: item with the same key "proc.num[{#NAMEHW}]" already exists.
Та же ошибка только в профиль и еще то что пустые
Cannot create item: item with the same key "proc.num[]" already exists.
Cannot create item: item with the same key "proc.num[]" already exists.
3.5.4 - отдельное правило обнаружения для процесса и отдельный блок в скрипте