Las rutas de unidades las usa la consola y están marcadas como solo consola en la referencia de la API. Aceptan tu token de sesión o un token de acceso personal.
Las líneas más nuevas
Sin parámetros obtienes las 500 líneas más nuevas de todas las unidades juntas. Dentro de la página, las líneas llegan de la más antigua a la más nueva.
const base = `/projects/${projectId}/service-instances/${serviceId}/units/logs`;const page = await api("GET", `${base}?limit=100`);for (const l of page.lines) console.log(l.at, `u${l.unit_ordinal}`, l.text);console.log(page.coverage);
Code
base = f"/projects/{project_id}/service-instances/{service_id}/units/logs"page = api("GET", base, limit=100)for l in page["lines"]: print(l["at"], f"u{l['unit_ordinal']}", l["text"])print(page["coverage"])
Retroceder
next_cursor indica dónde continuar en la dirección en que lees. Devuélvelo exactamente como lo recibiste. Es null cuando se agotan los 30 días de retención.
Code
let cursor: string | null = null;for (let i = 0; i < 5; i++) { const q = new URLSearchParams({ limit: "500", ...(cursor ? { cursor } : {}) }); const p = await api("GET", `${base}?${q}`); for (const l of p.lines) console.log(l.at, l.text); cursor = p.next_cursor; if (!cursor) break;}
Code
cursor = Nonefor _ in range(5): p = api("GET", base, limit=500, **({"cursor": cursor} if cursor else {})) for l in p["lines"]: print(l["at"], l["text"]) cursor = p["next_cursor"] if not cursor: break
let follow: string | null = (await api("GET", `${base}?limit=20`)).follow_cursor;for (;;) { const q = new URLSearchParams({ direction: "forward", ...(follow ? { cursor: follow } : {}) }); const p = await api("GET", `${base}?${q}`); for (const l of p.lines) console.log(l.at, `u${l.unit_ordinal}`, l.text); follow = p.follow_cursor ?? follow; await new Promise((r) => setTimeout(r, p.poll_after_ms));}
Code
import timefollow = api("GET", base, limit=20)["follow_cursor"]while True: p = api("GET", base, direction="forward", **({"cursor": follow} if follow else {})) for l in p["lines"]: print(l["at"], f"u{l['unit_ordinal']}", l["text"]) follow = p["follow_cursor"] or follow time.sleep(p["poll_after_ms"] / 1000)
Una línea tiene el mismo id allí donde se lea, así que si reinicias un seguidor puedes descartar las líneas que ya imprimiste.
Marcas
markers contiene hechos del ciclo de vida entre las líneas: un pod arrancado, sustituido o perdido, y container_restarted con un reason como OOMKilled o Error. Cuando un contenedor escribe más de 500 líneas por segundo, el resto va a un archivo y una marca overflow dice cuántas y cuándo; no se pierde nada, y la ruta de descarga las devuelve en orden.
Descargar
GET .../units/logs/download devuelve un archivo con el desbordamiento archivado ya mezclado, para cuando necesitas todas las líneas.