Интеграция WCS в Zabbix¶
Zabbix - система мониторинга с открытым исходным кодом под лицензией GPL v2. Для передачи параметров работы WCS в Zabbix используется набор скриптов, запускаемых Zabbix агентом на наблюдаемом сервере
В данном разделе мы не будем останавливаться на получении информации о системе, ограничиваясь только метриками WCS.
Общие сведения о настройке Zabbix агента¶
Файлы конфигурации параметров для передачи на Zabbix сервер мониторинга располагаются в каталоге /etc/zabbix/zabbix_agent.d
.
Файлы скриптов для сбора метрик раcполагаются в каталоге /etc/zabbix/scripts.d
.
Основные параметры работы WCS¶
Конфигурация¶
Основные параметры работы WCS перечисляются в файле webcallserver.conf
UserParameter=wcs.all,/etc/zabbix/scripts.d/get_stat.py
UserParameter=tcp.all,/etc/zabbix/scripts.d/tcp_status.sh
UserParameter=gc.type_gc,/etc/zabbix/scripts.d/gc.sh type_gc
UserParameter=gc.heap_size,/etc/zabbix/scripts.d/gc.sh heap_size
UserParameter=gc.used_mark_start,/etc/zabbix/scripts.d/gc.sh used_mark_start
UserParameter=gc.used_relocate_end,/etc/zabbix/scripts.d/gc.sh used_relocate_end
UserParameter=gc.pause_sum,/etc/zabbix/scripts.d/gc.sh pause_sum
UserParameter=websocket.check,/etc/zabbix/scripts.d/websocket_check.sh
UserParameter=wcs.check,/etc/zabbix/scripts.d/wcs_check.sh
Здесь
wcs.all
- параметры статистики WCStcp.all
- статистика TCP соединенийgc.type_gc
- тип сборщика мусора (GC)gc.heap_size
- текущий размер Java heapgc.used_mark_start
- используемый объем Java heap на момент начала работы GCgc.used_relocate_end
- используемый объем Java heap на момент окончания работы GCgc.pause_sum
- длительность работы GC (в это время приостанавливается работа JVM)websocket.check
- проверка доступности WCS по Websocketwcs.check
- проверка наличия процесса WCS в списке процессов узла
Скрипты¶
Получение параметров статистики¶
Параметры статистики собирает скрипт get_stat.py
get_stat.py
#!/usr/bin/env python
import json,requests,socket
from pyzabbix import ZabbixSender, ZabbixMetric
sender_host = socket.gethostname()
r = requests.get("http://localhost:8081/?action=stat")
res = r.text.split("\n")
sender = ZabbixSender('192.168.1.179',use_config=True,chunk_size=250)
metrics = []
for item in res:
if not item.startswith("---") and item != "":
key = item.split("=")[0]
value = item.split("=")[1]
if key.startswith("native_resources"):
pass
else:
m = ZabbixMetric(sender_host, 'wcs[' + key + ']', value)
metrics.append(m)
sender.send(metrics)
print(1)
Скрипт разбирает страницу статистики http://localhost:8081/?action=stat
, и отправляет параметры на Zabbix сервер по указанному в скрипте IP адресу, кроме раздела
native_resources
На стороне Zabbix к параметрам необходимо обращаться следующим образом:
Получение статистики TCP соединений¶
Статистику соединений собирает скрипт tcp_status.sh
tcp_status.sh
#!/bin/bash
HOST=`/bin/hostname`
/usr/sbin/ss -ant | awk "{if (NR>1) {state[\$1]++}} END {host = \"${HOST}\"; \
for (i in state) {s=i; \
sub (/ESTAB/, \"establ\", s); sub (/LISTEN/, \"listen\", s); sub (/SYN-SENT/, \"synsent\", s); \
sub (/SYN-RECV/, \"synrecv\", s); sub (/FIN-WAIT-1/, \"finw1\", s); sub (/FIN-WAIT-2/, \"finw2\", s); \
sub (/CLOSE-WAIT/, \"closew\", s); sub (/TIME-WAIT/, \"timew\", s); print host, \"tcp.\"s, state[i]}}" \
| /usr/bin/zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -s ${HOST} --port '10051' -i - >/dev/null 2>&1
echo "1"
exit 0
Скрипт собирает текущее состояние TCP соединений и отправляет на Zabbix сервер
Получение статистики сборки мусора (GC)¶
Статистику работы сборщика мусора (GC) JVM собирает скрипт gc.sh
gc.sh
#!/bin/bash
TYPE=$1
WCS_HOME="/usr/local/FlashphonerWebCallServer"
LAST_LOG=$(ls -t ${WCS_HOME}/logs/ | grep gc-core | head -1)
LOG="${WCS_HOME}/logs/${LAST_LOG}"
JAVA_VER=$(java -version 2>&1 | head -n 1 | awk -F '"' '{print $2}')
TYPE_GC="$(grep -Pv '^(#|$)' ${WCS_HOME}/conf/wcs-core.properties | grep -oE 'ConcMarkSweepGC|ZGC')"
if [[ -n "TYPE_GC" ]]; then
if [[ $TYPE == "type_gc" ]]; then
echo $TYPE_GC
fi
else
echo "Garbage Сollector configuration not found in WCS core.properties"
exit 1
fi
# Used OpenJDK 1.x or Java x; GC - ConcMarkSweepGC (only)
if [[ $JAVA_VER != "1"[0-9]* ]]; then
# 2019-08-29T03:48:51.481+0700: 153426.640: [GC (Allocation Failure) 2019-08-29T03:48:51.481+0700: 153426.640: [ParNew: 34153K->384K(38080K), 0.0045083 secs] 52756K->18988K(122752K), 0.0047446 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
if [[ $TYPE == "heap_size" ]]; then
grep 'Allocation Failure' $LOG | tail -1 | awk -F'->' '{print $3}' | sed -rn 's/([0-9]+)K\(([0-9]+)K\), ([0-9]+.[0-9]+).*/\2/p' | awk '{printf "%i\n", $1 * 1024}'
elif [[ $TYPE == "used_mark_start" ]]; then
grep 'Allocation Failure' $LOG | tail -1 | awk -F'->' '{print $2}' | sed -rn 's/.* ([0-9]+)K$/\1/p' | awk '{printf "%i\n", $1 * 1024}'
elif [[ $TYPE == "used_relocate_end" ]]; then
grep 'Allocation Failure' $LOG | tail -1 | awk -F'->' '{print $3}' | sed -rn 's/([0-9]+)K\(([0-9]+)K\), ([0-9]+.[0-9]+).*/\1/p' | awk '{printf "%i\n", $1 * 1024}'
elif [[ $TYPE == "pause_sum" ]]; then
grep 'Allocation Failure' $LOG | tail -1 | awk -F'->' '{print $3}' | sed -rn 's/([0-9]+)K\(([0-9]+)K\), ([0-9]+.[0-9]+).*/\3/p' | tr , . | awk '{printf "%f\n", $1 * 1000 }'
fi
# Used OpenJDK 1x or Java 1x; GC - ConcMarkSweepGC, ZGC
elif [[ $JAVA_VER == "1"[0-9]* ]]; then
if [[ $TYPE_GC == "ConcMarkSweepGC" ]]; then
# [26002.922s][info][gc] GC(133) Pause Young (Allocation Failure) 101M->21M(1014M) 4.239ms
if [[ $TYPE == "heap_size" ]]; then
grep 'Allocation Failure' $LOG | tail -1 | awk '{print $7}' | awk -F'->' '{print $2}' | sed -rn 's/[0-9]+M\(([0-9]+)M\).*/\1/p' | awk '{printf "%i\n", $1 * 1024 * 1024}'
elif [[ $TYPE == "used_mark_start" ]]; then
grep 'Allocation Failure' $LOG | tail -1 | awk '{print $7}' | sed -rn 's/([0-9]+).*/\1/p' | awk '{printf "%i\n", $1 * 1024 * 1024}'
elif [[ $TYPE == "used_relocate_end" ]]; then
grep 'Allocation Failure' $LOG | tail -1 | awk '{print $7}' | awk -F'->' '{print $2}' | sed -rn 's/([0-9]+).*/\1/p' | awk '{printf "%i\n", $1 * 1024 * 1024}'
elif [[ $TYPE == "pause_sum" ]]; then
grep 'Allocation Failure' $LOG | tail -1 | awk '{print $8}' | sed 's/ms$//'
fi
fi
if [[ $TYPE_GC == "ZGC" ]]; then
# [6.960s][info][gc,heap ] GC(1) Capacity: 4096M (100%) 4096M (100%) 4096M (100%) 4096M (100%) 4096M (100%) 4096M (100%)
if [[ $TYPE == "heap_size" ]]; then
grep 'GC(.*)*Capacity' $LOG | tail -1 | awk -F 'Capacity:' '{print $2}' | sed -rn 's/^[ ]*([0-9]+).*/\1/p' | awk '{printf "%i\n", $1 * 1024 * 1024}'
# 6.960s][info][gc ] GC(1) Garbage Collection (Metadata GC Threshold) 186M(5%)->70M(2%)
elif [[ $TYPE == "used_mark_start" ]]; then
grep 'Garbage Collection (.*) ' $LOG | tail -1 | awk -F 'Allocation Rate)|Proactive)|Warmup)|Threshold)' '{print $2}' | sed 's/^ *\([0-9]*\).*/\1/' | awk '{printf "%i\n", $1 * 1024 * 1024}'
elif [[ $TYPE == "used_relocate_end" ]]; then
grep 'Garbage Collection (.*) ' $LOG | tail -1 | awk -F 'Allocation Rate)|Proactive)|Warmup)|Threshold)' '{print $2}' | awk -F'->' '{print $2}' | sed -rn 's/([0-9]+).*/\1/p' | awk '{printf "%i\n", $1 * 1024 * 1024}'
elif [[ $TYPE == "pause_mark_start" ]]; then
grep '.*GC.*Pause Mark Start' $LOG | tail -1 | awk -F 'Pause Mark Start ' '{print $2}' | sed 's/ms$//'
elif [[ $TYPE == "pause_mark_end" ]]; then
grep '.*GC.*Pause Mark End' $LOG | tail -1 | awk -F 'Pause Mark End ' '{print $2}' | sed 's/ms$//'
elif [[ $TYPE == "pause_relocate_start" ]]; then
grep '.*GC.*Pause Relocate Start' $LOG | tail -1 | awk -F 'Pause Relocate Start ' '{print $2}' | sed 's/ms$//'
elif [[ $TYPE == "pause_sum" ]]; then
grep '.*GC.*Pause' $LOG | awk -F 'Pause Mark Start|End|Relocate Start' '{print $2}' | tail -3 | sed 's/ms$//' | awk '{a=$1; getline;b=$1;getline;c=$1;getline;t=a+b+c;print t}'
fi
fi
fi
Скрипт возвращает один из следующих параметров:
gc.type_gc
- тип сборщика мусора (GC)gc.heap_size
- текущий размер Java heapgc.used_mark_start
- используемый объем Java heap на момент начала работы GCgc.used_relocate_end
- используемый объем Java heap на момент окончания работы GCgc.pause_sum
- длительность работы GC (в это время приостанавливается работа JVM)
Zabbix agent сам отправляет параметр на Zabbix сервер
Проверка доступности WCS по Websocket¶
Доступность сервера по Websocket определяет скрипт websocket_check.sh
websocket_check.sh
#!/bin/bash
WCS_HOME="/usr/local/FlashphonerWebCallServer"
WSS_ADDRESS="$(grep -Pv '^(#|$)' ${WCS_HOME}/conf/flashphoner.properties | grep -E 'wss.address' | awk -F '=' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')"
[ -z $WSS_ADDRESS ] && WSS_ADDRESS='0.0.0.0'
WSS_PORT="$(grep -Pv '^(#|$)' ${WCS_HOME}/conf/flashphoner.properties | grep -E 'wss.port' | awk -F '=' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')"
[ -z $WSS_PORT ] && WSS_PORT='8443'
curl --connect-timeout 30 --insecure --silent --include \
--no-buffer \
--header "Connection: Upgrade" \
--header "Upgrade: websocket" \
--header "Host: $WSS_ADDRESS:$WSS_PORT" \
--header "Origin: https://$WSS_ADDRESS:$WSS_PORT" \
--header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \
--header "Sec-WebSocket-Version: 13" \
https://$WSS_ADDRESS:$WSS_PORT/ | grep -q "HTTP/1.1" && [[ $? == 0 ]] && echo '1' || echo '0'
Скрипт возвращает одно из следующих значений:
1
- WCS отвечает по Websocket0
- WCS не отвечает по Websocket
Zabbix agent сам отправляет параметр на Zabbix сервер
Проверка наличия WCS в списке процессов¶
Наличие WCS в списке процессов определяет скрипт wcs_check.sh
wcs_check.sh
Скрипт возвращает одно из следующих значений:
1
- WCS есть в списке процессов на сервере0
- WCS нет в списке процессов на узле
Zabbix agent сам отправляет параметр на Zabbix сервер
Пример шаблона Zabbix для получения данных от агента¶
Пример шаблона Zabbix для получения данных от агента на WCS сервере можно скачать здесь: zbx_export_templates.xml