Gestion des métriques absentes avec Prometheus Pushgateway
Contrairement aux exporters classiques qui exposent des métriques en continu via un modèle pull, Prometheus Pushagteway fonctionne sur un modèle push. Lorsque des tâches éphémères (short-lived jobs) ne poussent pas de données, le Pushgateway n'a aucune connaissance de l'existence du vecteur de surveillance. Cette absence de valeur par défaut complique l'évaluation de l'état de santé des applications, car une métrique manquante ne déclenche pas nécessairement une alerte de type "down" standard.
Configuration de Prometheus
Voici une configuration optimisée pour récupérer les métriques du Pushgateway et des exporters Windows. Le relabeling est utilisé pour extraire et uniformiser les étiquettes (labels), facilitant ainsi les jointures vectorielles lors de l'évaluation des règles.
global:
scrape_interval: 20s
evaluation_interval: 30s
alerting:
alertmanagers:
- static_configs:
- targets: ['127.0.0.1:9093']
rule_files:
- "/etc/prometheus/rules/*.yml"
scrape_configs:
- job_name: 'pushgateway_metrics'
static_configs:
- targets: ['10.0.0.50:9091']
- job_name: 'windows_exporters'
static_configs:
- targets:
- '10.0.1.10:9182'
- '10.0.1.11:9182'
- '10.0.1.12:9182'
relabel_configs:
- source_labels: [__address__]
regex: '([^:]+)(?::\d+)?'
target_label: node_ip
Règles d'alerte
Pour pallier l'absence de métriques par défaut dans le Pushgateway, l'astuce consiste à combiner la métrique poussée avec une métrique toujours présente (comme up) multipliée par zéro. Cela permet de générer un vecteur de valeur nulle lorsque la métrique cible est absente, déclenchant ainsi l'alerte correctement.
groups:
- name: system_and_batch_alerts
rules:
- alert: WindowsExporterDown
expr: up{job="windows_exporters"} == 0
for: 3m
labels:
severity: critical
annotations:
summary: "L'exporter Windows {{ $labels.instance }} est inaccessible."
description: "Le job {{ $labels.job }} sur l'instance {{ $labels.instance }} ne répond plus depuis 3 minutes."
- alert: BatchJobWxAutomationFailed
expr: (batch_job_last_success_timestamp{exported_job="wx_automation_push"} or (up{job="windows_exporters"} * 0)) == 0
for: 3m
labels:
severity: warning
annotations:
summary: "Échec de la tâche automatisée sur {{ $labels.node_ip }}"
description: "La tâche wx_automation_push sur le nœud {{ $labels.node_ip }} n'a pas renvoyé de signal de succès."
Script de poussée des métriques (Python)
Le script suivant illustre comment pousser une métrique de type Gauge vers le Pushgateway pour indiquer la dernière exécution réussie d'une tâche, en utilisant la bibliothèque prometheus_client.
import socket
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway
class MetricsPublisher:
def __init__(self, gateway_url: str, job_name: str):
self.registry = CollectorRegistry()
self.gateway_url = gateway_url
self.job_name = job_name
self.host_ip = socket.gethostbyname(socket.gethostname())
self.common_labels = ['node_ip']
def record_success(self, metric_name: str, metric_help: str) -> None:
gauge = Gauge(
metric_name,
metric_help,
labelnames=self.common_labels,
registry=self.registry
)
gauge.labels(node_ip=self.host_ip).set(1)
def publish(self, metric_name: str, metric_help: str) -> None:
self.record_success(metric_name, metric_help)
push_to_gateway(
self.gateway_url,
job=self.job_name,
registry=self.registry
)
if __name__ == "__main__":
publisher = MetricsPublisher(
gateway_url='10.0.0.50:9091',
job_name='wx_automation_push'
)
publisher.publish(
'batch_job_last_success_timestamp',
'Timestamp of the last successful batch execution'
)
Configuration de l'inhibition des alertes dans Alertmanager
L'inhibition permet de supprimer certaines alertes lorsque d'autres alertes, plus critiques, sont déjà déclenchées pour les mêmes composants. Cela évite les tempêtes d'alertes et réduit la fatigue liée aux notifications. La syntaxe moderne d'Alertmanager utilise source_matchers et target_matchers pour une définition plus flexible.
inhibit_rules:
- source_matchers:
- severity="critical"
target_matchers:
- severity="warning"
equal: ['alertname', 'instance']
Dans cette configuration, lorsqu'une alerte source avec le label severity="critical" est active, elle inhibe toute alerte cible avec severity="warning", à condition que les labels spécifiés dans equal (ici alertname et instance) soient strictement identiques entre les deux alertes.