ローカルデバッグガイド — Go
注釈:本資料はAI技術を用いて翻訳されています。
このガイドでは、Go で記述された Extend Event Handler アプリのデバッグに特有の内容を説明します。環境のセットアップ、VS Code のデバッグワークフロー、ログの読み方、一般的な問題などの一般的なデバッグの概念については、以下を参照してください。
- Extend ローカルデバッグガイド — すべての Extend アプリタイプに共通する概念
- Go 言語セットアップガイド — Go の前提条件、Delve、jq、および Go 特有のトラブルシューティング
このガイドのファイルパス、タスク名、スクリプト名は、AccelByte Extend Event Handler Go テンプレートを参照しています。 プロジェクトで異なる名前を使用している場合でも、概念自体は同様に適用されます。パスをプロジェクトの構成に合わせて調整してください。
前提条件
インストール要件については、Go 言語セットアップガイドを参照してください。 さらに、ローカル開発中に受信イベントをシミュレートするために grpcurl が必要です。インストールと使用方法については、メインガイドのテスト用にイベントをトリガーするを参照してください。
プロジェクト構造
| ファイル / パッケージ | 内容 |
|---|---|
main.go | エントリポイント — gRPC サーバー、Prometheus メトリクス、OpenTelemetry トレーシング、IAM ログインを結び付けます。 |
pkg/service/loginHandler.go | userLoggedIn イベントに対するビジネスロジック — イベントを受信し、grantEntitlement を呼び出します。 |
pkg/service/thirdPartyLoginHandler.go | userThirdPartyLoggedIn イベントに対するビジネスロジック — loginHandler.go と同じパターンです。 |
pkg/service/entitlement.go | AGS Fulfillment API を呼び出してユーザーにアイテムを付与する共有ヘルパー。 |
pkg/common/scope.go | リクエストスコープ — 各ハンドラー呼び出しごとに、コンテキスト、OpenTelemetry スパン、トレースタグ付きロガーをまとめます。 |
pkg/common/logging.go | gRPC ミドルウェアのロガーを Go の slog に橋渡しします。 |
pkg/common/tracerProvider.go | OpenTelemetry の分散トレーシング(Zipkin エクスポーター)をセットアップします。 |
pkg/proto/ | AGS イベントメッセージの形式を記述する .proto ファイル。 |
pkg/pb/ | .proto から自動生成された Go コード。直接編集しないでください。 |
ポート番号(main.go 内の定数):
| ポート | 用途 |
|---|---|
6565 | gRPC サーバー — Kafka Connect からのイベントおよびシミュレートされた grpcurl 呼び出しを受信します |
8080 | Prometheus メトリクスエンドポイント(/metrics) |
サービスをローカルで実行する
ターミナルから
# .env ファイルからすべての変数をエクスポート
export $(grep -v '^#' .env | xargs)
go run main.go
VS Code から
ターミナル → タスクの実行 → "Run: Service" を使用します。
このタスクは .vscode/tasks.json に定義されており、.env ファイルを自動的に読み込みます。
サービスが起動していることを確認する
次のようなログが表示されるはずです。
{"time":"...","level":"INFO","msg":"starting app server.."}
{"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"}
gRPC リフレクション(つまりサーバー)が動作していることを確認します。
grpcurl -plaintext localhost:6565 list
期待される出力 — 登録されているサービスの一覧:
accelbyte.iam.account.v1.UserAuthenticationUserLoggedInService
accelbyte.iam.account.v1.UserAuthenticationUserThirdPartyLoggedInService
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection
デバッガーのアタッチ
VS Code(推奨)
このリポジトリには、.vscode/launch.json にすぐに使える起動設定が付属しています。
{
"name": "Debug: Service",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"envFile": "${workspaceFolder}/.env",
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
手順:
一般ガイドのデバッガーのアタッチの手順に従い、ドロップダウンから "Debug: Service" を選択します。
Go 拡張機能は内部で Delve を使用しています。別途設定する必要はありません。
その他の IDE — Delve ヘッドレスモード
IDE が接続できるように、Delve をヘッドレスモードで起動します。
export $(grep -v '^#' .env | xargs)
dlv debug --headless --listen=:2345 --api-version=2 .
その後、DAP(Debug Adapter Protocol)経由で localhost:2345 にアタッチするように IDE を設定します。
ブレークポイントを設置する場所
注目すべきロジックの大部分は、サービスハンドラーファイル内にあります。まずはそこから確認しましょう。
| 調査したい内容 | ファイルと場所 |
|---|---|
| 任意のログインイベントの受信 | pkg/service/loginHandler.go — OnMessage の先頭 |
| サードパーティログインイベントの受信 | pkg/service/thirdPartyLoginHandler.go — OnMessage の先頭 |
| エンタイトルメント付与のロジック | pkg/service/entitlement.go — grantEntitlement の内部 |
| サービスがまったく起動しない | main.go — os.Exit(1) 呼び出しの直前 |
| スパンやトレース ID が欠落している理由 | pkg/common/scope.go — ChildScopeFromRemoteScope |
受信イベントペイロードの検査
デバッガーが OnMessage の内部で一時停止すると、msg パラメーターにイベント全体が含まれています。
Variables パネルで展開すると、UserId、Namespace、PlatformId など、イベントタイプに応じてイベントが保持するすべてのフィールドを確認できます。
条件付きブレークポイントの構文
ブレークポイントを右クリック → Edit Breakpoint → Go の式を入力します。例:
msg.UserId == "test-user-001"
条件付きブレークポイントの構文の詳細な例については、Go 言語ガイドを参照してください。
テスト用にイベントをトリガーする
イベントのシミュレーション方法や grpcurl コマンドについては、メインガイドのテスト用にイベントをトリガーするを参照してください。
サービスメソッドを記述する
proto メソッドの正確なフィールド名を知る必要がある場合は、grpcurl describe を使用します。
grpcurl -plaintext localhost:6565 \
describe accelbyte.iam.account.v1.UserAuthenticationUserLoggedInService.OnMessage
これにより、メソッドの proto 定義全体が表示されます。-d ペイロードに含めるべきフィールドを正確に把握する際に役立ちます。
ログを読む
jq によるログのフィルタリングについては、Go 言語ガイドを参照してください。
1 つのイベントをエンドツーエンドで追跡する
OnMessage の各呼び出しは、Scope(pkg/common/scope.go を参照)を作成し、出力するすべてのログ行に traceID を付加します。grpcurl リクエストを送信した後、その trace ID で grep すれば、その 1 つのイベントに関するすべてのログ行を確認できます。
go run main.go 2>&1 | jq -r 'select(.traceID != null) | "\(.traceID) \(.level) \(.msg)"'
Go 特有のトラブルシューティング
proto の変更が反映されない
症状: pkg/proto/ 内のファイルを編集したが、実行時に何も変わらない。
原因: pkg/pb/ 内の生成されたスタブが再生成されていません。
対処法: VS Code の "Proto: Generate" タスクを実行するか、次を実行します。
./proto.sh
その後、サービスを再起動してください。
go run とデバッガー起動設定の違い
go run main.go はデバッグ情報なしでコンパイルされます。デバッガーをアタッチする必要がある場合は、go run の代わりに常に VS Code の起動設定(または dlv debug)を使用してください。
ポートの競合を確認する
「address already in use」というメッセージが表示された場合:
ss -tlnp | grep -E '6565|8080'
古いプロセスを終了してから、再度起動してください。
grpcurl が "Failed to dial" を返す
症状:
Failed to dial target host "localhost:6565": ...
原因: gRPC サーバーがまだ起動していない、起動時にクラッシュした、または別のポートでリスニングしています。
対処法:
- サービスのログで起動時のエラー(
"level":"ERROR"の行)を確認します。 - ポート 6565 が開いていることを確認します:
ss -tlnp | grep 6565。 grpcurl -plaintext localhost:6565 listを再実行します — 成功すればサーバーは起動しています。
ハンドラーが Internal を返すが ERROR ログが表示されない
症状: grpcurl が Code: Internal を報告するが、対応する ERROR 行がログに表示されない。
原因: 一部のログ行に対してログレベルが error より上に設定されている、またはエラーが構造化ロガーではなく標準エラー出力に出力される深いライブラリ呼び出しから返されています。
対処法:
LOG_LEVEL=debugを設定して再実行します — これによりすべてのログレベルが有効になります。pkg/service/entitlement.go内のgrantEntitlementにブレークポイントを設定し、FulfillItemShortから返されるerrの値を検査します。
AI アシスタンス
このアプリテンプレートには、.claude/skills/debugging-guide/SKILL.md に Claude エージェントスキルが付属しています。
このスキルファイル全体を自分のリポジトリにコピーし、AI アシスタントで有効化してください。
スキルの全内容とプロンプトのヒントについては、メインガイドのAI アシスタンス セクションを参照してください。