Claude Media
ClaudeでGASのエラーログを調べる — clasp logsの出力を-pに渡す

ClaudeでGASのエラーログを調べる — clasp logsの出力を-pに渡す

GASの実行エラーは、clasp logsで取ったCloud Loggingの出力をclaude -pに渡すと原因行を絞れます。console.logしか出ない点と事前設定も解説します。

GASの実行エラーは、clasp logsで取り出したCloud Loggingの出力をclaude -pの標準入力に渡すと、原因の行を絞り込めます。ブラウザのエディタを開かず、ターミナルだけで「ログを取る、渡す、読む」が完結します。

ただしclasp logsが出すのはconsole.log系のログだけです。Logger.logは対象外で、GCPプロジェクトの紐づけも要ります。ここを外すと、Claudeに渡す以前に何も出力されません。この記事は、その前提の整え方と、渡し方、渡したあとの切り分けまでを順に扱います。

clasp logsとは何を取り出すコマンドか

clasp logsは、Apps ScriptのCloud Loggingに溜まった直近のログを標準出力へ表示するコマンドです。claspのREADMEは、対象を「console.logのログであってLogger.logではない」と明記しています。オプションは3つです。

オプション役割
--json役割ログをJSON形式で出力する
--watch役割最新のログを5秒ごとに取得し続ける
--simplified役割ログからタイムスタンプを除く

READMEの出力例は、重大度、日時、関数名、メッセージが1行に並ぶ形です。次はREADMEにある例で、自分のプロジェクトの実出力ではありません。

clasp logs
ERROR Sat Apr 07 2019 10:58:31 GMT-0700 (PDT) myFunction      my log error
INFO  Sat Apr 07 2019 10:58:31 GMT-0700 (PDT) myFunction      info message

1行に重大度と関数名が揃っているので、ERRORの行を拾うだけでも手がかりになります。ただ、行が数百に増えると目視では追えません。そこでClaudeの出番になります。

READMEには表記のずれが1つあります。コマンド一覧の「Advanced Commands」ではclasp tail-logsと書かれ、詳細の節はclasp logsの見出しです。3.x系の改名表にもlogs --openがopen-logsへ変わる行があります。手元のclaspで動くほうを使うのが確実で、clasp --helpの一覧で名前を確かめられます。この記事は詳細の節に合わせてclasp logsと書きます。

先に整える3つの前提

ログが空になる原因の大半は、コマンドの使い方ではなく前提の不足です。

手順

clasp logsを動かすまでの準備

  1. 1

    標準のGCPプロジェクトに紐づける

    Cloud Loggingのログは、Apps Scriptに関連づいたGoogle Cloudプロジェクトに付きます。Apps Scriptのダッシュボードでは簡略版が見えますが、Google Cloudコンソールで直接見られるのは標準のGoogle Cloudプロジェクトを使う場合です。

  2. 2

    Cloud Logging APIを有効にする

    READMEは、ログを読むのにlogging.googleapis.com(Cloud Logging API)が必要だと挙げています。自前のOAuthクライアントを使う場合は、Apps Script APIなどと並べて有効化します。

  3. 3

    projectIdをclaspに教える

    clasp setup-logsは、スクリプトにGCPプロジェクトIDが設定されているかを確かめるコマンドです。.clasp.jsonのprojectIdに入るIDで、設定されていなければclaspが必要な場面でプロンプトを出して聞きます。

3つ目は.clasp.jsonを手で書く形でも構いません。

clasp setup-logs
clasp logs --simplified

setup-logsには--jsonもあります。Claudeにセットアップごと任せる場合は、.clasp.jsonにprojectIdを書く手順をCLAUDE.mdに残しておくと、毎回聞き返されずに済みます。

出力をclaude -pに渡して原因行を絞る

Claude Codeの-p(--print)は、対話せずに1回で答えを返す非対話モードです。標準入力を読めるため、他のコマンドの出力をパイプで渡せます。公式の例も、ビルドログをcat build-error.txt | claude -p '...'の形で渡し、結果をファイルへ書き出しています。

