Local debugging guide for Extend Event Handler
注釈:本資料はAI技術を用いて翻訳されています。
このガイドの例とファイル参照は、AccelByte Extend Event Handler アプリテンプレートに基づいています。 独自にサービスをゼロから構築した場合でも、基本的な考え方は同様に適用されます。プロジェクトに合わせてファイルパス、タスク名、スクリプト名を調整してください。
概要
このガイドでは、ローカルマシンで Extend Event Handler アプリをデバッグする方法を説明します。
すべての Extend アプリタイプに共通するデバッグの概念(環境変数のセットアップ、VS Code のデバッグワークフロー、ログの読み方、よくある起動時エラーなど)については、 Extend ローカルデバッグガイドを参照してください。
このガイドでは Visual Studio Code(VS Code) を中心に説明しますが、ここで説明する考え方はどのエディタや IDE にも適用できます。
言語固有のセットアップ(前提条件、プロジェクト構成、実行コマンド、デバッガー設定)については、使用している言語のページに直接移動してください。
イベントがサービスを通過する流れ
すべての Extend Event Handler アプリは、言語に関係なく同じイベント駆動型のスタック上に構築されています。 この流れを理解することで、問題の発生箇所を特定しやすくなります。
AGS User Action (e.g., login)
│
▼
AGS Kafka Topic ← AGS publishes domain events here automatically
│
▼
Kafka Connect ← bridges Kafka to gRPC; managed by AGS infrastructure
│ gRPC
▼
gRPC Server (port 6565) ← your event handler logic lives here
│
▼
AccelByte AGS Services ← your handler calls back into AGS (e.g., grant an item)
Extend Service Extension との主な違い: サービスの前段に HTTP ゲートウェイがありません。
イベントは Kafka Connect 経由の gRPC のみを通じて届きます。REST エンドポイントのようにブラウザや curl でハンドラーをトリガーすることはできません。
代わりに grpcurl を使って受信イベントをシミュレートするか、AGS で実際のイベントをトリガーします(例: テストユーザーとしてログインする)。
ポートの概要:
| ポート | 用途 |
|---|---|
6565 | gRPC サーバー — Kafka Connect からイベントを受信し、grpcurl のテスト呼び出しを受け付けます |
8080 | Prometheus メトリクスエンドポイント(/metrics) |
問題が発生した場合は、レイヤーごとに原因を追跡してください。
| 症状 | 最も可能性の高いレイヤー | 最初に確認すべき場所 |
|---|---|---|
| サービスが起動しない | 環境変数 / 認証情報 | .env ファイル、ITEM_ID_TO_GRANT、IAM クライアント認証情報 |
| ハンドラーが一度も呼び出されない | Kafka Connect が未設定または未起動 | AGS Kafka Connect の設定、ポート 6565 への到達可能性 |
| ハンドラーは呼び出されるがエラーを返す | ビジネスロジック / AGS API 呼び出し | ハンドラーファイル、エンタイトルメント / フルフィルメントの呼び出し |
| AGS API 呼び出しが失敗する | ネームスペースの誤り、権限不足、または認証情報の誤り | AB_NAMESPACE、IAM クライアントの権限 |
| デバッガーが一時停止しない | ポートの競合またはビルドモード | ポート 6565 で実行中のプロセスを確認 |
| Proto の変更が反映されない | 生成されたコードが古い | protobuf バインディングを再生成 |
環境のセットアップ
共通の変数(AB_BASE_URL、AB_CLIENT_ID、AB_CLIENT_SECRET、PLUGIN_GRPC_SERVER_AUTH_ENABLED、LOG_LEVEL)と .env ファイルの作成・確認方法については、
汎用ガイドの環境のセットアップを参照してください。
Extend Event Handler 固有の変数
Extend Event Handler では、さらに 2 つの環境変数が必要です。
# The game namespace to operate in.
AB_NAMESPACE=<your-namespace-id>
# The in-game item ID that will be granted when a user logs in.
# Must exist in a published store in the namespace above.
ITEM_ID_TO_GRANT=<item-id-from-published-store>
| 変数 | 用途 | 例 |
|---|---|---|
AB_NAMESPACE | 操作対象のゲームネームスペース | mygame |
ITEM_ID_TO_GRANT | ログインイベント時に付与するアイテム ID | item_abc123 |
サービスをローカルで実行する
VS Code のタスクおよびターミナルでの実行手順については、汎用ガイドの サービスをローカルで実行するを参照してください。
サービスが起動していることを確認する
サービスが正常に起動すると、次のようなログ出力が表示されます。
{"time":"...","level":"INFO","msg":"starting app server..","service":"extend-app-event-handler"}
{"time":"...","level":"INFO","msg":"gRPC reflection enabled"}
{"time":"...","level":"INFO","msg":"serving prometheus metrics","port":8080,"endpoint":"/metrics"}
{"time":"...","level":"INFO","msg":"gRPC server started"}
{"time":"...","level":"INFO","msg":"app server started"}
使用言語ごとの正確なターミナルコマンドについては、言語別ガイドを参照してください。
デバッガーをアタッチする
VS Code でのデバッガーのアタッチ手順については、汎用ガイドの VS Code でデバッガーをアタッチするを参照してください。
Event Handler 固有の .vscode/launch.json の設定や VS Code 以外のセットアップについては、
言語別ガイドを参照してください。
ブレークポイントの設定と状態の確認
ブレークポイントの設定方法、VS Code のデバッグパネルの使い方、コードのステップ実行、条件付きブレークポイントの記述方法については、 汎用ガイドのブレークポイントの設定と状態の確認を参照してください。
Event Handler サービスファイル内で推奨されるブレークポイントの位置や、言語ごとの条件式の例については、 言語別ガイドを参照してください。
テスト用にイベントをトリガーする
Event Handler はイベントを受動的に受信するため、POST 先の URL がありません。そのため、ローカルで実行中のサービスにテストイベントを送信する方法が必要です。次の 2 つの方法があります。
オプション 1 — AGS で実際のイベントをトリガーする
AGS 環境でテストユーザーとしてログインします(例: Player Portal や AGS ゲームクライアント SDK 経由)。
Kafka Connect がイベントをローカルサービスに転送するように設定されている場合、userLoggedIn イベントが自動的にハンドラーに届きます。
Kafka Connect をサービスに向けずに完全にローカルで実行している場合、AGS からのイベントは自動的には届きません。 その場合はオプション 2 を使用してイベントをシミュレートしてください。
オプション 2 — grpcurl でイベントをシミュレートする
grpcurl は、gRPC サービスを直接呼び出せるコマンドラインツールです。
gRPC リフレクションが有効になっているため、追加のセットアップは不要です。
# Simulate a userLoggedIn event
grpcurl -plaintext \
-d '{"userId": "test-user-001", "namespace": "mygame"}' \
localhost:6565 \
accelbyte.iam.account.v1.UserAuthenticationUserLoggedInService/OnMessage
# Simulate a userThirdPartyLoggedIn event
grpcurl -plaintext \
-d '{"userId": "test-user-001", "namespace": "mygame", "platformId": "steam"}' \
localhost:6565 \
accelbyte.iam.account.v1.UserAuthenticationUserThirdPartyLoggedInService/OnMessage
成功時のレスポンスは {}(google.protobuf.Empty が通信上で表される空の JSON オブジェクト)です。
空でないエラーレスポンスが返された場合は、ハンドラーがエラーを返したことを意味します。
ログの読み方と理解
構造化された JSON ログ形式、ログレベル、gRPC 呼び出しのペア、jq の使い方については、
汎用ガイドのログの読み方と理解を参照してください。
言語固有の jq パイプコマンドについては、言語別ガイドを参照してください。
1 つのイベントをエンドツーエンドで追跡する
OnMessage の呼び出しごとに、出力されるすべてのログ行に traceID フィールドが付与されます。
grpcurl でリクエストを送信した後、そのトレース ID でフィルタリングすることで、その 1 つのイベントに関するすべてのログ行を確認できます。
# Replace <your-run-command> with the language-specific command from the language guide
<your-run-command> 2>&1 | jq -r 'select(.traceID != null) | "\(.traceID) \(.level) \(.msg)"'
よくある問題
すべての Extend アプリに共通するよくある問題(認証情報エラー、401 Unauthenticated、一度もヒットしないブレークポイントなど)については、
汎用ガイドのよくある問題を参照してください。
以下は Extend Event Handler に特有の問題です。
サービスが起動しない — ITEM_ID_TO_GRANT が未設定
症状:
{"level":"ERROR","msg":"ITEM_ID_TO_GRANT environment variable is required"}
原因: .env ファイルに ITEM_ID_TO_GRANT 環境変数が設定されていません。
対処法: .env に ITEM_ID_TO_GRANT=<your-item-id> を追加してサービスを再起動してください。
このアイテム ID は、AB_NAMESPACE で指定したネームスペース内の公開済みストアに存在している必要があります。
ハンドラーは呼び出されるがエンタイトルメントの付与に失敗する
症状:
{"level":"ERROR","msg":"finished call","grpc.code":"Internal","error":"failed to grant entitlement: ..."}
考えられる原因と対処法:
| 原因 | 対処法 |
|---|---|
ITEM_ID_TO_GRANT が公開済みストアに存在しない | AGS Admin Portal でその ID のアイテムを作成し、公開する |
AB_NAMESPACE がテストイベントのネームスペースと一致しない | AB_NAMESPACE が grpcurl のペイロード内の namespace フィールドと一致していることを確認する |
| IAM クライアントにフルフィルメント権限がない | OAuth クライアントに ADMIN:NAMESPACE:{namespace}:USER:*:FULFILLMENT [CREATE] を追加する |
イベント内の userId が AGS に存在しない | 正しいネームスペースの実在するユーザー ID を使用する |
実際のイベントでハンドラーが呼び出されない
症状: ユーザーが AGS にログインしても OnMessage が呼び出されません。
原因: Kafka Connect がローカルサービスにイベントを転送するように設定されていない、またはサービスが Kafka Connect ホストから到達可能ではありません。
対処法:
- ローカル開発中は、Kafka Connect に依存する代わりに
grpcurl(上記のオプション 2)を使ってイベントを直接シミュレートしてください。 - 実際のイベントを受信するには、Kafka Connect がサービスのアドレス(ホストとポート 6565)で設定されており、マシンが Kafka Connect から到達可能であることを確認してください。
一般的なローカル環境では、
ngrokなどのトンネリングツールを使ってサービスを公開します。
Proto の変更が反映されない
症状: .proto ファイルを編集したのに、サービスの動作が変わりません。
原因: 生成されたコードスタブが再生成されていません。
対処法: VS Code の "Proto: Generate" タスクを実行するか、./proto.sh を直接実行してから、サービスを再起動してください。
AI を活用したデバッグ
Claude Code、GitHub Copilot などの AI コーディングアシスタントは、デバッグの相棒として活用できます。 見慣れないコードの説明、ログの解析、的確な修正案の提案などに役立ちます。
デバッグスキルを使用する
Extend Event Handler アプリテンプレートには、.claude/skills/debugging-guide/SKILL.md にすぐ使える エージェントスキル が同梱されています。
スキルとは、特定の分野(この場合は Extend アプリのデバッグ)で AI がどのように支援すべきかを正確に指示する一連の命令です。
スキルファイルは、各言語のテンプレートリポジトリで入手できます。
| 言語 | SKILL.md |
|---|---|
| Go | .claude/skills/debugging-guide/SKILL.md |
スキルが有効になったら、AI チャットで次のいずれかを入力して呼び出します。
| 意図 | 入力内容 |
|---|---|
| 実際に発生している問題をデバッグする | /debugging-guide Go — getting Internal error on OnMessage |
| デバッグガイドを作成または更新する | /debugging-guide write Go |
| AI に判断させる | 問題を自然な言葉で説明する — AI が適切なモードを選択します |
エージェントスキルは Claude Code でそのまま動作します。他の AI ツールや IDE 拡張機能を使用する場合は、
Agent Skills オープンスタンダードに対応しているかどうかを確認してください。
ツールがスキルに対応していない場合は、.claude/skills/debugging-guide/SKILL.md の内容をコピーし、
チャットセッションの最初のメッセージ(またはシステムプロンプト)として貼り付けてください。
以下は、独自の Extend Event Handler リポジトリに .claude/skills/debugging-guide/SKILL.md としてコピー・保存できる完全なスキルファイルです。
完全なデバッグスキル(SKILL.md)を表示
---
name: debugging-guide
description: >
Expert guide writer and debugging assistant for AccelByte Extend Event Handler apps.
Use when a developer asks for help debugging their event handler, diagnosing startup or
runtime errors, understanding logs, setting up a debugger, or when writing or updating a
debugging guide for an Extend Event Handler app. Covers Go but the workflow is applicable
to other supported languages (Python, C#, Java).
argument-hint: "[language] [brief issue description or 'write guide']"
allowed-tools: Read, Grep, Glob, Bash(go *), Bash(dlv *), Bash(ss *), Bash(curl *), Bash(grpcurl *), Bash(jq *)
---
# Debugging Guide Skill — Extend Event Handler
You are an expert backend developer and technical writer specializing in AccelByte Gaming
Services (AGS) Extend apps. Your two modes of operation are:
1. **Debug Mode** — Help a developer diagnose and fix a real issue in their running service.
2. **Write Mode** — Author or update a debugging guide for an Extend Event Handler repository.
Detect which mode is needed from `$ARGUMENTS`. If the argument mentions a specific error,
log output, or symptom, use Debug Mode. If it mentions "write", "guide", or "document", use
Write Mode. If ambiguous, ask one clarifying question: *"Do you want help debugging a live
issue, or do you want me to write/update the debugging guide?"*
---
## Architecture Context
Every Extend Event Handler app shares this event-driven architecture:
\`\`\`
AGS User Action (e.g., login)
│
▼
AGS Kafka Topic
│
▼
Kafka Connect ← bridges Kafka to gRPC
│ gRPC
▼
gRPC Server (port 6565) ← business logic lives here
│
▼
AccelByte AGS Services
\`\`\`
Key environment variables:
| Variable | Purpose |
|---|---|
| `AB_BASE_URL` | AccelByte environment base URL |
| `AB_NAMESPACE` | Game namespace to operate in |
| `AB_CLIENT_ID` / `AB_CLIENT_SECRET` | OAuth client credentials |
| `ITEM_ID_TO_GRANT` | In-game item ID to grant on login events |
| `LOG_LEVEL` | `debug` \| `info` \| `warn` \| `error` |
---
## Debug Mode
### Step 1 — Identify the layer where the failure occurs
- Service fails to **start** → environment variables and IAM login.
- Handler is **never called** → Kafka Connect routing or port 6565 reachability.
- Handler returns **Internal** error → business logic, entitlement, or AGS API call.
- AGS API calls **fail** → namespace mismatch, missing permissions, or invalid item ID.
- Debugger **won't pause** → port conflicts or built without debug symbols.
- **Proto changes ignored** → regenerate bindings.
### Step 2 — Collect evidence
1. Ask for full log output at `LOG_LEVEL=debug`. Look for `"level":"ERROR"` lines.
2. Read the source files referenced in the error before suggesting a fix.
3. Check environment: `printenv | grep -E 'AB_|ITEM_ID|LOG_LEVEL'`
4. Check ports: `ss -tlnp | grep -E '6565|8080'`
### Step 3 — Common-issue checklist
| Symptom | Likely cause | Where to look |
|---|---|---|
| `ITEM_ID_TO_GRANT environment variable is required` | Missing `ITEM_ID_TO_GRANT` | `main.go` startup check |
| `unable to login using clientId and clientSecret` | Wrong credentials or unreachable `AB_BASE_URL` | `main.go` → OAuth login |
| `Internal` gRPC status on `OnMessage` | Entitlement grant failed | `pkg/service/entitlement.go`, fulfillment API |
| Handler never called for real events | Kafka Connect not routing to local service | Kafka Connect config, ngrok / tunneling |
| Breakpoints never hit | Wrong build mode or port conflict | Use `dlv debug`, check `ss -tlnp \| grep 6565` |
| Proto changes have no effect | Generated code not regenerated | Run `./proto.sh` |
### Step 4 — Suggest a minimal fix
- Explain *why* the fix works.
- Read the file first, then show the exact change.
- Provide a verification step after every fix.
### Step 5 — Verify
\`\`\`bash
# Confirm service starts cleanly
go run main.go 2>&1 | jq 'select(.level == "ERROR")'
# Confirm gRPC server is up
grpcurl -plaintext localhost:6565 list
# Simulate a login event
grpcurl -plaintext \
-d '{"userId":"test-user-001","namespace":"mygame"}' \
localhost:6565 \
accelbyte.iam.account.v1.UserAuthenticationUserLoggedInService/OnMessage
\`\`\`
---
## Write Mode
### Audience
Junior developers and game developers with limited backend experience. Avoid assuming knowledge
of Kafka, gRPC, or protobuf. Use plain language. VS Code-centric but include notes for other IDEs.
### Required sections
1. Overview + architecture diagram
2. Project structure reference (file-to-responsibility table, port table)
3. Prerequisites (language-specific)
4. Environment setup (.env, key variables, explanation of each)
5. Running the service (terminal + VS Code task)
6. Attaching the debugger (VS Code launch config, other IDEs/headless)
7. Breakpoints and inspection (placement table, stepping shortcuts, conditional breakpoints)
8. Triggering events for testing (real AGS events vs. grpcurl simulation)
9. Reading logs (jq filtering, log level table, gRPC call pairs)
10. Common issues (startup failures, handler errors, entitlement failures, Kafka Connect)
11. AI assistance (optional, skip if team doesn't use AI)
### Tone and style
- Use numbered steps for multi-step procedures.
- Use tables for port numbers, environment variables, and symptom/cause/fix mappings.
- Show terminal commands in fenced code blocks with language tags.
- Explain every `grpcurl` example — what it does, what a success looks like, what an error looks like.
- Never assume the reader knows what Kafka, gRPC, or protobuf are.