browser-trace

browser-trace

熱門

擷取任何瀏覽器自動化的完整 DevTools 協定追蹤 — CDP 事件串流、螢幕截圖和 DOM 轉儲 — 然後將串流分割成每個頁面可搜尋的區塊。當使用者想要偵錯失敗的執行、稽核網路/主控台/DOM 活動、將追蹤附加到進行中的工作階段,或將結構化的每頁摘要回饋到代理循環中,以便下一次迭代從上一次學習時使用。

3665星標
231分支
更新於 2026/7/24
SKILL.md
readonlyread-only
name
browser-trace
description

擷取任何瀏覽器自動化的完整 DevTools 協定追蹤 — CDP 事件串流、螢幕截圖和 DOM 轉儲 — 然後將串流分割成每個頁面可搜尋的區塊。當使用者想要偵錯失敗的執行、稽核網路/主控台/DOM 活動、將追蹤附加到進行中的工作階段,或將結構化的每頁摘要回饋到代理循環中,以便下一次迭代從上一次學習時使用。

Browser Trace

第二個唯讀 CDP 客戶端附加到已由主要自動化驅動的瀏覽器工作階段。追蹤會將完整的 DevTools 事件串流記錄到 NDJSON,同時輪詢螢幕截圖和 DOM 轉儲,並將所有內容切割成 bash 工具可搜尋的目錄樹。

此技能驅動頁面 — 它僅監聽。請搭配 browser 技能、browse、Stagehand、Playwright 或任何其他支援 CDP 的工具使用。

使用時機

  • 使用者想要偵錯瀏覽器自動化執行(表單失敗、元素遺失、導覽卡住、JS 例外)。
  • 使用者有正在執行的自動化,並希望在不重新啟動的情況下附加追蹤。
  • 使用者想要將 CDP 事件串流分割成網路/主控台/DOM/頁面區塊。
  • 使用者想要隨時間變化的螢幕截圖 + DOM 快照,並透過時間戳記與 CDP 事件關聯。

如果使用者只想驅動瀏覽器,請改用 browser 技能。

設定檢查

node --version                                  # 需要 Node 18+
which browse || npm install -g browse
which jq     || true                                # 可選 — 僅用於臨時查詢

驗證 browse cdp 存在:

browse --help | grep -q "^\s*cdp " || echo "browse cdp 不可用 — 請更新 browse"

運作方式

每個 Chrome DevTools 目標都接受多個並發 CDP 客戶端。您的主要自動化是一個客戶端;此技能新增第二個客戶端,僅啟用觀察領域(Network、Console、Runtime、Log、Page),且絕不發送動作命令。

追蹤器包含三個部分:

  1. 事件串流browse cdp <target> 將每個 CDP 事件以一行一個 JSON 物件串流到 cdp/raw.ndjson
  2. 取樣器:輪詢迴圈會定期呼叫 browse screenshot --cdp <target> --path <file>browse get html body --cdp <target>(預設間隔 2 秒)。輔助程式在取樣時傳遞 --cdp,以便從自己的程序附加到被追蹤的目標;一旦 browse 守護程序工作階段附加到 CDP 目標,該工作階段的後續命令無需重複 --cdp
  3. 分割器:執行結束後,bisect-cdp.mjs 會遍歷 raw.ndjson 一次,根據 CDP 方法將其分割成每個區塊的 JSONL 檔案,並另外使用頂層 Page.frameNavigated 事件作為邊界,按頁面分割。

快速入門

本機 Chrome

# 1. 啟動 Chrome 並開啟偵錯埠(任何 user-data-dir 可保持隔離)。
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
  --remote-debugging-port=9222 \
  --user-data-dir=/tmp/chrome-o11y \
  about:blank &

# 2. 啟動追蹤器。
node scripts/start-capture.mjs 9222 my-run

# 3. 針對埠 9222 執行您的主要自動化。
browse open https://example.com --cdp 9222
# ...執行任何操作...

# 4. 停止並分割。
node scripts/stop-capture.mjs my-run
node scripts/bisect-cdp.mjs my-run

Browserbase 遠端