clasp logsをその形に当てはめると、次の1行になります。

clasp logs --simplified | claude -p \
  'ERROR の行だけを拾い、関数名ごとに原因の候補を1行で書いてください。\
推測は推測と明記し、ログに無い事実は足さないでください'

--simplifiedでタイムスタンプを落とすと、同じメッセージが並んだときの重複が見やすくなります。時刻が要る調査では付けたままにします。

絞り込みを繰り返すなら出力を一度ファイルに置く

原因を追うときは、プロンプトを変えて何度も聞き直します。毎回clasp logsを叩くとログが入れ替わってしまうため、一度ファイルに保存して同じ材料を見せ続けるほうが比較しやすくなります。

clasp logs --json > gas-logs.json
claude -p 'gas-logs.json を読み、ERROR の関数名と件数を表にして'

--jsonの中身の構造はREADMEに例が載っていません。キー名を前提にしたプロンプトは書かず、「このファイルを読んで」と任せ、Claudeに構造を見てもらう形が安全です。

結果をスクリプトで使うなら出力形式を指定する

claude -pは--output-format jsonで結果をJSONにでき、jq -r '.result'で本文だけ取り出せます。--json-schemaを併用すると、structured_output欄に決まった形の結果が入ります。次は、エラーの関数名と原因候補を配列で受ける例です。

clasp logs --simplified | claude -p \
  'ERROR を関数名と原因候補にまとめて' \
  --output-format json \
  --json-schema '{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"function":{"type":"string"},"cause":{"type":"string"}},"required":["function","cause"]}}},"required":["errors"]}' \
  | jq '.structured_output'

公式は、有効な構造化出力が得られなかった場合にstructured_output欄が無くなると説明しています。スクリプトで使う前に、欄の有無を確かめる処理を入れます。またclaude -pは成功時に終了コード0、失敗時に非ゼロで終わるため、定期実行のシェルでも成否で分岐できます。

渡せないケースに備える

  • --watchは向かない: 5秒ごとに取得し続けるモードで、一度に渡す用途には通常のclasp logsを使います
  • 標準入力は10MBまで: 超えると非ゼロ終了でエラーになります。大きいときはファイルに保存し、パスをプロンプトに書きます
  • CIで回すなら--bare: ホストのフック・プラグイン・メモリー・CLAUDE.mdを読まずに起動できます

ログに残らないエラーは別の入口で見る

clasp logsの出力が静かなのに実行は失敗している場合があります。理由は、ログの種類が3つに分かれているためです。

仕組み特徴
実行ログ(組み込み)特徴軽量でリアルタイムに流れるが、残る期間は短い
Cloud Logging特徴数日にわたって残る。複数人が使う本番向き
Error Reporting特徴実行中のエラーを集めて表示する

clasp logsが読むのは真ん中のCloud Loggingです。ここに流れるかどうかが調査の分かれ目になります。

切り分け

clasp logsに何も出ないときの切り分け

  1. Qコードのログ出力が console.log / console.error になっている?
    答えがいいえのとき

    Logger.logの出力はclasp logsの対象外です。調べたい箇所をconsole.logに直してもらい、clasp pushしてから実行し直します。Rhinoランタイムでは、Cloud LoggingがLoggerサービスをサポートしないため、consoleへの置き換えが必須です。

    答えがはい
  2. Qスクリプトは標準のGoogle Cloudプロジェクトに紐づいている?
    答えがいいえのとき

    既定のプロジェクトのままでは、Google Cloudコンソールでの詳しい絞り込みができません。標準プロジェクトに切り替え、clasp setup-logsでIDを設定し直します。

    答えがはい
  3. QCloud Logging APIは有効?
    答えがいいえのとき

    logging.googleapis.comが無効だと、claspはログを読めません。GCPプロジェクト側で有効化します。

    答えがはい
  4. Q例外のログ記録が有効?
    答えが古いプロジェクトで未設定

    新しいプロジェクトでは、捕捉されなかった例外のCloud Loggingへの送信が既定で有効です。古いプロジェクトでは、プロジェクトの設定にある「Log uncaught exceptions to Cloud Operations」をオンにします。

    答えがはい

