21 июля 2016

Произвольные метрики в Zabbix из Elasticsearch

На самом деле сказ о том как вытащить произвольные переменные из полей Syslog сообщений обрабатываемых в Elastic.

Под катом я буду получать из логов значение времени обработки запросов(ReqTime) сервером Nginx для произвольного сервера.

Следуя концепции "все данные в одном месте", эти данные будут вытаскиваться в Zabbix.

Дальше эти данные можно удобно визуализировать и настроить, в случае необходимости, оповещения, если метрики выйдут из заданных диапазонов.






Logstash, первым обрабатывающий логи, умеет маршрутизировать их Zabbix. Но такой подход имеет явный недостаток. Если речь идет о нагруженном Nginx, заббикс будет просто завален огромным количеством логов каждого соединения сервера.

В отличии от этого подхода, Elasticsearch имеет удобный REST API, позволяющий получить агрегированные значения нужных полей за требуемый промежуток времени. В моем примере это будет максимальное и минимальное значение ReqTime за 5 минут для сервера 1.example.com.

Итак, на сервере Zabbix создаем скрипт, обертку передающую в Curl параметры и обрабатывающий полученные значения.
touch /usr/lib/zabbix/externalscripts/elastic.sh
chmod +x /usr/lib/zabbix/externalscripts/elastic.sh
Со следующим содержимым:
#!/bin/bash
DAY=`date +%Y.%m.%d`
SERVER=$1
FIELD=$2
AGR=$3

re='^[0-9]+([.][0-9]+)?$'

apivl=`curl -m 28 -s "http://elastic:9200/syslog-${DAY}/_search?q=message:${SERVER}" -d'
{
  "size": 0,
  "aggs": {
    "last_5_mins": {
      "filter": {
        "range": {
          "@timestamp": {
            "gte": "now-5m"
          }
        }
      },
      "aggs": {
        "tps": {
          '$AGR': {
            field: "'$FIELD'"
          }
        }
      }
    }
  }
}' | sed -e 's/[{}]/''/g' | awk -v RS=',"' -F: '/value/ {print $3}'`

if ! [[ $apivl =~ $re ]] ; then
        echo "0"
else
        echo "$apivl"
fi
В настройки агента заббикса на этом сервере добавляем:
UserParameter=elastic.sh[*],/bin/bash /usr/lib/zabbix/externalscripts/elastic.sh $1 $2 $3
И перезагружаем:
#/etc/init.d/zabbix-agent restart
 * Stopping Zabbix agent zabbix_agentd                                                                                       [ OK ] 
 * Starting Zabbix agent zabbix_agentd                                                                                       [ OK ]

В заббиксе создайем айтемы:




 Результат: