axiom-xclog-ref について
xclogを扱うリファレンススキルです。依存関係のないバイナリでiOSシミュレーターのコンソールログを取得し、接続デバイスの過去ログも検索できます。開発者のクラッシュや無言の失敗、Swiftログの調査に役立ちます。
主な機能
- 01print、debugPrint、NSLog、os_log、Loggerの取得
- 02シミュレーター内のインストール済みアプリ一覧
- 03アプリ起動とログ監視
- 04シミュレーターまたはデバイスの最近のログ検索
- 05出力のフィルタリングと収集時間・行数の制限
活用シーン
- 01アプリのクラッシュ直前のログ確認
- 02画面に現れない失敗の追跡
- 03サブシステムやレベル別の構造化ログ確認
- 04デバッグ用のログストリーム収集範囲の指定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-xclog-refインストール後、Claude Code で/axiom-xclog-refを入力して読み込まれたか確認します。
詳細
xclog リファレンス(iOS Simulator コンソールキャプチャ)
xclog は、simctl launch --console(print/debugPrint/NSLog)と log stream --style json(os_log/Logger)を組み合わせて、iOS Simulator のコンソール出力をキャプチャします。単一のバイナリで、依存関係はありません。
バイナリの場所
${CLAUDE_PLUGIN_ROOT}/bin/xclog
使用する場面
- 実行時のクラッシュ — クラッシュ前にアプリが出力したログをキャプチャします
- サイレントな失敗 — UI にフィードバックが表示されないネットワーク呼び出しやデータ操作の失敗
- print() 出力のデバッグ — アプリが stdout/stderr に出力している内容を確認します
- os_log の分析 — サブシステム、カテゴリ、レベルでフィルタリングする構造化ログ
- ログの自動キャプチャ —
--timeoutと--max-linesで収集範囲を制限します
重要なベストプラクティス
まず .axiom/preferences.yaml を確認してください。 保存された設定がない場合は、正しいバンドル ID を見つけるために launch の前に list を実行してください。
アプリはすでに実行中ですか? launch はアプリを終了して再起動します。現在の状態を維持する必要がある場合は attach を使用してください(os_log のみ — print() はキャプチャされません)。
# 1. FIRST: Check .axiom/preferences.yaml for saved device and bundle ID
# 2. If no preferences: Discover installed apps
${CLAUDE_PLUGIN_ROOT}/bin/xclog list
# 3. Find the target app's bundle_id from output
# 4. THEN: Launch with the correct bundle ID (restarts app)
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch com.example.MyApp --timeout 30s --max-lines 200
# OR: Attach to running app without restarting (os_log only)
${CLAUDE_PLUGIN_ROOT}/bin/xclog attach MyApp --timeout 30s --max-lines 200
設定
Axiom はシミュレーターの設定をプロジェクトのルートにある .axiom/preferences.yaml に保存します。xclog list を実行する前にこのファイルを確認してください — 設定が存在する場合は、保存されたデバイスとバンドル ID をそのまま使用してください。
設定の読み取り
xclog list を実行する前に、.axiom/preferences.yaml を読み取ります。
simulator:
device: iPhone 16 Pro
deviceUDID: 1A2B3C4D-5E6F-7890-ABCD-EF1234567890
bundleId: com.example.MyApp
ファイルが存在し、simulator セクションが含まれている場合は、xclog コマンドで保存された deviceUDID と bundleId を使用してください。別のアプリをユーザーが指定した場合、または保存された値が無効な場合を除き、xclog list は実行しないでください。
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch <bundleId> --device <deviceUDID> --timeout 30s --max-lines 200
ファイルが存在しない場合、または simulator セクションがない場合は、xclog list による検出に切り替えてください。
保存された deviceUDID が使用可能なシミュレーターに見つからない場合(xclog または simctl が失敗する場合)は、検出に切り替えて新しい選択内容を保存してください。
YAML の形式が正しくない場合は、開発者に警告し、検出に切り替えてください。形式が正しくないファイルを上書きしないでください。
設定の書き込み
xclog launch が成功した後、またはユーザーが xclog list の出力から対象アプリを選択したときに、デバイスとバンドル ID を保存します。
.axiom/が存在しない場合は作成します。その後、.gitignoreを確認します。ファイルが存在する場合は、.axiom/と完全に一致する行があるか確認し、なければ新しい行に.axiom/を追加します。.gitignoreが存在しない場合は、内容を.axiom/として作成します。- 他のキーを保持するため、
.axiom/preferences.yamlが存在する場合は読み取ります simulator:セクションをdevice、deviceUDID、bundleIdで更新します- Write ツールを使って、マージした YAML を書き込みます
上記の「設定の読み取り」に示したものと同じ simulator: 構造を書き込んでください。
コマンド
list — インストール済みアプリの検出
${CLAUDE_PLUGIN_ROOT}/bin/xclog list
${CLAUDE_PLUGIN_ROOT}/bin/xclog list --device <udid>
出力(JSON 行):
{"bundle_id":"com.example.MyApp","name":"MyApp","version":"1.2.0"}
{"bundle_id":"com.apple.mobilesafari","name":"Safari","version":"18.0"}
launch — コンソール出力をすべてキャプチャ
アプリを起動し、print()、debugPrint()、NSLog()、os_log()、Logger の出力をすべてキャプチャします。
# Basic launch (JSON output, runs until app exits or Ctrl-C)
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch com.example.MyApp
# Bounded capture (recommended for LLM use)
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch com.example.MyApp --timeout 30s --max-lines 200
# Filter by subsystem
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch com.example.MyApp --subsystem com.example.MyApp.networking
# Filter by regex
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch com.example.MyApp --filter "error|warning|crash"
# Save to file
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch com.example.MyApp --output /tmp/console.log --timeout 60s
attach — 実行中のプロセスを監視
os_log のみを使って実行中のプロセスに接続します。print()/debugPrint() はキャプチャしません。Simulator のみで使用できます。
# By process name
${CLAUDE_PLUGIN_ROOT}/bin/xclog attach MyApp --timeout 30s
# By PID
${CLAUDE_PLUGIN_ROOT}/bin/xclog attach 12345 --max-lines 100
# Filter for errors only
${CLAUDE_PLUGIN_ROOT}/bin/xclog attach MyApp --filter "(?i)error|fault"
show — 過去のログ検索(Simulator + 実機)
事前にキャプチャを開始しなくても、最近のログを検索できます。シミュレーターと接続済みの実機の両方で動作します。
# Simulator: show last 5 minutes of MyApp logs
${CLAUDE_PLUGIN_ROOT}/bin/xclog show MyApp --last 5m --max-lines 200
# Simulator: show last 10 minutes, errors only
${CLAUDE_PLUGIN_ROOT}/bin/xclog show MyApp --last 10m --max-lines 100 --filter "(?i)error|fault"
# Physical device: collect and show logs (device must be connected + unlocked)
${CLAUDE_PLUGIN_ROOT}/bin/xclog show MyApp --device-udid 00008101-... --last 5m --max-lines 200
# By PID
${CLAUDE_PLUGIN_ROOT}/bin/xclog show 12345 --last 2m
実機でのワークフロー:show --device-udid は log collect を実行し、USB 経由でデバイスからログアーカイブを取得して、ローカルで解析します。デバイスは接続され、ロック解除されている必要があります。
show と attach の使い分け:
show— 「たった今、何が起きましたか?」(事後調査。事前準備は不要です)attach— 「今、何が起きていますか?」(ライブストリーミング。イベント発生前に実行しておく必要があります)
出力形式
デフォルトの出力は JSON 行(1 行につき 1 つの JSON オブジェクト)です。
JSON Schema(デフォルト)
{
"time": "10:30:45.123",
"source": "os_log",
"level": "error",
"subsystem": "com.example.MyApp",
"category": "networking",
"process": "MyApp",
"pid": 12345,
"text": "Connection failed: timeout"
}
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
| time | string | 常に | HH:MM:SS.mmm タイムスタンプ |
| source | string | 常に | "print"、"stderr"、または "os_log" |
| level | string | os_log のみ | "debug"、"default"、"info"、"error"、"fault" |
| subsystem | string | os_log のみ | 逆 DNS 形式のサブシステム(例:com.example.MyApp) |
| category | string | os_log のみ | サブシステム内のログカテゴリ |
| process | string | os_log のみ | プロセスのバイナリ名 |
| pid | int | os_log のみ | プロセス ID |
| text | string | 常に | ログメッセージの内容 |
ソースに該当しないフィールドは省略されます(null にはなりません)。
人が読みやすい形式
${CLAUDE_PLUGIN_ROOT}/bin/xclog attach MyApp --human
${CLAUDE_PLUGIN_ROOT}/bin/xclog attach MyApp --human --no-color
オプション一覧
| オプション | デフォルト | 説明 |
|---|---|---|
--device <udid> | booted | 対象のシミュレーター UDID |
--device-udid <udid> | none | 物理デバイスの UDID(show コマンド) |
--output <file> | stdout | ファイルにも出力 |
--human | off | 人が読みやすい色付き出力 |
--no-color | off | ANSI カラーを無効化(--human モード) |
--filter <regex> | none | Go 正規表現で行をフィルタリング |
--subsystem <name> | none | サブシステムで os_log をフィルタリング |
--max-lines <n> | 0 (unlimited) | n 行後に停止 |
--timeout <duration> | 0 (unlimited) | 指定時間後に停止(例:30s、5m) |
--last <duration> | 5m | どこまで遡って検索するか(show コマンド) |
ソース別の対応状況
| Swift API | launch | attach | show |
|---|---|---|---|
print() | yes | no | no |
debugPrint() | yes | no | no |
NSLog() | yes | yes | yes |
os_log() | yes | yes | yes |
Logger | yes | yes | yes |
| シミュレーター | 物理デバイス | |
|---|---|---|
launch | yes | no |
attach | yes | no |
show | yes | yes |
Logger | yes | yes |
すべてのログを取得するには launch を使用してください。 attach は、すでに実行中のプロセスを監視するためのものです。
注:launch は、アプリを再起動する前に既存のインスタンスを終了します。アプリがすでに実行中で、再起動したくない場合は attach を使用してください(os_log のみ)。
エラー動作
xclog はエラーを stderr に出力し、コード 1 で終了します。一般的なエラーは次のとおりです。
| エラー | 原因 | 対処法 |
|---|---|---|
simctl launch: ... | バンドル ID が不正、または起動中のシミュレーターがない | xclog list を実行してバンドル ID を確認し、xcrun simctl list devices booted を確認してください |
could not parse PID from simctl output | アプリの起動に失敗しました | アプリがビルドでき、シミュレーターで実行できることを確認してください |
invalid filter regex | --filter パターンが不正です | Go の正規表現構文(RE2 に類似)を確認してください |
invalid subsystem | サブシステムに空白または特殊文字が含まれています | 逆 DNS 形式を使用してください:com.example.MyApp(英数字、ピリオド、アンダースコア、ハイフンのみ) |
出力の解釈
レベルによるフィルタリング
os_log のレベルは重大度を示します。クラッシュの診断では、error と fault に注目してください。
注:--filter は JSON 出力ではなく、メッセージテキストに対して照合します。レベルでフィルタリングするには jq を使用してください。
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch com.example.MyApp --timeout 30s 2>/dev/null | jq -c 'select(.level == "error" or .level == "fault")'
テキストベースのフィルタリングでは、--filter はメッセージ内容に対して機能します。
# Filter messages containing "error" or "failed" (case-insensitive)
${CLAUDE_PLUGIN_ROOT}/bin/xclog launch com.example.MyApp --filter "(?i)error|failed"
一般的なサブシステムパターン
| サブシステム | 示す内容 |
|---|---|
com.apple.network | URLSession/ネットワーキングレイヤー |
com.apple.coredata | Core Data/永続化 |
com.apple.swiftui | SwiftUI フレームワーク |
com.apple.uikit | UIKit フレームワーク |
| アプリ独自のサブシステム | アプリケーションレベルのログ |
ワークフロー:実行時クラッシュの診断
xclog list→ バンドル ID を確認しますxclog launch <bundle-id> --timeout 60s --max-lines 500 --output /tmp/crash.log→ 取得を開始します(アプリが再起動されます。これは想定どおりです)- シミュレーターでクラッシュを再現します
/tmp/crash.logを読み込み、エラーをフィルタリングします:jq 'select(.level == "error" or .level == "fault")' /tmp/crash.log- ストリーム終了直前の数行を確認します(クラッシュ発生箇所)
クラッシュが断続的に発生する場合は、上限を増やして --timeout 120s --max-lines 1000 に設定し、再試行してください。
ワークフロー:サイレント障害を調査する
xclog launch <bundle-id> --subsystem com.example.MyApp --timeout 30s- 失敗する操作を実行します
- アプリのサブシステムでエラーレベルのメッセージを探します
- アプリのログに何も記録されていない場合は、ネットワークまたはデータのサブシステムと照合します
リソース
スキル:axiom-xcode-debugging、axiom-performance-profiling、axiom-lldb