← back to Homesonspec
apps/admin/src/app/api/engine-log/route.ts
36 lines
import { NextResponse } from "next/server";
import { open, stat } from "node:fs/promises";
export const dynamic = "force-dynamic";
// Live tail of the ingestion ENGINE (pm2 homesonspec-ingest build-loop). The admin runs on the
// same Kamatera box as the engine, so it reads the pm2 out-log directly. Bounded tail (last ~56KB)
// so a huge/rotated log never blows memory. Read-only.
const LOG = "/root/.pm2/logs/homesonspec-ingest-out.log";
const TAIL_BYTES = 56 * 1024;
async function tail(path: string): Promise<string> {
const st = await stat(path);
const start = Math.max(0, st.size - TAIL_BYTES);
const len = st.size - start;
const fh = await open(path, "r");
try {
const buf = Buffer.alloc(len);
await fh.read(buf, 0, len, start);
return buf.toString("utf8");
} finally {
await fh.close();
}
}
export async function GET() {
try {
const raw = await tail(LOG);
// drop the first (likely partial) line, keep the last ~200
const lines = raw.split("\n").slice(1).filter(Boolean).slice(-200);
return NextResponse.json({ ts: new Date().toISOString(), ok: true, lines });
} catch (e: any) {
return NextResponse.json({ ts: new Date().toISOString(), ok: false, error: String(e?.message ?? e), lines: [] });
}
}