それでも出ないとき

Apps Scriptの左メニュー「Executions」を開き、ステータスで「Failed」と「Timed out」にフィルタをかけます。失敗した実行がここに並ぶので、その行を開いて内容をClaudeに貼ります。

「Timed out」が並ぶ場合は、エラーではなく実行時間の上限に当たっている可能性があります。その直し方はClaudeでGASの6分制限を分割実行に直す依頼の出し方にあります。

ClaudeがログからGASのバグを直しやすくなる出し方

ログを読ませる前に、ログの側を調べやすく整えておくと精度が変わります。ここは方針を決めておく作業で、Claudeに任せる部分です。

console.errorにはErrorオブジェクトを渡す

公式のログ解説は、例外が投げられたとき、またはconsole.errorにErrorオブジェクトを渡したとき、Apps ScriptがError Reportingに必要な項目を自動で入れると説明しています。文字列だけでconsole.errorするより、スタックトレースが付いた形でCloud Loggingに残ります。

CLAUDE.mdには、たとえば次のように書けます。これは書き方の例です。

## GASのログ規約
- 例外は catch で握りつぶさず、console.error(e) で Error オブジェクトごと出す
- Logger.log は使わず console.log / console.error に統一する
- メールアドレスなど個人情報はログに出さない

個人情報はログに出さない

ログはClaudeに渡す前に、まずCloud Loggingに残ります。公式のログ解説は、ユーザーのメールアドレスなどの個人情報を記録しないことを推奨しています。ユーザーを特定したいときは、ログに自動で付く一時的なアクティブユーザーキー(script.googleapis.com/user_keyラベル)を使えます。スクリプト内ではSession.getTemporaryActiveUserKey()で取得し、利用者に表示して不具合報告へ添えてもらう使い方が挙げられています。

clasp logsの出力は、そのまま外部のAPIへ送られる点にも注意が要ります。個人情報が混ざりそうなログは、渡す前にgrep -vなどで該当行を除くか、渡すログを関数単位に絞ります。

保持期間と上限は別ページで確かめる

Cloud Loggingのログは数日にわたって残るとされます。具体的な保持期間やクォータは、Cloud Loggingのクォータと制限のページが正で、追加が要るときはGoogle Cloudのクォータ申請を出します。調査を数週間前までさかのぼる前提で運用を組まないほうが安全です。

調査の流れを3ステップにまとめる

実際の運用では、次の順に進めると手戻りが少なくなります。

手順

GASの実行エラーを調べる流れ

  1. 1

    失敗した実行を見つける

    Executionsで「Failed」「Timed out」に絞り、失敗した時刻と関数名を控えます。

  2. 2

    その時刻のログを取って渡す

    clasp logs --simplified | claude -p '...'で、ERROR行の関数名と原因候補を出させます。

  3. 3

    コードを直してpushし、再実行する

    原因候補をコードと突き合わせて直し、clasp pushのあとで同じ操作を再実行します。直ったかどうかは、同じ関数のERROR行が消えたかで確かめます。

clasp pushまでの手順はClaude CodeでGAS開発を進める手順に書いてあります。ログを渡して調べる発想は、AWSでも同じ型で使えます。ClaudeにCloudWatch Logsのクエリを書かせ、Lambdaのエラー急増を調べるは、その例です。

よくある質問

トリガーで動いた実行の失敗も、clasp logsで追えますか

READMEが説明しているのはCloud Loggingのconsole.logだけで、実行の種類ごとの取り込み範囲には触れていません。トリガー実行の失敗はExecutionsの一覧と合わせて見ます。

claude -pに渡すとログがAnthropicに送られますか

claude -pはClaudeにプロンプトを送って応答を得る仕組みなので、標準入力で渡した内容もプロンプトの一部として扱われます。渡す前に個人情報を除くのはこのためです。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/headless
  2. github.com/google/clasp
  3. developers.google.com/apps-script/guides/logging
この記事を共有:XはてブLinkedIn