logs 是 Extension.js CLI 的一個指令。Extension.js 從一個 manifest.json 出發,為 Chrome、Edge、Firefox 與 Safari 建置並執行瀏覽器擴充功能,npx extension@latest dev 會啟動這個指令所讀取的工作階段。
logs 會讀取 dev 工作階段從你的擴充功能收集到的記錄:background、content script、popup、options 以及其餘情境。一個指令就能依序合併顯示全部內容,不必開啟任何一個 DevTools 視窗。
何時使用 logs
- 你想在同一道串流裡同時看到 background worker 與某個 content script 的主控台輸出。
- agent 或指令稿需要機器可讀的記錄,而不是從終端機文字裡刮取。
- 你想查看擴充功能稍早記錄了什麼,而不必重新觸發一次那個行為。
用法
logs 會印出磁碟上已有的記錄然後結束。加上 --follow 可以保持連線,即時串流新的記錄。
參數與 flag
選擇某個
--level 會一併包含該層級以及所有更嚴重的層級。--level warn 會顯示 warn 與 error。一般的 console.log 記錄算作 info。
從 4.1.20 起,Safari 工作階段的讀取方式完全相同。extension logs --browser safari 會印出 dev --browser safari 工作階段中 background 與 content 的記錄列,加上 --follow 就是即時串流。請見 建置 Safari 擴充功能。
一次性模式
不加--follow 時,指令會直接讀取 dist/extension-js/<browser>/logs.ndjson,不需要任何即時連線。開發工作階段會把每一筆記錄附加到那個檔案,所以即使你已經關掉瀏覽器,一次性讀取仍然有效。
如果該檔案不存在,logs 會提示你先啟動 extension dev,並以結束碼 1 結束。機器可讀格式還會輸出一個錯誤碼為 E_LOGS_NOT_FOUND 的失敗信封(參見 結果信封)。
當工作階段丟棄過記錄時,檔案裡會在對應位置保留一筆 gap 記錄。不帶任何過濾的 ndjson 或 json 讀取會把這筆記錄原樣印到 stdout。一旦有任何過濾條件縮小了讀取範圍(--context、--level、--since、--url、--tab),stdout 上就只有日誌記錄,遺失的情況會在 stderr 上以一行回報,附上丟棄筆數與原因,所有輸出格式都如此。
跟隨模式
--follow 會查出工作階段的就緒契約,以記錄消費端的身分連上控制通道,並在記錄產生時串流出來。它需要一個執行中的開發工作階段,但不需要任何解鎖 flag:記錄消費永遠是允許的。
logs 會在 stderr 上印出一行提示,說明丟棄的筆數與原因。
當你用 Ctrl+C 停止串流時,機器可讀格式會印出一個狀態為 interrupted 的終止成功信封,讓消費端能分辨乾淨的停止與當機。結束碼為 0。
如果找不到所選瀏覽器對應的工作階段,指令會以 E_SESSION_NOT_FOUND 失敗,並指名該執行的 extension dev 指令。
輸出格式
pretty 模式每筆記錄印出一行:ndjson 每行印出一筆原始 JSON 記錄,很適合 jq 與記錄收集器。json 則會把每筆記錄格式化成多行。當 stdout 不是 TTY 時,ndjson 本來就是預設值,因此導管不需要額外的 flag:
區分 content script 的列與 service worker 的列
沒有logs 時,這兩種輸出分別住在兩個 DevTools 視窗裡:service worker 的主控台藏在擴充功能管理頁後面,content script 的主控台則在它所執行的頁面裡。logs 把它們合併成一條串流,並給每筆記錄標上產生它的情境標籤,這樣你就能按自己的方式再把它們分開。
這個標籤就是 context 欄位,pretty 模式下印在括號裡。開發工作階段按編譯後的項目分配它。content_scripts/ 下的輸出是 content,背景 service worker(或 Firefox 的背景指令碼)是 background。action/index.js 是 popup,options/index.js 是 options,其餘依此類推,涵蓋 --context 接受的整個清單。
console.log 呼叫印出為 LOG,按 info 過濾,因此 --level info 會保留它,--level warn 會丟棄它。
除了標籤之外,這兩種列還有兩處不同。content script 的記錄還帶有它所執行的頁面(url、tabId、frameId)。content script 把輸出轉發給 service worker,而工作階段記錄下了送出方。背景記錄沒有頁面,所以這些欄位一個都沒有。這給了你兩種分離兩條串流的方式:
--context按標籤選擇。--context background只顯示 service worker,--context content只顯示 content script,逗號分隔的清單則把它們組合起來。清單之外的名字會被拒絕。--url和--tab按頁面選擇。背景列沒有 URL 也沒有分頁,所以任一篩選器都會把它丟掉,只留下 content 列。
error 列到達,訊息後面附有堆疊,因此跨兩個情境使用 --level error 是看清哪一側拋出錯誤的最快方式。
要在指令碼裡拆分這條串流,請讀取 ndjson 並按 context 欄位分支。背景列上沒有 url 欄位:
dev 透過 --logs 和 --log-context 在自己終端機裡印出的串流。請見 dev。

