English | 日本語
ブラウザのコンソール出力(ログ・警告・エラー・例外)を、テキストファイルへ自動記録するツール。 記録対象は4つ — PC の Chrome、USB 接続した Android 端末の Chrome、Mac の Safari、 USB 接続した iPhone / iPad の Safari。
DevTools を開いていなくても、専用の Chrome を立ち上げている間(または対象端末を USB で繋いでいる間)は、 コンソールの内容がファイルに書き出され続ける。PC / Android の Chrome は Chrome DevTools Protocol (CDP)、 iPhone / iPad の Safari は Web Inspector、Mac の Safari は WebDriver BiDi でブラウザにアタッチして コンソールイベントを受け取る方式なので、対象ページのソースには一切手を入れない。
これは PC 向けだけのロガーではない。USB 接続したスマホ実機の Chrome コンソールを、そのまま
PC 側のテキストファイルに連続記録できるのが大きな特徴。chrome://inspect を開いて DevTools の
出力を手でコピペする必要はなく、モバイルのコンソール(ログ・例外・ネットワークエラー等)が、
実機の画面遷移・リロードをまたいでファイルへ流れ続ける。結果として スマホ実機のデバッグログを、
コピペ無しでそのまま AI に渡せる。手順は「Android 端末の Chrome を記録する」節を参照。
現状の実装(エントリポイント)は
chrome_console_logger.py。
AI に直接ブラウザを操作させる方式(MCP など)の代替ではなく、**「人が手で再現し、 その結果を AI に読ませる」**ためのパッシブなレコーダーです。
- ツール非依存: 出力はただのテキスト。どの AI にも貼る/渡すだけで、連携設定が要らない。
- 取りこぼさない: リロードや遷移をまたいでセッション全体を連続記録(都度クエリ方式のような欠落が無い)。
- PC をまたげる: dev と test を別 PC にしても、出力フォルダを同期しておけばファイルが自動で渡る。
- 安全(信頼境界が小さい): AI に操作権を渡さず、読み取り専用の成果物だけ渡せる。
- モバイルも対象: USB 接続した Android 端末の Chrome、および iPhone / iPad の Safari のコンソールも記録でき、スマホ実機のデバッグログを手コピペ無しで取り出せる。
逆に、AI が自律的にクリック→リロード→確認…と反復デバッグする用途はライブ制御向き。 本ツールはコンソール中心(ネットワーク本文などは対象外)。ログに機微情報が出る場合があるため、 クラウドの AI へ渡す前に中身を確認してください(削除クリア+フィルタが「最小限だけ渡す」に役立ちます)。
- OS: Windows / macOS(Linux は実装のみで未検証。下の対応表参照)
- Chrome の自動検出・コンソールのコードページ設定・画面クリアは OS ごとに出し分け済み。
- 起動は Windows が
glog.bat、macOS / Linux はglog.sh(またはpython chrome_console_logger.py ...を直接実行)。
- Python 3.8 以上
- Windows:
pythonかpyがパスにあること。 - macOS / Linux:
python3がパスにあること(macOS 標準の 3.9 でも動く)。
- Windows:
- Google Chrome(一般的な場所にインストールされていれば自動検出。
見つからなければ
config.jsonのchrome_exeでフルパス指定)- 自動検出する既定パス: Windows は
Program Files等のchrome.exe、 macOS は/Applications/Google Chrome.app(~/Applications/...も)、 Linux はPATH上のgoogle-chrome/chromium等。
- 自動検出する既定パス: Windows は
- Python パッケージ:
websocket-client - (Android 端末の記録を使う場合のみ)adb(Android SDK Platform-Tools)。 インストール方法は「Android 端末の Chrome を記録する」節を参照
- (iPhone / iPad の記録を使う場合のみ)
pymobiledevice310.2 以上 (pip install -r requirements-ios.txt)。root / sudo は不要。 Windows のみ追加要件が2つある(Apple Mobile Device Support と C コンパイラ)。 詳細は「iPhone / iPad の Safari を記録する」節を参照
「どのブラウザを、どの PC で記録できるか」の一覧。原則としてロガーとブラウザは同じ PCにあり、 別マシンのブラウザには繋がらない(USB で繋いだ Android / iPhone だけが例外)。
凡例: ✅ サポート / ⚠ 実装済み・未検証 / ✗ 非対応(設計上できない)
| ブラウザ | 端末 | source |
🪟 Windows で記録 | 🍎 Mac で記録 |
|---|---|---|---|---|
| Chrome | PC 本体 ¹ | desktop |
✅ | ✅ |
| Chrome | Android | android |
✅ | ✅ |
| Chrome | iPhone / iPad | — | ✗ ² | ✗ ² |
| Safari | PC 本体 ¹ | safari |
✗ ³ | ✅(実験的) |
| Safari | iPhone / iPad | ios |
✅ ⁴ | ✅ |
端末列の Android / iPhone / iPad は、いずれも PC に USB 接続した実機を指す。
脚注
- PC 本体 = ロガーを動かしている PC 自身。
desktop/safariはその PC のブラウザを起動 / アタッチするため、別マシンのブラウザには届かない(=ロガーとブラウザは同じ機体)。 - iPhone の Chrome は iOS 上で WebKit(WKWebView)で動き、Web インスペクタの対象外。green_light の iOS 記録は iPhone / iPad の Safari のみ対応。
safaridriverは macOS 同梱ツールで macOS 専用。Windows / Linux には存在しない。- 実装は OS 共通(純 Python)だが、Windows はセットアップに追加要件が2つある
(Apple Mobile Device Support と C コンパイラ。
「iPhone / iPad の Safari を記録する」節を参照)。
Windows での実機記録は 2026-08-30 に検証済み(
iPhone12,8/ iOS 26.5.2 / pymobiledevice3 11.2.1 / Windows 11)。pymobiledevice3は 10.2 以上が必須 (理由は同節の「pymobiledevice3 のバージョン下限」)。
⚠ Linux をロガーにする場合は「実装済み・未検証」(表の ⚠ 相当)。対象の組み合わせは Windows 列と同じ (
desktop/android/iosが対象でsafariは不可)で、起動はglog.sh。ただし OS 分岐を 実装してあるだけで、Linux 実機での動作確認はしていない。
図にすると(脚注1の「ロガーとブラウザは同じ機体」という関係も合わせて見える):
flowchart LR
%% 左=対象ブラウザ/右=ロガー実行環境。エッジのラベル=使う source。
%% エッジが無い(または点線)組み合わせ=未検証か非対応。
classDef browser fill:#e8f0fe,stroke:#4285f4,color:#111827;
classDef host fill:#fff4e5,stroke:#f5a623,color:#111827,font-weight:bold;
classDef na fill:#eeeeee,stroke:#9e9e9e,color:#555,stroke-dasharray:4 3;
CW["Chrome<br/>Windows"]:::browser
CM["Chrome<br/>Mac"]:::browser
CA["Chrome<br/>Android(USB)"]:::browser
CI["Chrome<br/>iPhone(USB)"]:::browser
SM["Safari<br/>Mac"]:::browser
SI["Safari<br/>iPhone(USB)"]:::browser
HW["🪟 ロガー = Windows"]:::host
HM["🍎 ロガー = Mac"]:::host
CW -->|"desktop ✅"| HW
CM -->|"desktop ✅"| HM
CA -->|"android ✅"| HW
CA -->|"android ✅"| HM
SM -->|"safari ✅(実験的)"| HM
SI -->|"ios ✅(検証済)"| HM
SI -->|"ios ✅(検証済)"| HW
CI -.->|"✗ 非対応"| NA["記録不可<br/>iPhone の Chrome は<br/>Web インスペクタ対象外"]:::na
Windows(コマンドプロンプト):
:: 1) 依存パッケージを入れる
pip install -r requirements.txt
:: 2) 設定ファイルを用意(サンプルをコピーして編集)
copy config.example.json config.jsonmacOS / Linux(ターミナル):
# 1) 依存パッケージを入れる(venv 推奨)
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# 2) 設定ファイルを用意(サンプルをコピーして編集)
cp config.example.json config.jsonconfig.json は環境依存のため Git 管理対象外(.gitignore 済み)。
必ず config.example.json をコピーして作成し、自分の環境に合わせて書き換えること。
最低限 output_dir(ログの出力先)を確認すればよい。
- 起動する(Windows は
glog.bat、macOS / Linux は./glog.sh)。 Windows はダブルクリックでも起動でき、ターミナルからなら URL や--configを引数で渡せる(下記「起動例」)。 macOS / Linux は./glog.sh ...かpython chrome_console_logger.py ...を直接実行する。 - 専用プロファイルの Chrome が立ち上がる
- 記録したいページのアドレスを 自分で入力して開く
- すべてのページのコンソール出力が出力先ファイルに記録される
- 記録を止めるときは、このターミナルで
Ctrl+C(Chrome は開いたまま)
ℹ️
Ctrl+C後も debug Chrome は意図的に開いたままにする(作業を続けられるし、次回起動時は その Chrome にアタッチする)。macOS では全ウィンドウを閉じてもプロセスが終了せず、 リモートデバッグポート(既定 9222)を掴んだまま常駐する(Windows は最後のウィンドウを 閉じれば終了する)。ウィンドウが見えないのにポートが塞がっているときはこれ。使い終わったら その debug Chrome を Cmd+Q で終了させること(デバッグ可能な Chrome を常駐させ続けないため)。
既定ではフィルタを掛けず全ページを記録する(filter_enabled: false)。
起動時メニューも出ず、特定 URL も開かない。
起動例(Windows はダブルクリックでも、ターミナルから引数付きでも起動できる):
glog.bat
glog.bat https://example.com/
glog.bat --config myapp
glog.bat --config myapp https://example.com/macOS / Linux は glog.sh に同じ引数を渡す:
./glog.sh
./glog.sh https://example.com/
./glog.sh --config myapp
./glog.sh --config myapp https://example.com/- 引数なし … 既定の
config.jsonで記録(ダブルクリックと同じ) <URL>… 起動時にその URL を開く(config.jsonのstart_urlより優先)--config <名前>… 設定セットconfig.<名前>.jsonを使う- URL と
--configは併用できる(順不同)
各引数の詳細は下の「コマンドライン引数」を参照。
同時に2つ以上ロガーを起動すると同じログファイルに二重書き込みになるため、 起動し直すときは前のロガーのターミナルを
Ctrl+Cで止めてから。
glog.bat に渡せる引数:
| 引数 | 説明 |
|---|---|
<URL>(位置引数) |
起動時に開く URL。config.json の start_url より優先 |
--config <名前> / -c <名前> |
使う設定セットを指定。名前(myapp → config.myapp.json)でもパスでも可。default は config.json。詳細は下の「プロジェクト毎に設定を切り替える」参照 |
--check / --doctor |
記録は始めず、スマホが今つながっているかだけを診断して終了(source: ios / android 用) |
--config=<名前>/-c=<名前>の 等号付き表記も可。- URL と
--configは併用できる(順不同)。 - 引数を何も付けなければ、設定セットは対話選択(ダブルクリック時)または
config.json、URL はstart_urlの値が使われる。
:: myapp 用の設定で、起動時に指定 URL を開く
glog.bat --config myapp https://example.com/USB 接続のスマホ(source: ios / android)は、つながっていない理由が実行時には見分けにくい。
--check は記録を始めずに接続を3段階で診断し、どこで失敗しているかと対処法だけを表示する。
glog.bat --config myandroid --checkgreen_light Android connection check (port 9333, the only attached device)
[1/3] adb usable ........................ OK D:\tools\platform-tools\adb.EXE
[2/3] device attached / authorized ...... OK the only attached device (device)
[3/3] Chrome DevTools / pages ........... OK 13 page(s) Chrome/150.0.7871.124
=> green_light can reach the device. You can start glog.
- 診断する段階は、Android が adb → 端末の接続/認可 → Chrome の DevTools、 iOS が usbmux → lockdown(信頼)→ Web インスペクタ。
--configを省くと、稼働中の記録/ディスク上のスマホ用 config から対象を選ぶ(候補が1つなら自動選択)。- 終了コードは 0=到達できた/1=どこかの段階で失敗/2=診断していない(スマホ用 config でない等)。
- 記録中の実行も安全。すでにポートが使われている場合は読み取り専用で確認するだけで、
adb forwardは自分が作ったものしか削除しない(動作中の記録を壊さないため)。
記録中でも出力ファイルを削除できる(ロガーはファイルを開きっぱなしにしない)。
削除すると、次の出力時に自動で作り直し、先頭に # === log file (re)created ... ===
の印を入れて記録を続ける。このときロガーのターミナル画面も同時にクリアされる。
ログが溜まりすぎたら、ファイルを消すだけで「ファイルも画面もまっさら」になる。 開始前に出る不要なログ(ログイン画面など)も、目的のページに着いてから削除すれば消える。
特定ドメインだけ記録したい場合のメインスイッチが filter_enabled。まずここを切り替える。
filter_enabled: false(既定) … フィルタ無効。全ページを記録する。起動メニューも 出さず、URL はstart_url/ コマンドライン引数で開く。filter_enabled: true… フィルタ有効。メインフレームの URL に、設定した文字列を含む ページだけが記録対象になる(ログイン画面など別ドメインは除外)。
⚠
filter_enabled: trueにしたら、記録したいサイトを必ずurl_filter_presets(単一サイトならurl_filter)に指定すること。 指定が空のままだと「フィルタ設定なし」の 警告が出て 全ページ記録にフォールバックし、絞り込みの意味がなくなる(=意図せぬフィルタ漏れ)。 記録対象は各 preset のfilter(メインフレーム URL に含む文字列)で判定され、url_filter_presetsが優先・url_filterはフォールバック。ログイン/認証フローが複数 ドメインにまたがる場合は、必要なドメインを preset に並べておく。
filter_enabled: true のとき、複数のフィルタ候補をどう適用するかを決めるのが filter_menu
(filter_enabled: false のときは無視され、メニューも出ない):
filter_menu: false(既定) …url_filter_presetsの全filterが同時に有効filter_menu: true… 起動時メニューで1つだけ選ぶ(その候補にurlがあれば自動で開く)
フィルタ有効時の安全策として、対象外のページを開くとターミナルに
[info] Not recording (no filter match; ...)と表示される(画面表示は英語)。 フィルタの設定忘れで無言のまま記録できていない、という事態を防ぐため。 既定でフィルタを切ってあるのも、この「気づけないデータ欠落」を避けるため。
フィルタ選択メニューの表示例(filter_enabled: true かつ filter_menu: true のとき。画面表示は英語):
==================================================
Select which pages to record:
1. Production [example.com]
2. Local dev [localhost]
3. All pages (no filter) [(all pages)] <- default
==================================================
Enter a number (Enter = 3):
(<- default は url_filter に一致するプリセット。上は url_filter: "" なので「All pages」が既定)
| キー | 説明 | 既定 |
|---|---|---|
output_dir |
ログの出力先フォルダ。相対パスはこのスクリプトのフォルダ基準。先頭の ~ はホームに展開(macOS / Linux) |
logs |
log_filename |
ログファイル名 | console.log |
overwrite |
true=起動ごとに上書き / false=追記 |
true |
port |
リモートデバッグポート | 9222 |
chrome_exe |
Chrome の実行ファイルパス(空なら自動検出) | 空(自動検出) |
profile_dir |
デバッグ用 Chrome のプロファイル保存先(空ならこのフォルダ内 .chrome-debug-profile) |
空 |
source |
記録対象。desktop=ロガーを動かしている PC の Chrome を起動して記録(Windows / Mac / Linux) / android=USB 接続端末の Chrome を記録(後述) / safari=Mac の Safari を記録(後述・macOS 専用) / ios=USB 接続した iPhone・iPad の Safari を記録(後述) |
desktop |
adb_path |
source: android 時の adb のパス(空なら PATH と一般的な SDK の場所から自動検出) |
空 |
device_serial |
対象端末の識別子。source: android は adb の serial、source: ios は端末の UDID(空なら唯一接続されている端末) |
空 |
safaridriver_path |
source: safari 時の safaridriver のパス(空なら PATH から自動検出。通常 macOS 同梱で指定不要) |
空 |
start_url |
起動時に開く URL(コマンドライン引数が優先) | 空 |
filter_enabled |
false=フィルタ無効(全ページ記録) / true=フィルタで絞り込み |
false |
filter_menu |
(filter_enabled: true のときのみ)false=メニュー無し(全プリセットのフィルタを同時有効・URLは開かない) / true=起動時にフィルタを1つ選ぶ(その url を開く) |
false |
url_filter |
プリセットが空のときの絞り込み文字列(メインフレーム URL に含むページのみ記録) | 空 |
url_filter_presets |
記録対象の候補。[{ "label": 表示名, "filter": 絞り込み文字列, "url": 開くURL }, ...]。url は filter_menu: true で選択時に開く(任意) |
例: Production / Local dev / All |
redact_patterns |
機微情報のマスキング(任意)。正規表現のリスト。一致部分を *** に置換して記録する。ベストエフォートであり保証ではない(後述) |
[](無効) |
timestamp |
true で各行頭に [HH:MM:SS] |
false |
stack_for_trace |
console.trace のスタックも出す |
true |
Windows のパス指定について:
config.jsonは JSON のため、\(円記号 / バックスラッシュ)は エスケープ文字として扱われる。Windows の絶対パスを書くときは区切りを\\(2つ重ね) にすること。 対象はoutput_dir/chrome_exe/profile_dirなどパスを取るキー全部。"output_dir": "C:\\Users\\you\\logs", "chrome_exe": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
\\の代わりに **/(スラッシュ)**でも可("C:/Users/you/logs")。\を1つだけ書くと JSON として不正になり、起動時に読み込みエラーになる。
出力先やファイル名などをプロジェクト別に分けたいときは、設定ファイルを
config.<名前>.json として複数用意して切り替える。
:: myapp 用の設定を作る(テンプレからコピーして編集)
copy config.example.json config.myapp.json
切り替え方は2通り:
- コマンドラインで指定:
glog.bat --config myapp(デフォルトを明示するならglog.bat --config default) - ダブルクリックで対話選択:
glog.batをそのまま実行すると、開いたコンソールで 設定セットの一覧が出る。番号か名前を入力(ENTERだけならデフォルトのconfig.json)。
補足:
--configを付けたときは対話を出さない(バッチ/自動化向け)。--config defaultはconfig.json。- 値は名前(
myapp→config.myapp.json)でもパス(C:\path\my.json)でもよい。 --configで指定したファイルが無いときは、誤った場所への記録を防ぐためエラー終了する (defaultは例外で、config.jsonが無くても従来どおり既定値で起動)。config.<名前>.jsonは Git 管理対象外(config.example.jsonだけ追跡される)。- 複数のロガーを同時に動かせる。 分けるものは source によって違う:
- すべて共通 …
portとoutput_dir/log_filename。 出力先が同じだと、overwrite: trueの後発が先発のログを切り詰める。 desktop… 加えてprofile_dir(同じプロファイルの Chrome は 1 つしか起動できない)。- スマホ(
android/ios)…profile_dirは無関係。portを必ず分ける (例 desktop 9222 / android 9333 / ios 9444)。 iOS と Android の同時記録は実測済み(Pixel 8a と iPhone を同時に USB 接続し、 2 プロセスで記録。互いのログに相手の出力が混ざらないことを確認)。 ポートが衝突していると、--checkが「別のポートを使うこと」と教えてくれる。
- すべて共通 …
chrome://inspect を開いて手でコピペする代わりに、USB 接続した Android 端末の
Chrome コンソールを PC 版と同じ仕組みでファイルに連続記録できる。仕組みは
adb forward で端末の DevTools を localhost に橋渡しし、あとは通常どおり CDP で
アタッチするだけ(端末側のソースには手を入れない)。実機の遷移・リロードを
またいで連続記録でき、AI には出力ファイルを渡すだけ=スマホ実機のデバッグログを
手コピペ無しで取り出せる。
Android の記録には adb(Android Debug Bridge)が必要。adb は Android SDK の Platform-Tools に含まれる。
- まず入っているか確認: ターミナル(Windows は PowerShell / コマンドプロンプト)で
adb version。バージョンが表示されれば導入済み(Android Studio・Flutter・React Native などの モバイル開発環境を入れていれば、たいてい既に入っている)。 - 入っていなければインストール(いずれか):
- 公式の「SDK Platform-Tools」を Google からダウンロードして展開し、
adbのあるフォルダを PATH に追加する(developer.android.com の Platform-Tools 配布物。 Android Studio 全体を入れなくても、この zip 単体で使える)。 - パッケージマネージャでも可:
- Windows:
scoop install adb/choco install adb - macOS:
brew install --cask android-platform-tools - Linux:
sudo apt install adb(Debian / Ubuntu 系)など
- Windows:
- Android Studio を入れた場合の既定の場所:
- Windows:
%LOCALAPPDATA%\Android\Sdk\platform-tools\adb.exe - macOS:
~/Library/Android/sdk/platform-tools/adb - Linux:
~/Android/Sdk/platform-tools/adb
- Windows:
- 公式の「SDK Platform-Tools」を Google からダウンロードして展開し、
- PATH に通さない場合は、Android 用 config の
adb_pathに adb のフルパスを指定すればよい。adb_pathが空のときの自動検出は PATH →(Windows のみ)一般的な SDK の場所の順。 macOS / Linux では PATH しか見ないため、PATH に無ければadb_pathを指定すること。
adb version でバージョンが出れば準備の第一段階は完了。
- 端末で 開発者オプション → USB デバッグを ON。初回接続時に端末へ出る
認証ダイアログを「許可」(
adb devicesでdevice=OK /unauthorized=未許可)。 - 記録したい Chrome を端末で開いておく。
💡 端末が見つからない(
adb devicesが空)ときは、まず USB ポートを変えてみる。 PC 前面のポートは配線や電力の都合で不安定なことがあり、実測でも 前面ポートでは Windows が端末を USB デバイスとしてすら認識せず(デバイスマネージャにも出ない)、 背面(マザーボード直結)のポートに挿し替えたら即座に認識した例がある(Pixel 8a)。 この状態では USB デバッグを ON/OFF し直しても無駄なので、 背面ポート → 別のケーブル(充電専用ではなくデータ転送対応のもの)の順に試す。 ポートとケーブルを変えても出てこない場合に、初めて USB デバッグ設定や端末の USB モードを疑うとよい。
⚠ Android では
filter_enabled: trueを強く推奨。デスクトップは自分専用の プロファイルを起動するが、Android は自分の実機 Chromeに繋ぐため、個人利用のタブ (ネット銀行・通販・SNS)や**各種サービスへのログイン(認証セッション)**が同じ Chrome に同居していることが多い。フィルタ無効(全ページ記録)のままだと、それらの console まで記録され、特にoutput_dirを同期フォルダにするとクラウドへ流出しかねない。
filter_enabled: trueにしたら、記録したいサイトを必ずurl_filter_presets(単一サイトならurl_filter)に指定すること。指定が空のままだと「フィルタ設定なし」 の警告が出て全ページ記録にフォールバックし、絞り込みの意味がなくなる。記録対象は 各 preset のfilter(メインフレーム URL に含む文字列)で判定され、url_filter_presetsが優先・url_filterはフォールバック。ログイン/認証フローが複数ドメインにまたがる 場合は、必要なドメインを preset に並べておく。クラウドの AI へ渡す前にも中身を確認する。
glog.bat --config android :: Windows./glog.sh --config android # macOS / Linux→ adb で端末の DevTools を localhost:<port> に転送し、Android Chrome に
アタッチして記録を開始する。停止は Ctrl+C(終了時に転送も自動で解除)。
ℹ️
Ctrl+C以外(ターミナルを閉じる等)で落ちるとadb forwardが残ることがある(localhost のみで 実害は小さく、次回は "port in use" で気づける)。気になればadb forward --remove-allで消せる。
ℹ️ 画面を消しても・ロックしても記録は止まらない(iOS とはここが違う)。実測(Pixel 8a / Chrome 151、画面オフ+ロック中):
adb devicesはdeviceのまま、--checkは 3/3 で通り、 既に開いているページのコンソール出力もそのまま届いた。 ただしこの状態で新しいタブは開けない(Chrome がCould not create new pageを返す)。端末が
offlineになったときは、起動時に自動で待機してオンラインになり次第記録を始める。offlineは画面ロックそのものでは起きなかったので、出たときは USB の挿し直しやadb reconnectを試すとよい。
ℹ️ iOS はロックすると止まる。 端末の Safari のページが動かなくなるため、
source: "ios"で記録している間は端末をロックしない(自動ロックを切っておくと確実)。 同じ「USB 接続したスマホ」でも、Android(adb + CDP)と iOS(Web インスペクタ)で 条件が違う点に注意。
ℹ️ アタッチした瞬間、各タブがそれまで溜めていた console をまとめて再送するため、 接続直後はログが一気に出る(Chrome の仕様。DevTools を後から開くと過去ログが見えるのと同じ)。 重複やノイズが気になるときは、端末で不要なタブを閉じる、または接続後に ログファイルを削除すれば「今から」だけにできる。
⚠ ポートはデスクトップ版と分けること。
portが既に使われているとadb forwardは失敗する。本ツールは失敗を握りつぶさずエラー終了し、さらに 接続先が本当に端末か(Android Chrome か)を検証する。これは、別の Chrome が 同じポートを使っているときに誤って PC の Chrome へ繋いでしまう事故を防ぐため。
⚠️ この機能は実験段階です。 Safari の WebDriver BiDi は本稿執筆時点で実験扱いで、 内部で未公開のキャパビリティsafari:experimentalWebSocketUrlを要求している(これが無いと BiDi の WebSocket URL が返らない)。Safari 26.2 で動作確認済みだが、この解錠方法は Apple の 公式ドキュメントに記載が無く、Safari のバージョン更新で名称・挙動が変わる/使えなくなる可能性が ある。うまく繋がらない場合はまず Safari のバージョンと「リモートオートメーション」設定を確認すること。
Mac の Safari のコンソールも記録できる(source: safari)。Safari は CDP を
話さないため、Chrome 系とは別経路(macOS 同梱の safaridriver + WebDriver BiDi)で
コンソール/未捕捉例外を受け取り、同じテキストファイルに追記する。
Safari を自動化から制御するには、一度だけ次のいずれかを実施する(管理者権限が要る):
sudo safaridriver --enableまたは Safari > 設定 > 詳細 で「メニューバーに"開発"メニューを表示」を有効化 → Safari > 開発 > 「リモートオートメーションを許可」にチェック。
⚠ 本ツールは
safaridriver --enable(要 sudo)を自分では実行しない。上記は利用者が 一度だけ手で行う前提。これはセキュリティ上の昇格操作なので、意図せず有効化しないため。
config.safari.json の例(start_url は必須。理由は下記「最大の制限」):
{
"output_dir": "logs",
"source": "safari",
"start_url": "https://example.com/",
"timestamp": true
}./glog.sh --config safari https://example.com/ # 記録したいページを指定して起動自動化用の Safari ウィンドウが開き(「Safari は自動テストによって制御されています」の表示)、
指定した URL が読み込まれ、そのページのコンソール出力を記録する。停止は Ctrl+C(他ソースと同じ)。
Safari は自動化ウィンドウの上に 「グラスペイン」 と呼ばれる透明な膜をかぶせ、 マウス・キーボード操作を遮断する(WebKit 公式の設計: WebDriver Support in Safari 10 — "Safari installs a 'glass pane' over the Automation window while the test is running. This blocks any stray interactions (mouse, keyboard, resizing, and so on)")。 無理に操作するとダイアログが出て、そこで「セッションを停止」を選ぶと WebDriver セッションが切断され、記録も終了する。
したがって source: safari では、Chrome 版のように
「人間がブラウザを手で操作して不具合を再現し、そのログを記録する」ことはできない。
記録できるのは start_url で開いたページの読み込み時以降に出るログ(自動で発生する
コンソール出力・未捕捉例外など)に限られる。
手動操作しながらの記録は Chrome(
source: desktop/android)を使うこと。 Safari でも手動操作を可能にするには、WebDriver 以外の経路(Safari 拡張による コンソールのフック等)が必要で、これは将来対応の課題。
- URL フィルタは無効:Safari の BiDi ログにはページの識別情報が乗らないため、
url_filter/ プリセットはsource: safariでは無視され、全ページを記録する。 - 行番号プレフィックスが付かない:Safari はコンソール行にソース位置を付けないため、
Chrome 版のような
file.js:12の接頭辞は出ない(メッセージ本文はそのまま記録される)。 - ログイン状態を引き継がない:自動化ウィンドウは通常の Safari とは別プロファイル。
- macOS 専用:
safaridriverは macOS 同梱。Windows / Linux では使えない。 - WebDriver BiDi は現状 Safari では実験扱いのため、内部で
safari:experimentalWebSocketUrlを要求している。
USB 接続した iOS 実機の Safari のコンソールも記録できる(source: ios)。Android 版と同じ発想で、
端末を手に持って操作しながら、そのコンソール出力が PC 側のテキストファイルに流れ続ける。
Mac の Safari と違い手動操作の制約は無い(自動化ではなく Web Inspector に接続するため)。
root / sudo も tunnel も不要。実装は macOS / Windows / Linux で同じコードだが、 セットアップの手間は OS で大きく違う(macOS は pip だけ、Windows は追加で2つ要る)。 macOS / Windows は実機で検証済み(対応表の脚注4)。Linux は未検証。
macOS — pip だけでよい(usbmux が OS に内蔵されているため):
pip install -r requirements-ios.txt # pymobiledevice3(ios ソース専用。他の用途では不要)Windows — pip の前に、次の2つが要る:
- Apple Mobile Device Support(usbmux) … Windows には iOS 端末と話す仕組みが無いため、
Apple 製の usbmux(
AppleMobileDeviceProcess.exe、127.0.0.1:27015で待ち受け)が必要。 iTunes(Microsoft Store 版 / Apple 配布版)または Apple Devices アプリを入れると同時に入る。 iTunes を使う必要はなく、入れておくだけでよい。 - C++ コンパイラ(Build Tools for Visual Studio の「C++ によるデスクトップ開発」)
…
pymobiledevice3の依存pyimg4がlzfseを要求し、これにホイールが1つも無いため ソースからのビルドが要る。これは Windows / Linux だけの問題で、macOS はlzfseの代わりにapple-compressを使うため踏まない(pyimg4の依存がlzfse>=0.4.2; sys_platform != 'darwin'のため)。
pip install -r requirements-ios.txt導入できたか(端末を繋ぐ前に)確認する:
python -c "import asyncio; from pymobiledevice3.usbmux import list_devices; print(asyncio.run(list_devices()))"[] と表示されれば OK(=usbmux と会話できている。端末未接続なので空リスト)。
ここでエラーになる場合は上の 1.(Apple Mobile Device Support)が入っていない。
Linux は未検証(対応表の Linux 注記)。lzfse のビルドが要る点は
Windows と同じで、加えて usbmux デーモン(usbmuxd)が要る見込み。
💡
lzfseのビルドが「Unable to find a compatible Visual Studio installation」で失敗するとき。 Visual Studio を入れてあるのに出ることがある。setuptools は最新の VS を選ぶが、その VS にVC\Auxiliary\Build\vcvarsall.batが無いと詰まる(実測: VS 2022 Community に同ファイルが欠けており、 併存する Build Tools 2019 には揃っていた)。対処は、vcvars が揃っている方の環境を有効化してからDISTUTILS_USE_SDK=1を立てて(=setuptools に VS を再探索させず今の環境を使わせる)ビルドする:call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat" set DISTUTILS_USE_SDK=1 pip install -r requirements-ios.txt
requirements-ios.txt は pymobiledevice3>=10.2 を要求する。下げないこと。
10.2.0(2026-07-28)で CDP ブリッジが書き直され、それ以前の版は iOS 26 の端末に対して 次のように壊れる。いずれも静かに壊れるのが厄介で、症状はどれも同じに見える:
The device stopped responding (unplugged or locked?); recording stopped.
- 端末は生きている。 ブリッジ内部の受信ループが例外で死んでおり、以後どの CDP メッセージも 届かなくなる(生存確認の応答も来ないので「端末が落ちた」ように見える)。9.36.0 + iOS 26.5.2 で実測。
- 10.2.0 では他に、
/json/versionが正しい応答を返すようになった(それ以前はルートが隠れており、 ページ一覧が返っていた)。--checkの判定はこの両方の形を受け付ける。
上限は付けていない。 11.2.1 まで実機で確認済み。ただし 10.2 以降は console 出力に
ファイル名と行番号が乗らなくなったため、green_light 側で WebKit の値を補っている
(ソース gl_ios.py の _harden_cdp_target 参照)。
- USB 接続し、端末で「このコンピュータを信頼しますか?」→ 信頼(要ロック解除)
- 設定 → アプリ → Safari → 詳細 → 「Web インスペクタ」を ON (iOS 17 以前は 設定 → Safari → 詳細 → Web インスペクタ)
⚠️ console.*をラップする Safari 拡張は OFF にする。例えば App Store アプリ 「Web Inspector」は各ページにconsole.jsを注入してconsole.*を包むため、記録される 位置プレフィックスが常にその拡張のファイル(console.js:53など)になり、ページ本来のfile.js:12が分からなくなる。設定 → アプリ → Safari → 拡張機能 で OFF にすること。 OFF にしても、既に開いているページはリロードするまで注入が残る点に注意。- 記録したいページを 端末の Safari で開いておく(端末はロックしない)
config.ios.json の例:
{
"output_dir": "logs-ios",
"source": "ios",
"port": 9223,
"device_serial": "",
"timestamp": true
}./glog.sh --config ios # macOS / Linuxglog.bat --config ios :: Windows端末の Safari で開いているページに自動でアタッチし、以後そのページのコンソール出力・未捕捉例外を
記録し続ける。端末側で普通に操作すればよい。停止は Ctrl+C。
まず glog.bat --config <名前> --check(「コマンドライン引数」の節を参照)で、
usbmux / 信頼 / Web インスペクタのどこで止まっているかを見る。
⚠
--checkは通るのに、Safari を開くと「The device stopped responding」で止まる場合。 まずpip show pymobiledevice3でバージョンを見ること。10.2 未満なら、まずこれを疑う (端末は正常。上の「pymobiledevice3 のバージョン下限」参照。9.36.0 + iOS 26.5.2 で実測し、 更新して解消した)。--checkが通るのは、接続の確立までは古い版でも成功し、 壊れるのはその後の受信ループだから。pip install -U -r requirements-ios.txtで更新する。
iPhone の USB 接続(iOS 17+ の muxed mode)は、ケーブルと端末が正常でもソフト側の状態が固まることがある。
この状態は USB を挿し直しても解消しない。macOS のみ、その復旧を手順化した ios-recover.sh を同梱している。
./ios-recover.sh # config を指定しない場合はポート関連の段階を飛ばす
./ios-recover.sh ios # config.ios.json からポートを読む残っているプロセスの停止 → usbmuxd の再起動 → 端末側リセット、と影響の小さい順に案内する。
⚠ このスクリプトは
sudoを自分では実行しない。 usbmuxd の再起動には root が必要で、 かつ Mac 上の他の usbmux 利用者すべて(Finder の端末同期・Xcode・実行中のバックアップ等)を 巻き込む。そのためコマンドを表示するだけにとどめ、実行するかは利用者が判断する (safaridriver --enableと同じ方針)。プロセスの停止も、対象を一覧表示して確認を取ってから行う。
Windows には usbmuxd が無く、代わりに Apple Mobile Device Service が同じ役割を担うため、
このスクリプトは動かない(実行すると macOS 専用である旨を表示して終了する)。services.msc から
同サービスを再起動し、端末を挿し直すこと。
start_urlは無視される:PC 側から端末の Safari にページを開かせない(端末で自分で開く)。- 端末の Safari で開いているページだけが対象。端末がロックされるとページが止まる。
- URL フィルタは使える(
url_filter/ プリセット)。 - タブごとに接続する方式のため、ページのリロード直後は数秒アタッチが遅れることがある。
ログにはトークン・API キー・個人情報が混じり得る(実際に、実機ログに Supabase の apikey=… が
出た)。redact_patterns に正規表現のリストを書くと、一致部分を *** に置換して記録する。
"redact_patterns": [
"apikey=[A-Za-z0-9_\\-]+",
"eyJ[A-Za-z0-9_\\-]{10,}\\.[A-Za-z0-9_\\-]+\\.[A-Za-z0-9_\\-]+"
]WebSocket connection to 'wss://…/websocket?***&vsn=2.0.0' failed
⚠️ これはベストエフォートであり、安全の保証ではない。 正規表現では必ず取りこぼす (独自形式のトークン、文中に紛れた ID、日本語の個人情報など)。「マスク済みだから安全」と考えず、 クラウド AI に渡す前・出力フォルダを同期する前に、これまでどおり中身を確認すること。 自分のアプリのトークン形式を知っている人が、それを機械的に落とすための機能である。 既定は無効([])で、指定しない限り挙動は一切変わらない。
- Chrome を
--remote-debugging-port+ 専用--user-data-dirで起動する (Chrome 136 以降、既定プロファイルではリモートデバッグが無効化されるため専用プロファイルを使用) - 接続側で Origin ヘッダを抑制して CDP に接続(
--remote-allow-origins=*は付けず、403 origin 拒否を回避) - CDP にブラウザレベルで1接続し、
Target.setAutoAttach(flatten)で全ページに自動アタッチ Runtime.consoleAPICalled/Runtime.exceptionThrown/Log.entryAddedを受け取り、 ファイルへ追記する(書き込みのたびに開閉するのでハンドルを保持せず、記録中でも削除可能)
- 専用プロファイルのため、普段使いの Chrome のログイン情報・拡張機能は引き継がれない。 必要なサイトには初回ログインが要る(プロファイルは保存されるので2回目以降は不要)。
profile_dirを同期フォルダ(Drive/Dropbox 等)の中に置くと肥大化・競合の恐れが あるため、既定どおりこのプロジェクトフォルダ内に置くのを推奨。config.jsonと.chrome-debug-profile/、logs/は.gitignore済み(コミットされない)。
開発者が自分のマシンで使う前提のツールです。設計上のポイント:
- デバッグポートは localhost のみ。
--remote-debugging-portは127.0.0.1にバインドされ、 LAN/外部には公開されません(--remote-debugging-addressは付けていません)。 - 全オリジン許可はしない。本ツールは Origin ヘッダ無しで接続するため
--remote-allow-origins=*は不要で、付けていません。これにより Chrome 既定の Origin チェックが有効なまま=悪意ある Web ページがデバッグポートへ CDP 接続して当ブラウザを操作することを防ぎます。 - Chrome のサンドボックスを弱めない。
--no-sandboxや--disable-web-securityは使いません。 - Android 記録も localhost 限定。
adb forwardはホスト側127.0.0.1にのみバインドするため、 端末を記録する場合も CDP が LAN/外部に出ることはありません。 - Safari 記録も localhost 限定。
safaridriverの WebDriver サーバと BiDi WebSocket は127.0.0.1にバインドされ、本ツールもそこへのみ接続します。safaridriver --enable(要 sudo)は 利用者が一度だけ手で行う前提で、本ツールは実行しません。 - iOS 記録も localhost 限定・非特権。端末の Web Inspector を CDP に橋渡しするサーバは
127.0.0.1にバインドします(LAN には出しません)。root / sudo も tunnel も使いませんし、 デベロッパーディスクイメージのマウントもしません。 - 昇格が要る操作は「表示するだけ」。
safaridriver --enableも、ios-recover.shが案内するsudo pkill usbmuxdも、本ツール/同梱スクリプトが自分で実行することはありません。 影響(前者は Safari の自動化許可、後者は Mac 上の全 usbmux 利用者の切断)を理解した上で 利用者が実行するべきものだからです。
運用側で気をつけること:
- 記録中、デバッグ用 Chrome は同一PC上のローカルプロセスからは操作可能な状態です。 共有PCや信頼できない環境では、使い終わったらウィンドウを閉じてください。
.chrome-debug-profile/には**ログインセッション(Cookie/トークン)**が保存されます。 クラウド同期フォルダに置かない・他者と共有しないこと。- 出力ログ自体に機微情報(トークン・個人情報など)が混じる場合があります。クラウドの AI へ
渡す前・出力フォルダを同期する前に中身を確認してください。
redact_patterns(任意)で既知の パターンを***に落とせますが、ベストエフォートであり確認の代わりにはなりません。 config.jsonのchrome_exe/adb_path/safaridriver_path(いずれも起動する実行ファイル)と URL は信頼できる値に保つこと。他者から受け取った/同期されてきた config をそのまま使わない (実行ファイルや出力先が差し替えられ、任意プログラム実行・任意の場所への書き込みになり得るため)。
コミットメッセージの書き方、ブランチ運用、言語の決まり(コードと画面表示は英語・ この日本語 README が原本)、崩してはいけない不変条件、変更の確かめ方は CONTRIBUTING.md にまとめてある。フォークして直すときも、 別のマシンから触るときも、まずこれを読めば足りるようにしてある。
MIT License で公開。自由に利用・改変・再配布できます(無保証)。
{ "source": "android", "port": 9333, // ← デスクトップ版の 9222 と必ず分ける(後述) "adb_path": "", // 空 = 自動検出 "device_serial": "", // 空 = 唯一の端末 / 複数なら adb devices の serial "output_dir": "logs-android", "log_filename": "console.log", "filter_enabled": true, // ← Android では ON を強く推奨(下記) "url_filter_presets": [ // ← 記録したいサイトをここに必ず列挙(filter = URL に含む文字列) { "label": "my app", "filter": "example.com", "url": "https://example.com/" }, { "label": "auth", "filter": "accounts.example.com", "url": "" } ] }