Set-OPS-Public/roles/serveur_prometheus/templates/prometheus.yml.j2
Daniel Allaire 49ceb81a4d materiel : un catalogue de capteurs, un tableau Grafana, un verdict Icinga
Les hyperviseurs exposaient temperatures, ventilateurs, SMART et usure NVMe sans que rien
les regarde. scripts/materiel.py porte capteurs et seuils ; Grafana en tire le tableau
Materiel, Icinga un service materiel par hyperviseur. Premier verdict : le disque sda de
gandalf (OSD Ceph) a 56 secteurs en attente, stables.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 10:13:43 -04:00

70 lines
3.3 KiB
Django/Jinja

# Gere par Set-OPS (role serveur_prometheus). Ne pas editer a la main.
global:
scrape_interval: {{ serveur_prometheus_intervalle }}
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
- job_name: node
{% if serveur_prometheus_metriques_tls | default(false) %}
scheme: https
tls_config:
ca_file: {{ serveur_prometheus_metriques_ca }}
{% endif %}
static_configs:
{# `intersect` rend un ENSEMBLE : son ordre d'iteration n'est pas stable d'un
processus Python a l'autre. Sans `sort`, ce fichier se rendait differemment a
chaque passage — memes quatorze cibles, ordre different — et Prometheus etait
redemarre pour rien. Trouve par le passage d'idempotence du 2026-08-09.
On trie sur les HOTES : ordre deterministe et lisible par un humain. #}
- targets: {{ (groups.get(serveur_prometheus_groupe_metriques, []) | intersect(groups.get('hotes_actifs', [])) | sort)
| map('extract', hostvars)
| selectattr('ansible_host', 'defined')
| map(attribute='ansible_host')
| map('regex_replace', '$', ':' ~ serveur_prometheus_port_node)
| list | to_json }}
{# --- LES CIBLES QUE LES ROLES DECLARENT (2026-09-14) ---------------------------
Chaque `roles/<role>/meta/metriques.yml` decrit son exportateur ; le nom du DOSSIER
est le nom du GROUPE, donc les cibles sont les hotes actifs de ce groupe.
UN ROLE DECLARE SANS HOTE NE PRODUIT AUCUN JOB. Prometheus n'a pas a porter une cible
qui n'existe pas, et son journal n'a pas a se remplir de refus previsibles.
ORDRE STABLE : `sort` sur les hotes, comme pour `node` juste au-dessus. Sans lui, le
fichier se rend differemment a chaque passage et Prometheus redemarre pour rien —
defaut trouve le 2026-08-09, qu'on ne va pas reintroduire ici. #}
{% for decl in serveur_prometheus_declarations.results | default([]) %}
{% set role = decl.item.path | dirname | dirname | basename %}
{% set meta = decl.content | b64decode | from_yaml %}
{% set expo = meta.exportateur | default(none) %}
{% set cibles = (groups.get(role, []) | intersect(groups.get('hotes_actifs', [])) | sort)
| map('extract', hostvars) | selectattr('ansible_host', 'defined')
| map(attribute='ansible_host')
| map('regex_replace', '$', ':' ~ (expo.port | default(0))) | list %}
{% if expo and cibles %}
- job_name: {{ expo.job }}
static_configs:
- targets: {{ cibles | to_json }}
{% endif %}
{% endfor %}
{# Les cibles ECRITES AU PLAN completent la derivation, elles ne la remplacent pas :
un equipement ou un service tiers n'a aucun role Set-OPS pour le declarer. #}
{% for job in serveur_prometheus_cibles_supplementaires %}
- job_name: {{ job.job }}
static_configs:
{% if job.hotes | default({}) %}
{# UNE CIBLE NOMMEE PAR BLOC : l'etiquette `hote` s'attache a un `static_config`, pas a
une adresse. Les series disent alors « asgard », pas « 192.168.11.41:9100 ». #}
{% for cible in job.cibles %}
- targets: {{ [cible] | to_json }}
labels:
hote: {{ job.hotes[cible] | default(cible) | to_json }}
{% endfor %}
{% else %}
- targets: {{ job.cibles | to_json }}
{% endif %}
{% endfor %}