Skip to content

Referencia de API — MiniObserv ​

Base URL: http://<host>:<puerto> (predeterminado :8080)


1. Autenticación ​

Las rutas de métricas requieren un token JWT en el encabezado Authorization:

Authorization: Bearer <jwt>

Cómo funciona:

  1. El secreto AGENT_TOKEN (mínimo 16 caracteres) es compartido entre el agente y el servidor.
  2. El agente firma un JWT HS256 con exp = now + 24h usando ese secreto.
  3. El servidor valida la firma, el algoritmo (solo HS256 es aceptado) y la expiración en cada petición.
  4. Si el token es inválido, expirado o ausente, el servidor devuelve 401 Unauthorized.

Las rutas /healthz y /readyz no requieren autenticación.


2. POST /api/v1/metrics ​

Ingesta un batch de métricas recolectadas por el agente.

Autenticación ​

Requerida (Bearer JWT).

Cuerpo de la petición ​

Content-Type: application/json

json
{
  "host": "string",
  "metrics": [
    {
      "time":   "RFC3339",
      "host":   "string",
      "name":   "string",
      "value":  "number",
      "labels": { "clave": "valor" }
    }
  ]
}
CampoTipoObligatorioDescripción
hoststringsíNombre lógico del host origen del batch
metricsarraysíLista de mediciones (1 – 1000 elementos)
metrics[].timeRFC3339síInstante de la medición (con zona horaria)
metrics[].hoststringsíNombre del host (debe coincidir con el campo raíz)
metrics[].namestringsíNombre canónico de la métrica (ver sección 6)
metrics[].valuefloat64síValor numérico finito (no NaN, no ±Inf)
metrics[].labelsobjectnoMetadatos adicionales como pares clave-valor

Respuesta exitosa ​

HTTP 202 Accepted

json
{ "ingested": 7 }

Ejemplo ​

bash
TOKEN="TU_JWT_AQUI"

curl -s -X POST http://localhost:8080/api/v1/metrics \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "host": "servidor-prod-01",
    "metrics": [
      {
        "time": "2026-06-05T12:00:00Z",
        "host": "servidor-prod-01",
        "name": "cpu.usage_pct",
        "value": 45.2,
        "labels": { "core": "total" }
      },
      {
        "time": "2026-06-05T12:00:00Z",
        "host": "servidor-prod-01",
        "name": "mem.used_pct",
        "value": 68.1
      }
    ]
  }'

Respuesta:

json
{ "ingested": 2 }

Validaciones ​

  • metrics no puede estar vacío.
  • El batch no puede superar 1000 métricas.
  • Cada name debe ser uno de los nueve nombres canónicos (ver sección 6).
  • time no puede ser el instante cero.
  • value debe ser un número finito.
  • Las claves y valores de labels no pueden estar vacíos.

3. GET /api/v1/metrics/query ​

Consulta una serie temporal con agregación por bucket de tiempo.

Autenticación ​

Requerida (Bearer JWT).

Parámetros de consulta ​

ParámetroTipoObligatorioPredeterminadoDescripción
hoststringsí—Nombre exacto del host a consultar
namestringsí—Nombre canónico de la métrica (ver sección 6)
fromRFC3339sí—Inicio del rango temporal (inclusive)
toRFC3339sí—Fin del rango temporal (inclusive)
bucketstringno1mGranularidad del bucket: 1m, 5m, 15m, 1h, 1d
aggstringnoavgFunción de agregación: avg, max, min

Respuesta exitosa ​

HTTP 200 OK

json
{
  "host":   "servidor-prod-01",
  "name":   "cpu.usage_pct",
  "bucket": "1m",
  "agg":    "avg",
  "points": [
    { "time": "2026-06-05T12:04:00Z", "value": 45.2 },
    { "time": "2026-06-05T12:03:00Z", "value": 42.8 },
    { "time": "2026-06-05T12:02:00Z", "value": 39.1 }
  ]
}

Los puntos se devuelven en orden descendente (más reciente primero). Si no hay datos en el rango, points es [].

Ejemplos ​

Uso de CPU en los últimos 5 minutos, bucket de 1 minuto:

bash
TOKEN="TU_JWT_AQUI"

