Pushgateway - скрапим при помощи Bash
В этой заметке хотелось бы продемонстрировать пример, как можно извлекать данные из командной оболочки (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.
Со своей машины я кидаю запрос:
user@t420:~/Gitlab/test.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
будет равно И тогда алерт будет отправлен.
На этом можно считать задачу решенной.