兩個輔助程式封裝了平台端的簿記:bb-capture.mjs 建立或附加到工作階段並啟動追蹤器;bb-finalize.mjs 在執行結束時將平台工件(最終工作階段元資料、伺服器日誌、下載)拉取到執行目錄中。

Browserbase 會在其最後一個 CDP 客戶端斷開連線時結束工作階段。使用 --keep-alive 建立,然後在追蹤器之前或同時將自動化附加到工作階段的 connectUrl bb-capture.mjs --new 處理保持連線的工作階段和追蹤器設定;您的自動化仍需附加。

export BROWSERBASE_API_KEY=...

# 1. 一步建立保持連線的工作階段並啟動追蹤器。
#    列印工作階段 ID、connectUrl 前綴,以及一個即時偵錯程式 URL,
#    您可以在瀏覽器中開啟以互動方式觀看執行。
node scripts/bb-capture.mjs --new my-run

# 2. 驅動自動化。bb-capture 已將工作階段 ID 寫入 manifest。
SID=$(jq -r .browserbase.session_id .o11y/my-run/manifest.json)
CONNECT_URL="$(browse cloud sessions get "$SID" | jq -r .connectUrl)"
BROWSE_NAME=my-run-browser
browse open https://example.com --cdp "$CONNECT_URL" --session "$BROWSE_NAME"
browse open https://news.ycombinator.com --session "$BROWSE_NAME"

# 3. 停止追蹤器、分割,然後拉取平台工件並釋放。
node scripts/stop-capture.mjs my-run
node scripts/bisect-cdp.mjs my-run
node scripts/bb-finalize.mjs my-run --release

附加到已經在執行的工作階段(例如您的生產工作者建立的)— bb-capture.mjs 接受工作階段 ID 而非 --new

# 選擇一個正在執行的工作階段(客戶端過濾;browse cloud sessions list 沒有 --status 旗標)
browse cloud sessions list | jq -r '.[] | select(.status == "RUNNING") | .id'

node scripts/bb-capture.mjs <session-id> mid-flight-debug
# ...追蹤器與現有自動化客戶端並行執行;不會中斷...
node scripts/stop-capture.mjs mid-flight-debug
node scripts/bisect-cdp.mjs mid-flight-debug
node scripts/bb-finalize.mjs mid-flight-debug   # 不加 --release:保持工作階段執行
從 Browserbase 平台獲得的內容

bb-capture.mjsmanifest.json 中新增一個 browserbase 區塊(工作階段 ID、專案、區域、started_at、expires_at、偵錯程式 URL)。bb-finalize.mjs 寫入:

  • <run>/browserbase/session.json — 最終的 browse cloud sessions get 快照(proxyBytes、狀態、ended_at、viewport 等)
  • <run>/browserbase/logs.jsonbrowse cloud sessions logs 輸出。通常為空。 CDP 事件串流 cdp/raw.ndjson 是真相來源;這是側通道。
  • <run>/browserbase/downloads.zip — 工作階段下載的檔案(如果有的話;腳本會丟棄當沒有檔案時得到的空 22 位元組 zip)

工作階段重播工件擷取已棄用,不會被擷取。請使用 screenshots/dom/ 中的螢幕截圖和 DOM 轉儲作為視覺真相。

manifest 中的即時 debugger_url 會開啟一個由 Browserbase 提供的互動式 Chrome DevTools 檢視 — 方便在追蹤器將事件串流擷取到磁碟時觀看長時間執行的自動化。

檔案系統佈局

