# Logs y métricas

Los logs y las métricas se leen por Workload y se mezclan entre sus unidades, o se acotan a una con `unit_id`. Ambos se pueden leer durante **30 días**, también para unidades retiradas, destruidas o cuyo Workload está detenido.

**curl**

```bash
# newest 200 lines of every unit, then follow
curl -sS -G "$UNITS/logs" -H "$AUTH" --data-urlencode "limit=200" --data-urlencode "search=error"
curl -sS -G "$UNITS/metrics" -H "$AUTH" --data-urlencode "window=1h" --data-urlencode "series=cpu,memory"
```

**TypeScript**

```ts
const logs = await call("GET", `${UNITS}/logs?limit=200&search=error`);
let cursor = logs.body.follow_cursor;
for (;;) {
  const page = await call("GET", `${UNITS}/logs?direction=forward&cursor=${encodeURIComponent(cursor)}`);
  for (const l of page.body.lines) console.log(l);
  cursor = page.body.follow_cursor ?? cursor;
  await new Promise((r) => setTimeout(r, page.body.poll_after_ms ?? 1000));
}
```

**Python**

```python
import time

_, logs = call("GET", f"{UNITS}/logs", params={"limit": 200, "search": "error"})
cursor = logs["follow_cursor"]
while True:
    _, page = call("GET", f"{UNITS}/logs", params={"direction": "forward", "cursor": cursor})
    for line in page["lines"]:
        print(line)
    cursor = page.get("follow_cursor") or cursor
    time.sleep(page.get("poll_after_ms", 1000) / 1000)
```


## Logs

| Parámetro | Significado |
|---|---|
| `unit_id` | una unidad (viva o retirada); sin él, todas las unidades mezcladas por instante |
| `direction` | `backward` (por defecto, las más nuevas primero, así se abre un panel) o `forward` (así se sigue por sondeo) |
| `cursor` | opaco; continúa exactamente, sin duplicados ni huecos |
| `limit`, `from`, `to` | tamaño de página y ventana de tiempo |
| `search` | subcadena sin distinguir mayúsculas |
| `container` | qué contenedor del pod |

`lines` siempre van de la más antigua a la más nueva. Para seguir: lee la primera página hacia atrás, toma `follow_cursor` y sondea `direction=forward&cursor=<follow_cursor>` cada `poll_after_ms`. Las líneas del propio agente de la plataforma están ocultas salvo que las pidas.

Para un socket en vivo en lugar de sondeo, `POST .../units/{unit_id}/logs/stream-ticket` crea un ticket de corta vida para el flujo y `GET .../units/logs/download` exporta un rango como archivo.

## Métricas

`GET .../units/metrics` devuelve CPU, memoria y red sobre una `window` de `1h`, `6h`, `24h`, `7d` o `30d`, siempre en 120 intervalos. `series` es una lista separada por comas de `cpu`, `memory`, `network_in`, `network_out` y `log_lines_archived`. Sin `unit_id`, cada serie tiene una línea agregada y una por cada una de como máximo diez unidades (las más altas), con `omitted_units` para el resto.

`GET .../units/count` es la serie del número de unidades en el tiempo y `GET .../units/{unit_id}/terminations` lista cómo terminaron los contenedores de una unidad.
