Summary
The hackbrowser crawl worker runs as a separate subprocess, and its internal state — browser/page lifecycle, crawl progress, and errors — is not reliably surfaced anywhere the operator can read. When a crawl fails or stops early (see #104), there is no persisted record of what actually happened (e.g. whether a page closed, a popup was dismissed, the renderer crashed, or the browser disconnected). This has repeatedly blocked troubleshooting.
Goal
Give the worker its own persistent diagnostic log and record every browser lifecycle event, so a failed/partial crawl can be diagnosed after the fact without guessing from a single stack trace.
Proposed changes
1. Dedicated worker log file
Write worker diagnostics to a per-session file in the runtime data dir:
<data>/log/hackbrowser-<sessionID>.log
- Lives in the data dir (outside the repo), so it is never committed.
- Independent of the main log / IPC relay, which does not reliably carry worker logs today.
2. Log all browser lifecycle events
Attach listeners and log each event with context:
page.on("close") — page closed (navigation / window.close / popup dismissed)
page.on("crash") — renderer crash (distinct from a close)
context.on("page") — a new page/popup/tab was opened
context.on("close") — context closed
browser.on("disconnected") — browser went away
Listening to close vs crash separately means we can tell a deliberate close from a crash without inferring it from an error string.
3. Context attached to each event
- timestamp
- URL of the page/target
- open page count (
context.pages().length)
browser.isConnected()
- crawl progress: pages explored so far, queue length
4. Capture-drop diagnostics (ties into #104)
When a request capture is dropped because the target closed mid-flight, log the target state at that moment: pageClosed, browserConnected, and the URL. Combined with the lifecycle log, this pinpoints whether a partial crawl was caused by a page close, a popup, or a browser death.
5. Verbosity
Consider gating the verbose lifecycle logging behind a debug flag / env var so normal runs stay quiet, while troubleshooting can opt in.
Notes
Summary
The hackbrowser crawl worker runs as a separate subprocess, and its internal state — browser/page lifecycle, crawl progress, and errors — is not reliably surfaced anywhere the operator can read. When a crawl fails or stops early (see #104), there is no persisted record of what actually happened (e.g. whether a page closed, a popup was dismissed, the renderer crashed, or the browser disconnected). This has repeatedly blocked troubleshooting.
Goal
Give the worker its own persistent diagnostic log and record every browser lifecycle event, so a failed/partial crawl can be diagnosed after the fact without guessing from a single stack trace.
Proposed changes
1. Dedicated worker log file
Write worker diagnostics to a per-session file in the runtime data dir:
2. Log all browser lifecycle events
Attach listeners and log each event with context:
page.on("close")— page closed (navigation / window.close / popup dismissed)page.on("crash")— renderer crash (distinct from a close)context.on("page")— a new page/popup/tab was openedcontext.on("close")— context closedbrowser.on("disconnected")— browser went awayListening to
closevscrashseparately means we can tell a deliberate close from a crash without inferring it from an error string.3. Context attached to each event
context.pages().length)browser.isConnected()4. Capture-drop diagnostics (ties into #104)
When a request capture is dropped because the target closed mid-flight, log the target state at that moment:
pageClosed,browserConnected, and the URL. Combined with the lifecycle log, this pinpoints whether a partial crawl was caused by a page close, a popup, or a browser death.5. Verbosity
Consider gating the verbose lifecycle logging behind a debug flag / env var so normal runs stay quiet, while troubleshooting can opt in.
Notes
allHeaders()), which this observability work helps root-cause going forward.