curl -s \
  -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8080/api/v1/metrics/query?host=servidor-prod-01&name=cpu.usage_pct&from=2026-06-05T12:00:00Z&to=2026-06-05T12:05:00Z&bucket=1m&agg=avg"

Uso de memoria máximo en la última hora:

bash
curl -s \
  -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8080/api/v1/metrics/query?host=servidor-prod-01&name=mem.used_pct&from=2026-06-05T11:00:00Z&to=2026-06-05T12:00:00Z&bucket=1h&agg=max"

Bytes de red recibidos, bucket de 5 minutos:

bash
curl -s \
  -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8080/api/v1/metrics/query?host=servidor-prod-01&name=net.bytes_in&from=2026-06-05T11:00:00Z&to=2026-06-05T12:00:00Z&bucket=5m&agg=avg"

Restricciones ​

  • El rango from → to no puede superar 30 días.
  • from debe ser anterior a to.
  • bucket debe ser uno de: 1m, 5m, 15m, 1h, 1d.
  • agg debe ser uno de: avg, max, min.

4. GET /api/v1/hosts ​

Devuelve el estado de salud actual de todos los hosts conocidos por el servidor. No requiere autenticación.

El servidor registra la última vez que cada host envió métricas. El estado se deriva del tiempo transcurrido desde entonces:

EstadoCondición
okEl host reportó métricas dentro del período HOST_STALE_AFTER (predeterminado 20 s)
staleSilencioso durante más de HOST_STALE_AFTER pero menos de HOST_DOWN_AFTER
downSilencioso durante más de HOST_DOWN_AFTER (predeterminado 50 s); se ha disparado el webhook host.down

Autenticación ​

No requerida.

Ejemplo ​

bash
curl -s http://localhost:8080/api/v1/hosts | jq .

Respuesta exitosa ​

HTTP 200 OK

json
{
  "hosts": [
    {
      "host": "web-01",
      "status": "ok",
      "last_seen": "2026-06-05T16:42:23Z"
    },
    {
      "host": "web-02",
      "status": "stale",
      "last_seen": "2026-06-05T16:41:58Z"
    },
    {
      "host": "api-01",
      "status": "down",
      "last_seen": "2026-06-05T16:40:10Z"
    }
  ]
}

hosts es un array vacío si ningún agente ha reportado todavía.

Variables de entorno relacionadas ​

VariablePredeterminadoDescripción
HOST_STALE_AFTER20sTiempo tras el cual un host silencioso se considera stale. Acepta duraciones Go.
HOST_DOWN_AFTER50sTiempo tras el cual un host silencioso se considera down y se dispara el webhook host.down.
ALERT_NOTIFICATIONS—Array JSON de objetos webhook que reciben los eventos host.down. Ver getting-started.

6. GET /healthz ​

Sonda de liveness. Verifica que el proceso del servidor está en ejecución.

Autenticación ​

No requerida.

Respuesta ​

HTTP 200 OK — siempre, sin consultar la base de datos.

ok

Cuándo usarla ​

  • Configuración de sondas de liveness en Kubernetes (livenessProbe).
  • Verificación rápida de que el proceso arrancó correctamente.
  • No indica si la base de datos está disponible (para eso, use /readyz).

Ejemplo ​

bash
curl -s http://localhost:8080/healthz
# ok

7. GET /readyz ​

Sonda de readiness. Verifica que el servidor puede atender peticiones y que la conexión con la base de datos funciona.

Autenticación ​

No requerida.

Respuesta exitosa ​

HTTP 200 OK

ok

Respuesta en caso de error ​

HTTP 503 Service Unavailable

json
{ "error": "db unavailable" }

Cuándo usarla ​

  • Configuración de sondas de readiness en Kubernetes (readinessProbe).
  • Verificación post-arranque antes de dirigir tráfico al servidor.
  • Diagnóstico de problemas de conectividad con TimescaleDB.

Ejemplo ​

bash
curl -s http://localhost:8080/readyz
# ok

# Verificar el código de estado HTTP:
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/readyz
# 200

8. GET /metrics ​

Pública — no requiere autenticación. Compatible con cualquier scraper de Prometheus.

