Привет всем,
В этой заметке хотелось бы показать пример, как можно извлекать данные из командной оболочки (Bash) и отдавать их в Prometheus.
Представим на нас упала таска, по заданию которой требуется извлекать значения из файлов с переменными и слать алерт в мессенджер при случаи изменения этих значений.
Более опытные из нас, наверное пошли бы по пути написания небольшого скрипта, который бы полностью решал бы эту задачу.
В моем же случаи, я преследую интерес реализации этой же задачи более нативным методом. А именно с использованием связки:
*--> Bash --> Pushgateway --> Prometheus
Пропустим установку прометеус, так как на текущем проекте он у меня уже активно используется и установим Pushgateway.
Установка Pushgateway
Идем на github проекта и качаем последний релиз на сервер.
root@monitoring:/tmp# wget https://github.com/prometheus/pushgateway/releases/download/v1.6.0/pushgateway-1.6.0.linux-amd64.tar.gz
Распаковываем полученный архив, бинарь пушгейтвея закидываем в каталог в исполняемым файлам:
root@monitoring:/tmp# tar -zxvf pushgateway-1.6.0.linux-amd64.tar.gz
root@monitoring:/tmp# cp pushgateway-1.6.0.linux-amd64/pushgateway /usr/local/bin/
Запускать будем через системного пользователя, поэтому добавляем нового юзера:
root@monitoring:/tmp# useradd -c "Pushgateway system user" -U --system -s /bin/false pushgateway
Теперь остается написать systemd-юнит, для запуска приложения:
root@monitoring:/tmp# vim /etc/systemd/system/pushgateway.service
---
[Unit]
Description=Prometheus Pushgateway
Wants=network-online.target
After=network-online.target
[Service]
User=pushgateway
Group=pushgateway
Type=simple
ExecStart=/usr/local/bin/pushgateway --web.listen-address=127.0.0.1:9091
[Install]
WantedBy=multi-user.target
Сохраняемся и релодим systemd.
Далее запускаем сервис:
root@monitoring:/tmp# systemctl daemon-reload
root@monitoring:/tmp# systemctl enable --now pushgateway
Если вы читаете это, то возможно уже знаете что у нас есть две модели доставки метрик в prometheus - Pull/Push. По Pull модели прометей работает уже по умолчанию, и этот способ рекомендуется как предпочтительным.
Но бывают ситуации, когда приложение работает не постоянно и в случаи изменения его состояния, требуется отдать какую либо метрику.
Так вот для реализации push модели в prometheus есть некий посредник, который слушает порт и принимает запросы со стороны своих клиентов. А далее prometheus уже традиционным способом спуллит все изменения.
Как вы могли уже догадаться, что этим посредником выступает сервис pushgateway.
Теперь давайте в конфигурации prometheus пропишем новый job для pushgateway:
root@monitoring:/tmp# vim /etc/prometheus/prometheus.yml
---
- job_name: 'Pushgateway'
honor_labels: true
static_configs:
- targets:
- 'localhost:9091'
И перезапускаем прометей:
root@monitoring:/tmp# systemctl restart prometheus
Сервис pushgateway запущен на localhost, проксировать запросы на нему будет через nginx.
root@monitoring:~# vim /etc/nginx/conf.d/pushgateway.conf
---
server {
listen 8080;
allow 10.10.11.0/24;
deny all;
location / {
proxy_pass http://127.0.0.1:9091;
}
}
Далее просто перезапускаем nginx.
Теперь если мы обратимся к серверу через браузер, то обнаружим такой вот ui:
Отправляем данные на Pushgateway
На стороне серверной части все готово, давайте теперь попробуем отправить какую либо метрику через curl.
Со своего ноута я кидаю запрос:
tony@t420:~/Gitlab/nixhub.ru$ echo "simple_metric 1.1" | curl --data-binary @- http://10.8.1.7:8080/metrics/job/test-job/instance/test-instance
Смотрим в webui отображение метрики:
Отлично, наша рандомная метрика отобразилась на push-гейте.
Bash-скрипт и отправка данных
Приступаем к решению основной части нашего задания. Теперь нам требуется написать скриптец, который будет парсить определенные параметры из файла и отправлять из на pushgateway.
Собственно сам скриптец:
#!/bin/bash
SEARCH_PATH=$1
RESULT=$(grep -E "define\('MAINTENANCE_PROCESS', .*?\)" $SEARCH_PATH | grep -oP '\(\K[^\)]+' | sed -e "s/'//g" | sed -e "s/,//g" | awk '{print $2}')
if [ "$RESULT" == "true" ]; then
echo "maintenance_plan_check 1" | curl --data-binary @- http://10.0.1.253:8080/metrics/job/maintenance_plan/instance/$(hostname)
else
echo "maintenance_plan_check 0" | curl --data-binary @- http://10.0.1.253:8080/metrics/job/maintenance_plan/instance/$(hostname)
fi
Этот скриптец через grep
парсит нужную мне переменную из файла, далее выдергивает из этой переменной ее значение.
Ну и затем выполняется условие, результатом которого отправляется целочисленное значение 0/1.
Данный скрипт, по сути описательный. И не стоит его воспринимать, как что то более чем пример. =)
Можем запустить несколько раз сценарий, что бы проверить отображение данных в прометеус. Затем я этом скриптец ставлю в крон выполнение каждые 5-7 минут:
root@tomita-u20-trunk:~# vi /etc/crontab
---
*/5 * * * * root bash maintance_notify.sh /path/to/file/conf.php
Далее идем в графану, что бы просмотреть данные. В графане через эксплорер метрик выдергиваем нашу метрику:
Обратите внимание на значение полей job
, instance
- они у меня прописаны от балды. В реально же жизни стоит подойти к этом серьезнее.
Отправка нотификакий
Как научить прометеус отправлять уведомления я показывал в прошлых заметках. В этом поинте просто добавим новое правило алертинга уже к существующим. Все правила у меня описаны в конфигурационном файле - alerts.yml
. Открываем его, и в конце добавляем:
root@monitoring:~# vi /etc/prometheus/alerts.yml
---
- alert: Maintenance plan enabled
expr: maintenance_plan_check == 1
for: 3m
labels:
severity: "warning"
annotations:
summary:
"Maintenance plan was been enabled on {{ $labels.instance }}."
Это правило сработает, если значение метрики maintenance_plan_check
будет равно 1. И тогда алерт будет отправлен.
На этом можно считать задачку решенной. =)