mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-30 22:23:37 +00:00
62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
/** Reads recent gateway service logs for actionable daemon restart diagnostics. */
|
|
import fs from "node:fs/promises";
|
|
import { resolveGatewayLogPaths, resolveGatewaySupervisorLogPaths } from "./restart-logs.js";
|
|
|
|
// Error patterns worth surfacing from gateway service logs after failed starts.
|
|
const GATEWAY_LOG_ERROR_PATTERNS = [
|
|
/refusing to bind gateway/i,
|
|
/gateway auth mode/i,
|
|
/gateway start blocked/i,
|
|
/failed to bind gateway socket/i,
|
|
/tailscale .* requires/i,
|
|
];
|
|
|
|
async function readLastLogLine(filePath: string): Promise<string | null> {
|
|
try {
|
|
const raw = await fs.readFile(filePath, "utf8");
|
|
const lines = raw.split(/\r?\n/).map((line) => line.trim());
|
|
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
if (lines[i]) {
|
|
return lines[i];
|
|
}
|
|
}
|
|
return null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function readLastGatewayErrorLine(
|
|
env: NodeJS.ProcessEnv,
|
|
options?: { platform?: NodeJS.Platform },
|
|
): Promise<string | null> {
|
|
const platform = options?.platform ?? process.platform;
|
|
const readStderr = platform !== "darwin";
|
|
// launchd supervisor mode combines child stderr into stdout; other platforms
|
|
// keep stderr as the strongest failure signal.
|
|
const { stdoutPath, stderrPath } =
|
|
platform === "darwin"
|
|
? resolveGatewaySupervisorLogPaths(env, { platform })
|
|
: resolveGatewayLogPaths(env);
|
|
const stderrRaw = readStderr ? await fs.readFile(stderrPath, "utf8").catch(() => "") : "";
|
|
const stdoutRaw = await fs.readFile(stdoutPath, "utf8").catch(() => "");
|
|
// stderr is the strongest failure signal on non-darwin platforms, so place it
|
|
// last and scan from the end: the most recent stderr error line then wins over
|
|
// any (possibly stale) stdout match, matching the stderr-first fallback below.
|
|
const lines = [...stdoutRaw.split(/\r?\n/), ...stderrRaw.split(/\r?\n/)].map((line) =>
|
|
line.trim(),
|
|
);
|
|
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
const line = lines[i];
|
|
if (!line) {
|
|
continue;
|
|
}
|
|
if (GATEWAY_LOG_ERROR_PATTERNS.some((pattern) => pattern.test(line))) {
|
|
return line;
|
|
}
|
|
}
|
|
return readStderr
|
|
? ((await readLastLogLine(stderrPath)) ?? (await readLastLogLine(stdoutPath)))
|
|
: await readLastLogLine(stdoutPath);
|
|
}
|