> For the complete documentation index, see [llms.txt](https://es-kb.topopool.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://es-kb.topopool.com/monitoreo/pool-exporter.md).

# Pool Exporter (Koios → Prometheus)

Los paneles de **Stake Metrics**, **Delegators**, **Blocks**, **Saturation** y **ROA** del dashboard TOPO⚡ usan métricas que no vienen del nodo — son datos de la blockchain que solo están disponibles vía consulta a la API.

Este exporter es un script bash que consulta **Koios** (gratis, sin API key) cada 60 segundos y escribe un archivo `.prom` que node\_exporter lee y sirve junto con las métricas del sistema. Sin puerto extra, sin scrape job extra en Prometheus.

***

## Arquitectura

```
Koios API
    │
    ▼ (cada 60s vía systemd timer)
pool-exporter.sh ──► /var/lib/node_exporter/textfile/pool_metrics.prom
                                    │
                                    ▼ (node_exporter --collector.textfile)
                              Prometheus :9090
                                    │
                                    ▼
                              Grafana dashboard TOPO⚡
```

Las métricas del pool aparecen en el mismo endpoint `:9100/metrics` que ya scrapea Prometheus — sin cambios en `prometheus.yml`.

***

## Dependencias

```bash
# curl y awk vienen de serie en Ubuntu
# jq es el único paquete a instalar
sudo apt install -y jq
```

***

## Instalación

### 1. Habilitar textfile collector en node\_exporter

Editá el servicio de node\_exporter para agregar el flag `--collector.textfile.directory`:

```bash
sudo mkdir -p /var/lib/node_exporter/textfile

# Editar /etc/systemd/system/node_exporter.service
# Agregar la línea al ExecStart:
#   --collector.textfile.directory=/var/lib/node_exporter/textfile
```

El bloque `ExecStart` queda así:

```ini
ExecStart=/usr/local/bin/node_exporter \
  --collector.systemd \
  --collector.processes \
  --web.listen-address=127.0.0.1:9100 \
  --collector.textfile.directory=/var/lib/node_exporter/textfile
```

```bash
sudo systemctl daemon-reload
sudo systemctl restart node_exporter
```

### 2. Instalar el script

```bash
sudo cp pool-exporter.sh /usr/local/bin/pool-exporter.sh
sudo chmod +x /usr/local/bin/pool-exporter.sh
```

El script está en `kb/monitoreo/pool-exporter.sh` de este repositorio.

### 3. Crear el servicio y el timer systemd

Reemplazá `pool1...` con el bech32 ID de tu pool:

```bash
cardano-cli stake-pool id --cold-verification-key-file cold.vkey --output-format bech32
```

Crear el **servicio** (oneshot — se ejecuta y termina):

```bash
sudo tee /etc/systemd/system/pool-exporter.service > /dev/null << 'EOF'
[Unit]
Description=TOPO Pool Metrics — consulta Koios y escribe .prom
After=network-online.target

[Service]
Type=oneshot
User=TU_USUARIO
Environment="POOL_BECH32_ID=pool1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Environment="TEXTFILE_DIR=/var/lib/node_exporter/textfile"
ExecStart=/usr/local/bin/pool-exporter.sh
StandardOutput=journal
StandardError=journal
SyslogIdentifier=pool-exporter
EOF
```

Crear el **timer** (dispara cada 60 segundos):

```bash
sudo tee /etc/systemd/system/pool-exporter.timer > /dev/null << 'EOF'
[Unit]
Description=TOPO Pool Metrics — cada 60 segundos

[Timer]
OnBootSec=30
OnUnitActiveSec=60

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable pool-exporter.timer
sudo systemctl start pool-exporter.timer
```

### 4. Verificar

Ejecutar manualmente la primera vez para confirmar que funciona:

```bash
sudo -u TU_USUARIO POOL_BECH32_ID=pool1xxx \
  TEXTFILE_DIR=/var/lib/node_exporter/textfile \
  /usr/local/bin/pool-exporter.sh
```

Verificar el archivo generado:

```bash
cat /var/lib/node_exporter/textfile/pool_metrics.prom
```

Deberías ver:

```
# HELP saturation Pool saturation ratio 0-1
# TYPE saturation gauge
saturation 0.0023
# HELP delegators Number of delegators
# TYPE delegators gauge
delegators 14
...
```

Verificar que node\_exporter las expone:

```bash
curl -s http://127.0.0.1:9100/metrics | grep -E '^(saturation|delegators|stake|blocks|roa)'
```

{% hint style="info" %}
No hace falta tocar `prometheus.yml`. El job de `node` que ya existe scrapea el `:9100` donde ahora también aparecen las métricas del pool.
{% endhint %}

***

## Variables de entorno

| Variable         | Default                           | Descripción                                 |
| ---------------- | --------------------------------- | ------------------------------------------- |
| `POOL_BECH32_ID` | —                                 | **Requerido.** `pool1...`                   |
| `KOIOS_API`      | `https://api.koios.rest/api/v1`   | Cambiar a `preview.koios.rest` para testnet |
| `TEXTFILE_DIR`   | `/var/lib/node_exporter/textfile` | Directorio que lee node\_exporter           |

***

## Métricas expuestas

| Métrica             | Fuente Koios          | Unidad    |
| ------------------- | --------------------- | --------- |
| `saturation`        | `live_saturation`     | ratio 0–1 |
| `delegators`        | `live_delegators`     | número    |
| `stake`             | `active_stake`        | lovelace  |
| `stake_active`      | `live_stake`          | lovelace  |
| `pledged`           | `live_pledge`         | lovelace  |
| `blocks_lifetime`   | `block_count`         | número    |
| `blocks_epoch`      | `block_cnt` (history) | número    |
| `blocks_est_epoch`  | calculado¹            | número    |
| `roa` / `roa_short` | calculado²            | ratio     |

**¹** `blocks_est_epoch = (active_stake / total_active_stake) × 21600`\
21600 = slots\_per\_epoch × active\_slot\_coefficient = 432000 × 0.05 (mainnet).

**²** `roa = (pool_fees + delegator_rewards) / active_stake × 73`\
73 épocas ≈ 1 año. El ROA sube durante el epoch a medida que se acumulan rewards.

***

## Logs

```bash
journalctl -u pool-exporter.service
# o seguir el timer
systemctl list-timers pool-exporter.timer
```

Si Koios falla (mantenimiento, timeout), el script termina con error, el timer lo reintenta al siguiente ciclo y el `.prom` previo se conserva — Grafana no muestra saltos a cero.
