feat: unibus_exporter — daemon que sondea /healthz del cluster unibus y empuja estado+posture a VictoriaMetrics
Compone parse_unibus_health + format_prom_exposition + push_prom_remote del registry (grupo fleet-metrics). Un solo exporter scrapea los 3 nodos por IP pública con la CA del cluster; labels node/instance por serie. Config JSON con secretos fuera de argv. Incluye systemd unit y unibus.example.json. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
---
|
||||
name: unibus_exporter
|
||||
lang: go
|
||||
domain: infra
|
||||
version: 0.1.0
|
||||
description: "Exporter del cluster de mensajería unibus: sondea el /healthz de cada nodo por TLS (CA del cluster) en un bucle y empuja a VictoriaMetrics métricas de estado del cluster y posture (up/down, enforce/acl/tls/cluster, store-kv, cluster_size) sin instrumentar el bus."
|
||||
tags: [fleet-metrics, unibus, monitoring, daemon]
|
||||
uses_functions:
|
||||
- parse_unibus_health_go_infra
|
||||
- format_prom_exposition_go_infra
|
||||
- push_prom_remote_go_infra
|
||||
uses_types:
|
||||
- PromSample_go_infra
|
||||
framework: ""
|
||||
entry_point: "main.go"
|
||||
dir_path: "projects/fleet_monitoring/apps/unibus_exporter"
|
||||
repo_url: "https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/dataforge/unibus_exporter"
|
||||
---
|
||||
|
||||
# unibus_exporter
|
||||
|
||||
Daemon que monitoriza el cluster de mensajería **unibus** (NATS + JetStream, desplegado como
|
||||
3 nodos: magnus, homer, datardos) y lo hace visible en Grafana junto al resto de la flota. Es
|
||||
parte del project `fleet_monitoring`.
|
||||
|
||||
No instrumenta el bus: solo **lee** el endpoint público de salud de cada nodo
|
||||
(`GET https://<nodo>:8470/healthz`, verificado con la CA del cluster) y traduce su respuesta a
|
||||
métricas Prometheus que empuja a VictoriaMetrics. Así un único exporter (corriendo en magnus,
|
||||
que alcanza los 3 nodos por IP pública) cubre todo el cluster sin tocar la configuración de los
|
||||
nodos.
|
||||
|
||||
## Qué hace
|
||||
|
||||
Compone tres funciones del registry (grupo `fleet-metrics`), no reimplementa nada:
|
||||
|
||||
1. `parse_unibus_health_go_infra` — convierte el JSON de `/healthz` de un nodo en `[]PromSample`
|
||||
con labels `node`/`instance`.
|
||||
2. `format_prom_exposition_go_infra` — serializa los samples a texto formato Prometheus exposition.
|
||||
3. `push_prom_remote_go_infra` — hace POST del texto a VictoriaMetrics, añadiendo la label común
|
||||
`job=unibus_exporter` vía `extra_label`.
|
||||
|
||||
Como un solo exporter scrapea varios nodos, las labels `node` e `instance` se fijan **por serie**
|
||||
(en el parser) y no vía `extra_label`, que aplicaría un único valor a todo el lote.
|
||||
|
||||
## Métricas que produce
|
||||
|
||||
| Serie | Labels | Significado |
|
||||
|---|---|---|
|
||||
| `unibus_up` | node, instance | 1 si el nodo respondió `/healthz`, 0 si falló el GET/parseo |
|
||||
| `unibus_status_ok` | node, instance | 1 si `status=="ok"` |
|
||||
| `unibus_posture_enforce` | node, instance | posture: enforcement de auth (1/0) |
|
||||
| `unibus_posture_acl` | node, instance | posture: ACL de subjects (1/0) |
|
||||
| `unibus_posture_tls` | node, instance | posture: TLS del transporte (1/0) |
|
||||
| `unibus_posture_cluster` | node, instance | posture: modo cluster activo (1/0) |
|
||||
| `unibus_store_kv` | node, instance | 1 si el backend de store es `kv` (JetStream KV) |
|
||||
| `unibus_scrape_error` | node, instance | 1 si el scrape de ese nodo falló |
|
||||
| `unibus_scrape_duration_seconds` | node, instance | latencia del GET `/healthz` |
|
||||
| `unibus_cluster_size` | (global) | número de nodos configurados (los vivos = `sum(unibus_up)`) |
|
||||
|
||||
## Por qué no lleva el tag `service`
|
||||
|
||||
Es un daemon, pero igual que `metrics_agent` su liveness no se vigila con un health check propio
|
||||
por SSH (modelo `service:`/`services_monitor`): si el exporter cae, las series `unibus_*` se
|
||||
vuelven stale y eso es la señal. Por eso se etiqueta `daemon`.
|
||||
|
||||
## Configuración
|
||||
|
||||
Config por archivo JSON (`-config`). Campos en `unibus.example.json`:
|
||||
|
||||
| campo | descripción | default |
|
||||
|---|---|---|
|
||||
| `nodes[]` | lista de `{name, url}` por nodo (url = `/healthz` completo) | — (obligatorio) |
|
||||
| `ca_cert_path` | PEM de la CA del cluster unibus, para verificar el TLS de cada nodo | — (obligatorio) |
|
||||
| `hub_url` | endpoint de ingesta de VictoriaMetrics (`…/api/v1/import/prometheus`) | — (obligatorio) |
|
||||
| `user` / `pass` | basic-auth del hub (vacío si el hub es local sin auth) | "" |
|
||||
| `interval_sec` | periodo de scrape+push en segundos | 15 |
|
||||
| `timeout_sec` | timeout del GET `/healthz` por nodo | 8 |
|
||||
| `labels` | labels comunes añadidas vía `extra_label` | `{"job":"unibus_exporter"}` |
|
||||
|
||||
Overrides por entorno: `UNIBUS_HUB_URL`, `UNIBUS_USER`, `UNIBUS_PASS`, `UNIBUS_CA_CERT`,
|
||||
`UNIBUS_INTERVAL`. Los secretos viven solo en el archivo de config (chmod 600), nunca en argv.
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```bash
|
||||
cd projects/fleet_monitoring/apps/unibus_exporter
|
||||
go build -o unibus_exporter .
|
||||
|
||||
# Scrape+push único de prueba (lee config y sale)
|
||||
./unibus_exporter -config /etc/unibus-exporter/unibus.json -once
|
||||
|
||||
# Bucle continuo (lo que hace el servicio systemd)
|
||||
./unibus_exporter -config /etc/unibus-exporter/unibus.json
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Despliégalo en una máquina que alcance los 3 nodos del cluster (hoy magnus, por IP pública). No
|
||||
hay que tocar los nodos de unibus: el exporter solo lee su `/healthz`. El dashboard
|
||||
`hub/dashboards/unibus-cluster.json` visualiza estas series.
|
||||
|
||||
## Deploy
|
||||
|
||||
Desde la raíz del project: `./hub/deploy_unibus_exporter.sh magnus om`. Compila el binario, sube
|
||||
binario + CA del cluster a `/opt/unibus-exporter` + `/etc/unibus-exporter`, escribe la config con
|
||||
el endpoint local de VM (`http://127.0.0.1:8428/...`, sin auth porque corre en el hub) e instala
|
||||
el servicio systemd.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- La CA del cluster es **secreta** (gitignored): no se versiona en el repo. El deploy la sube al
|
||||
nodo a `/etc/unibus-exporter/ca.crt` (chmod 600). Localmente vive en
|
||||
`projects/message_bus/apps/unibus/deploy/tls/ca.crt`.
|
||||
- El TLS se verifica **siempre** contra esa CA: una CA equivocada o ausente hace fallar el
|
||||
arranque, no se ignora.
|
||||
- `unibus_up=0` lo emite este exporter (no el parser) cuando el GET falla, para que un nodo caído
|
||||
sea visible en Grafana en vez de simplemente desaparecer.
|
||||
- Métricas profundas de NATS/JetStream (msgs/s, conexiones, RAFT leader por stream, NRestarts) NO
|
||||
las produce: requieren el monitoring embebido de NATS (puerto 8222), hoy cerrado en producción.
|
||||
Ver el report `unibus-grafana-monitoring` para el detalle del gap.
|
||||
Reference in New Issue
Block a user