Devuelve los valores actuales de todas las métricas de todos los hosts en formato de texto Prometheus (versión 0.0.4). Los nombres de métricas llevan el prefijo miniobserv_ y los puntos se reemplazan por guiones bajos.

Autenticación ​

No requerida.

Petición ​

GET /metrics

Respuesta ​

Content-Type: text/plain; version=0.0.4

# HELP miniobserv_cpu_usage_pct MiniObserv metric: cpu.usage_pct
# TYPE miniobserv_cpu_usage_pct gauge
miniobserv_cpu_usage_pct{host="web-01"} 42.5 1717600943000
miniobserv_cpu_usage_pct{host="web-02"} 71.2 1717600943000

Ejemplo ​

bash
curl http://localhost:8080/metrics

Uso con Prometheus ​

yaml
scrape_configs:
  - job_name: miniobserv
    static_configs:
      - targets: ['tu-host:8080']
    metrics_path: /metrics

Códigos de respuesta ​

CódigoCuerpoSignificado
200 OKFormato texto PrometheusMétricas devueltas para todos los hosts conocidos.

9. Respuestas de error ​

Todas las respuestas de error siguen este formato JSON:

json
{ "error": "descripción del error" }

Códigos de estado ​

CódigoSignificadoCausas típicas
400 Bad RequestPetición mal formadaJSON inválido, campo faltante, nombre de métrica desconocido, batch vacío, batch > 1000, parámetro de query inválido, rango > 30 días
401 UnauthorizedToken ausente o inválidoSin encabezado Authorization, token expirado, firma incorrecta, algoritmo distinto de HS256
500 Internal Server ErrorError interno del servidorFallo en la base de datos al insertar o consultar
503 Service UnavailableBase de datos no disponibleSolo en /readyz; la base de datos no responde al ping

Ejemplos de respuestas de error ​

400 — Nombre de métrica desconocido:

json
{ "error": "metric[0]: unknown metric name \"cpu.load\"" }

400 — Batch excede el límite:

json
{ "error": "batch exceeds maximum size of 1000" }

400 — Parámetro de bucket inválido:

json
{ "error": "invalid bucket \"2m\": must be one of 1m,5m,15m,1h,1d" }

401 — Token ausente:

json
{ "error": "unauthorized" }

400 — Rango temporal inválido:

json
{ "error": "time range must not exceed 30 days" }

10. Referencia de métricas ​

Tabla de nombres canónicos ​

NombreUnidadLabelsEmitido desde
cpu.usage_pct% (0–100)core=total|0|1|…Primer tick
mem.used_pct% (0–100)—Primer tick
mem.used_bytesbytes—Primer tick
mem.total_bytesbytes—Primer tick
disk.used_pct% (0–100)mount=/Primer tick
disk.used_bytesbytesmount=/Primer tick
disk.total_bytesbytesmount=/Primer tick
net.bytes_inbytes (delta)iface=eth0Segundo tick
net.bytes_outbytes (delta)iface=eth0Segundo tick

Notas sobre labels ​

  • cpu.usage_pct: core=total representa el promedio de todos los núcleos; core=0, core=1, etc. representan cada núcleo físico.
  • disk.*: mount contiene el punto de montaje exacto del sistema de archivos (p. ej. /, /data, /home).
  • net.*: iface contiene el nombre de la interfaz de red (p. ej. eth0, ens3, enp3s0). El loopback (lo) siempre se excluye.
  • Las métricas de memoria no tienen labels porque representan el estado global del sistema.

Semántica de net.bytes_in / net.bytes_out ​

Estos valores representan el delta de bytes desde el tick anterior, no el total acumulado. Por eso no se emiten en el primer tick del agente: el primer tick solo registra el estado inicial de los contadores del sistema operativo como referencia para el cálculo siguiente.


11. Límites ​

LímiteValor
Tamaño máximo de batch (POST /api/v1/metrics)1000 métricas
Rango máximo de consulta (GET /api/v1/metrics/query)30 días
Granularidades de bucket disponibles1m, 5m, 15m, 1h, 1d
Funciones de agregación disponiblesavg, max, min
Duración del JWT generado por el agente24 horas
Longitud mínima de AGENT_TOKEN16 caracteres
Algoritmo JWT aceptadoHS256 únicamente

Released under the MIT License.