Бывают случаи, когда требуется собирать несколько значений из одной таблицы или вьюхи. При этом, сам селект долго отрабатывает и грузит сервер. К сожалению, заббикс в текущей реализации не умеет забирать несколько значений из селекта.
Для решения этой проблемы мне видятся два подхода:
- забирать данные скриптом, а потом использовать zabbix-sender
- забирать данные скриптом в файл, а заббикс читает эти данные
Далее я покажу реализацию второго подхода.
- Создаем VIEW на BD. Zabbix не преобразует пустое значение в 0 (когда вью ничего не вернула). Поэтому, надо написать такую вьюху, которая возвращала бы 0 вместо "нет результатов"
Пример:
123456789CREATE OR REPLACE VIEW mon.events_distinct_customer_platform ASWITH event_distinct_customer_platform_a(platform, "COUNT") AS (основной SELECT)SELECT s.platform,COALESCE(( SELECT a."COUNT"FROM event_distinct_customer_platform_a aWHERE a.platform::text = s.platform::text), 0::bigint) AS "COUNT"FROM ( дополнительный SELECT с необходимыми значениями для заббикса) s(platform);
Наша вьюха:
1234567891011121314CREATE OR REPLACE VIEW mon.events_distinct_customer_platform ASWITH event_distinct_customer_platform_a(platform, "COUNT") AS (SELECT ep.value,count(DISTINCT e.customer_id) AS countFROM auth.event eJOIN auth.event_param ep ON e.id = ep.event_idWHERE ep.param::text = 'platform'::text AND e.creation > (now() - '00:01:00'::interval)GROUP BY ep.value)SELECT s.platform,COALESCE(( SELECT a."COUNT"FROM event_distinct_customer_platform_a aWHERE a.platform::text = s.platform::text), 0::bigint) AS "COUNT"FROM ( VALUES ('WEB'::character varying), ('ANDROID'::character varying), ('IOS'::character varying)) s(platform); - на standby сервере DB или ином другом.
1234sudo mkdir /opt/script/sudo chown postgres:zabbix /opt/script/sudo chmod 775 /opt/script/sudo -u zabbix bash - Сохранение пароля подключения к БД. vim /opt/script/.pgpass
1servername-db1:5432:БАЗА:ЛОГИН:ПАРОЛЬ
1chmod 0600 /opt/script/zabbix/.pgpass - Скрипт исполнения запроса. vim /opt/script/zabbix/get_data.sh
get_data.sh
12345678910111213141516171819202122232425#!/bin/bash#Author: CTAPOMAKview="${1}"echo $PATHfunction get_data() {echo $(date "+%s") > /opt/script/zabbix/${view}.lockecho "$(/opt/rh/rh-postgresql95/root/usr/bin/psql -X -A -t -h servername-db1 -d dbname -U dbuser_zabbix -c "select * from MON.${view};")" > /opt/script/zabbix/${view}.stat;rm /opt/script/zabbix/${view}.lock}#если лок существуетif (test -f /opt/script/zabbix/${view}.lock)thendate_now=$(date "+%s")date_stats=$(cat /opt/script/zabbix/${view}.lock)date_rusult=$[$date_now - ${date_stats:-0}]if [ $date_rusult -gt 1200 ]thenget_dataelseecho "work"exitfielseget_datafi
- крипт возвращает возможные значения айтемов. vim /opt/script/zabbix/stat_items.sh
stat_items.sh
123456789101112131415161718192021#!/bin/bash#Author: CTAPOMAK#file_name="/opt/script/zabbix/имявьюхи.stat"file_name="/opt/script/${1}.stat"echo "{\"data\":["text=""while read linedotext="${text}{\"{#SYSTEMNAME}\":\"$(echo $line | awk -F'|' '{ print $1 }')\"},"done <<< "$(cat $file_name)"echo "$( echo "$text" | sed 's/.$//')"echo "]}"#{# "data":[## { "{#SYSTEMNAME}":"ANDROID"},# { "{#SYSTEMNAME}":"WEB"},# { "{#SYSTEMNAME}":"IOS"}## ]#} - crontab -e. Файл кеша именуется название_вьюхи.stat
1234567### global vars for connection to dbPGPASSFILE=/opt/script/zabbix/.pgpass#PATH=$PATH:/opt/rh/rh-postgresql95/root/usr/binLD_LIBRARY_PATH=/opt/rh/rh-postgresql95/root/lib64PGDATA=/var/opt/rh/rh-postgresql95/lib/pgsql/data#название вьюхи* * * * * /opt/script/zabbix/get_data.sh название_вьюхи
- Zabbix. Под каждый сервер создаем свой темплейт с названием Templ_App_SQL_имяПриложения
- идем в Discovery rules и создаем правило. Здесь задается значение переменной, которая будет перебираться для создания item-ов. Например, перемененная {#SYSTEMNAME} = WEB. ANDROID, IOS
Name: events_distinct_customer_platform - по имени вьюхи
Type: Zabbix agent
Key: system.run["sh /opt/script/stat_items.sh events_distinct_customer_platform"]
Update interval (in sec): 3600 - чем больше, тем лучше
Keep lost resources period (in days): 30 - удаление, если не найдено
- внутри этого правила переходим на Item prototypes и создаем прототип элемента данных
Name: events_distinct_customer_platform_{#SYSTEMNAME}
Type: Zabbix agent
Key: system.run["grep -E '^{#SYSTEMNAME}\|' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"]
Update interval (in sec): 60
History storage period (in days): 30
Trend storage period (in days): 365
Applications: название группы элементов данных для вывода в графане
- Trigger prototypes. Для этого типа item-ов создаем два тригера. Первый сравнивает среднее значение за последние 5 минут со средним от средних значений за 5 минут 7, 14, 21, 28 дней назад. Второй сравнивает среднее значение за 5 минут и среднне значение за 5 минут 30 минут назад. Для обоих триггеров задается два порога 9-21 и 21-9
1)Name: EVENTS_distinct_customer_{#SYSTEMNAME}
Expression:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
( ( ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m)} / ( ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,7d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,14d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,21d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,28d)} )/4 ) )>2 or ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m)} / ( ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,7d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,14d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,21d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,28d)} )/4 ) )<0.5 ) and ( ({Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].time(0)}>=90000) and ({Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].time(0)}<=210000) ) ) or ( ( ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m)} / ( ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,7d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,14d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,21d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,28d)} )/4 ) )>4 or ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m)} / ( ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,7d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,14d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,21d)}+ {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,28d)} )/4 ) )<0.25 ) and ( ({Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].time(0)}>210000) and ({Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].time(0)}<90000) ) ) |
Description
Количество уникальных пользователей в онлайне по {#SYSTEMNAME} в сравнении с прошлой неделей выросло или снизилось
в 2 раза (9-21) или
в 4 раза ночью (21-9).
Текущее значение: {ITEM.VALUE}
2)Name: EVENTS_distinct_customer_{#SYSTEMNAME}
Expression:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
( ( ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m)} / {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,30m)} )>2 or ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m)} / {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,30m)} )<0.5 ) and ( ({Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].time(0)}>=90000) and ({Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].time(0)}<=210000) ) ) or ( ( ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m)} / {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,30m)} )>4 or ( {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m)} / {Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].avg(5m,30m)} )<0.25 ) and ( ({Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].time(0)}>210000) and ({Templ_App_SQL:system.run["grep '{#SYSTEMNAME}' /opt/script/events_distinct_customer_platform.stat | awk -F'|' '{ print $2 }'"].time(0)}<90000) ) ) |
Description
Количество уникальных пользователей в онлайне по {#SYSTEMNAME} в сравнении с данными 30 минут назад выросло или снизилось
в 2 раза днем (9-21) или
в 4 раза ночью (21-9).
Текущее значение: {ITEM.VALUE}
Идем в Monitoring - Latest data и проверяем получает ли заббикс данные