.o11y/<run-id>/
  manifest.json                 執行元資料:目標、領域、started_at、stopped_at
  index.jsonl                   每個樣本一行:{ts, screenshot, dom, url}
  cdp/
    raw.ndjson                  完整 CDP 事件串流(每行一個 JSON 物件)
    summary.json                {sessionId, duration, totalEvents, pages[]} — 請參閱下方結構
    network/{requests,responses,finished,failed,websocket}.jsonl   工作階段範圍的區塊(總是寫入)
    console/{logs,exceptions}.jsonl
    runtime/all.jsonl
    log/entries.jsonl
    page/{navigations,lifecycle,frames,dialogs,all}.jsonl
    dom/all.jsonl                                               (僅當 O11Y_DOMAINS 包含 DOM 時)
    target/{attached,detached}.jsonl
    pages/                      按頁面分割,以頂層 frameNavigated 邊界索引
      000/                      第一個具體頁面
        url.txt                 此頁面的 URL
        summary.json            此頁面的 domains/network/timing 區塊(與 pages[] 條目結構相同)
        raw.jsonl               限於此頁面的事件串流
        network/, console/, page/, runtime/, log/, target/, dom/    相同區塊,僅非空檔案
  screenshots/<iso-ts>.png      每個取樣間隔一個 PNG
  dom/<iso-ts>.html             每個取樣間隔一個 HTML 轉儲
  browserbase/                  由 bb-finalize.mjs 新增(僅 Browserbase 執行)
    session.json                最終的 `browse cloud sessions get` 快照(proxyBytes、狀態、ended_at 等)
    logs.json                   `browse cloud sessions logs` 輸出(通常為 [])
    downloads.zip               `browse cloud sessions downloads get` 輸出(僅當工作階段下載了檔案)

當執行是透過 bb-capture.mjs 啟動時,manifest.json 也會攜帶一個頂層的 browserbase 區塊:session_idproject_idregionstarted_atexpires_atkeep_alivedebugger_url

摘要結構

cdp/summary.json 是任何分析的入口點:它包含工作階段層級的總計和一個由頂層 Page.frameNavigated 索引的 pages[] 陣列。每個頁面的條目按導覽順序發出(頁面 0 = 第一個具體 URL)。

{
  "sessionId": "45f28023-…",
  "duration": { "startMs": 1777312533000, "endMs": 1777312609000, "totalMs": 76000 },
  "totalEvents": 420,
  "pages": [
    {
      "pageId": 0,
      "url": "https://example.com/",
      "startMs": 1777312533000, "endMs": 1777312538886, "durationMs": 5886,
      "eventCount": 60,
      "domains": {
        "Network": { "count": 18, "errors": 1 },
        "Console": { "count": 2 },
        "Page":    { "count": 24 },
        "Runtime": { "count": 13 }
      },
      "network": { "requests": 4, "failed": 1, "byType": { "Document": 2, "Script": 1, "Other": 1 } }
    }
  ]
}

startMs / endMs / durationMs 是牆上時鐘毫秒,源自 manifest.started_at 加上每個事件的 CDP 單調時間戳記偏移。domains[*] 僅在非零時包含 errors/warnings 鍵。

使用 query.mjs 深入查詢

對於互動式探索,請使用 scripts/query.mjs <run-id> <command> 而不是記住路徑:

node scripts/query.mjs my-run list                    # 頁面的單行表格
node scripts/query.mjs my-run page 1                  # 頁面 1 的完整摘要
node scripts/query.mjs my-run page 1 network/failed   # 顯示頁面 1 的 failed.jsonl
node scripts/query.mjs my-run errors                  # 所有頁面的錯誤,按 pid 歸因
node scripts/query.mjs my-run errors 2                # 僅頁面 2 的錯誤
node scripts/query.mjs my-run hosts                   # 按請求計數排列的頂級主機
node scripts/query.mjs my-run host api.example.com    # 特定主機的所有請求/回應
node scripts/query.mjs my-run summary                 # 完整的 summary.json

幕後它僅讀取 cdp/summary.jsoncdp/pages/<pid>/ 樹 — 一旦您熟悉結構,可以隨意使用原始 jq/rg 繞過它。

頂層遍歷技巧

# 所有失敗的網路請求(使用 jq -c 保持行分隔)
jq -c '.params' .o11y/<run>/cdp/network/failed.jsonl

# 尋找對特定主機的請求
jq -c 'select(.params.request.url | test("api\\.example\\.com"))' \
  .o11y/<run>/cdp/network/requests.jsonl

# 4xx/5xx 回應
jq -c 'select(.params.response.status >= 400)
       | {status: .params.response.status, url: .params.response.url}' \
  .o11y/<run>/cdp/network/responses.jsonl

# 僅主控台錯誤
jq -c 'select(.params.type == "error")' .o11y/<run>/cdp/console/logs.jsonl

