Prima di ricominciare il lavoro direi che è necessario scaldarsi un pochino. Ho pensato quindi di implementare un giro (molto tranquillo) di una roba che ho sempre desiderato fare. Monitorare alcuni dei miei servizi “teknoludici” tra cui https://accolli.it.
Lo scopo è molto semplice, vorrei una notifica qualora qualcuno creasse una carta di accollo al fine di capire se mi stanno dossando (non è vero, per quello uso altri strumenti ma mi serve una scusa per impostare il tutto).
Siccome espongo i miei servizi con HaProxy direi che potrei usare le loggate per individuare le chiamate POST che creano le card. Il Grok Exporter è un progetto molto utile: trasforma in metriche per Prometheus il parsing dei log.
Per prima cosa lo installo in /opt/grok e gli do un file di configurazione molto semplice…
global:
config_version: 3
input:
type: file
path: /var/log/haproxy.log
readall: true
imports:
- type: grok_patterns
dir: ./logstash-patterns-core/patterns
metrics:
- type: counter
name: grok_post_cartadiaccollo_lines_total
help: Counter metric example with labels.
match: '.*302.*POST /cartadiaccollo.*'
server:
port: 9144
Poi creo una unit Systemd di tipo service per trattarlo come un servizio Linux (file grok_exporter.service)
[Unit]
Description=Grok Exporter Service
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/opt/grok_exporter
ExecStart=/opt/grok_exporter -config /opt/config.yml
Restart=on-failure
[Install]
WantedBy=multi-user.target
Lo avvio con systemctl start grok_exporter e controllo se il servizio è running.
$ root@ns304365 (~) > systemctl status grok_exporter.service
● grok_exporter.service - Grok Exporter Service
Loaded: loaded (/etc/systemd/system/grok_exporter.service; disabled; preset: enabled)
Active: active (running) since Sun 2024-09-01 08:20:53 UTC; 1 day 10h ago
Main PID: 4039639 (grok_exporter)
Tasks: 13 (limit: 19100)
Memory: 9.4M
CPU: 7min 1.362s
CGroup: /system.slice/grok_exporter.service
└─4039639 /opt/grok_exporter -config /root/grok_exporter/config.yml
Sep 01 08:20:53 ns304365 systemd[1]: Started grok_exporter.service - Grok Exporter Service.
Sep 01 08:20:53 ns304365 grok_exporter[4039639]: Starting server on http://ns304365:9144/metrics
Per provare il suo funzionamento basta un curl verso localhost su porta 9144
$ root@ns304365 (~) > curl http://localhost:9144/metrics -s | grep accollo
grok_exporter_line_processing_errors_total{metric="grok_post_cartadiaccollo_lines_total"} 0
grok_exporter_lines_matching_total{metric="grok_post_cartadiaccollo_lines_total"} 8
grok_exporter_lines_processing_time_microseconds_total{metric="grok_post_cartadiaccollo_lines_total"} 169
# HELP grok_post_cartadiaccollo_lines_total Counter metric example with labels.
# TYPE grok_post_cartadiaccollo_lines_total counter
grok_post_cartadiaccollo_lines_total 8
Al cambiamento di stato, ovvero all’aggiunta di una nuova riga di log in haproxy.log intercettata da Grok, la metrica grok_post_cartadiaccollo_lines_total cambia per cui mi basta confrontarla con quella ottenuta in un controllo precedente.
Non ho voglia di scrivere troppo codice, basteranno un po’ di righe di bash
$ root@ns304365 (~) > cat telegram_notifications/notify.sh
#!/bin/bash
# Set the API token and chat ID
API_TOKEN="***"
CHAT_ID="***"
check_cartadiaccollo=$(curl -s http://localhost:9144/metrics | grep '^grok_post_cartadiaccollo_lines_total\ [0-9]*')
ls check_cartadiaccollo.lock || echo $check_cartadiaccollo > check_cartadiaccollo.lock
check_cartadiaccollo_lock=$(cat check_cartadiaccollo.lock)
while true
do
if [ "$check_cartadiaccollo" != "$check_cartadiaccollo_lock" ]; then
echo "Metrica grok_post_cartadiaccollo_lines_total cambiata, inviare notifica Telegram"
MESSAGE='Warning, a new carta di accollo has just been issued!'
curl -s -X POST https://api.telegram.org/bot$API_TOKEN/sendMessage -d chat_id=$CHAT_ID -d text="$MESSAGE"
echo $check_cartadiaccollo > check_cartadiaccollo.lock
fi
sleep 2
done
A questo punto creo una unit Systemd anche per il mio script bash per gestire il servizio notify_telegram.service
$ root@ns304365 (~) > cat /etc/systemd/system/notify_telegram.service
[Unit]
Description=My Telegram Notifications
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/root/telegram_notifications
ExecStart=/root/telegram_notifications/notify.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
$ root@ns304365 (~) > systemctl status notify_telegram.service
● notify_telegram.service - My Telegram Notifications
Loaded: loaded (/etc/systemd/system/notify_telegram.service; disabled; preset: enabled)
Active: active (running) since Sun 2024-09-01 20:16:28 UTC; 22h ago
Main PID: 376330 (notify.sh)
Tasks: 2 (limit: 19100)
Memory: 1.1M
CPU: 32min 52.345s
CGroup: /system.slice/notify_telegram.service
├─ 376330 /bin/bash /opt/telegram_notifications/notify.sh
└─1255329 sleep 2