# 造訪的 URL 順序
jq -r '.params.frame.url' .o11y/<run>/cdp/page/navigations.jsonl

# 尋找最接近某個時間戳記的螢幕截圖(例如,當例外發生時)
ls .o11y/<run>/screenshots/ | sort | awk -v t=20260427T1714123NZ '
  $0 >= t { print; exit }'

請參閱 REFERENCE.md 以取得完整的 jq 技巧庫和按方法分割的對應表。請參閱 EXAMPLES.md 以取得端到端偵錯情境。

最佳實踐

  1. 在 Browserbase 上使用 bb-capture.mjs:它會強制使用 --keep-alive、擷取 connectUrl、取得偵錯程式 URL,並在 manifest 中標記。手動操作容易出錯。
  2. 不要 --release 您不擁有的工作階段bb-finalize.mjs --release 適用於您使用 --new 建立的工作階段。當透過 bb-capture.mjs <session-id> 附加到生產工作階段時,請執行 bb-finalize.mjs 而不加 --release,以便原始自動化繼續執行。
  3. 遠端時順序很重要:在 Browserbase 上,在追蹤器之前(或同時)附加主要自動化客戶端,並使用 --keep-alive 建立工作階段。否則,工作階段會在追蹤器的 WebSocket 關閉時立即結束。
  4. 不要輪詢快於約 1 秒:每個樣本都會執行瀏覽器 CLI 讀取命令並對 Chrome 進行螢幕截圖。2 秒是良好的預設值。
  5. 刻意選擇領域:預設值(Network Console Runtime Log Page)涵蓋大多數偵錯。透過 O11Y_DOMAINS="$O11Y_DOMAINS DOM" 新增 DOM 以取得 DOM 樹變更(非常嘈雜)。
  6. 在遠端重複使用同一個 Browserbase 工作階段,方法是使用 browse open ... --cdp "$CONNECT_URL" --session <name> 附加到該工作階段的 connectUrl--session 旗標命名本機 browse 守護程序;它不是 Browserbase 工作階段附加旗標。
  7. 始終執行 stop-capture.mjs,即使在崩潰後也是如此,這樣背景程序就不會殘留,且 manifest 會取得 stopped_at
  8. 每個執行分割一次bisect-cdp.mjs 是冪等的 — 它每次都會從 raw.ndjson 覆寫每個區塊的檔案。

疑難排解

  • browse cdp exited immediately:通常表示目標無法連線(錯誤的埠)或 Browserbase 工作階段已結束。對於遠端,請使用 browse cloud sessions get <id> 驗證 — 如果 statusCOMPLETED,請使用 --keep-alive 重新建立並先附加自動化。
  • 即使程序在執行,raw.ndjson 也是空的:確認 CDP 客戶端確實正在驅動頁面。追蹤器僅發出瀏覽器產生的事件,因此閒置的瀏覽器只會產生約 5 行附加/發現訊息,沒有其他內容。
  • 所有螢幕截圖看起來都一樣:檢查 index.jsonl — 如果 url 沒有改變,表示頁面尚未導覽。輪詢迴圈獨立於主要自動化的節奏執行。
  • Browserbase 工作階段中途結束:可能已達到 --timeout。使用更高的逾時值重新建立(BB_SESSION_TIMEOUT=1800 node scripts/bb-capture.mjs --new ...)或移除逾時旗標。
  • bb-capture.mjs <id> 顯示 "not RUNNING":您嘗試附加的工作階段已結束。使用 browse cloud sessions list | jq '.[] | select(.status == "RUNNING")' 列出候選項目,然後重試。
  • browserbase/logs.json 是空的 []:這是預期的 — browse cloud sessions logs 在實務上內容稀疏。CDP 事件串流 cdp/raw.ndjson 是真相來源。
  • 工作階段錄製(rrweb)在哪裡?:工作階段重播工件擷取已棄用;此技能不會擷取它。請使用 screenshots/ 中的螢幕截圖串流和 dom/ 中的 DOM 轉儲。

如需完整參考,請參閱 REFERENCE.md
如需範例偵錯執行,請參閱 EXAMPLES.md