Local debugging guide — C#
注釈:本資料はAI技術を用いて翻訳されています。
このガイドでは、C# で記述された Extend Event Handler アプリのデバッグに特化した内容を説明します。環境構築、VS Code のデバッグワークフロー、ログの読み方、よくある問題といった一般的なデバッグの概念については、以下を参照してください。
- Extend ローカルデバッグガイド — すべての Extend アプリタイプに共通する概念
- C# 言語セットアップガイド — .NET の前提条件、アタッチモード、jq、C# 固有のトラブルシューティング
このガイドに記載されているファイルパス、タスク名、クラス名は、AccelByte Extend Event Handler C# テンプレートを参照しています。 プロジェクトで異なる名前を使用している場合でも、考え方は同じです。パスは各自の構成に合わせて読み替えてください。
前提条件
インストール要件については、C# 言語セットアップガイドを参照してください。加えて、ローカル開発中に受信イベントをシミュレートするには grpcurl が必要です。インストールと使用方法については、メインガイドのテスト用にイベントをトリガーするを参照してください。
プロジェクト構成
| ファイル / クラス | 役割 |
|---|---|
Program.cs | エントリーポイント — gRPC サーバー、Prometheus メトリクス、OpenTelemetry トレーシング、IAM ログイン、ヘルスチェックを組み立てます。 |
Services/UserLoggedInService.cs | userLoggedIn イベントに対するビジネスロジック — イベントを受信し、Entitlement.GrantEntitlement を呼び出します。 |
Services/UserThirdPartyLoggedInService.cs | userThirdPartyLoggedIn イベントに対するビジネスロジック — UserLoggedInService.cs と同じパターンです。 |
Services/Entitlement.cs | AGS Fulfillment API を呼び出してユーザーにアイテムを付与する共有ヘルパーです。 |
Classes/DefaultAccelByteServiceProvider.cs | 設定を読み込み、AccelByteSDK インスタンスを構築し、初回のクライアント認証情報によるログインを実行します。 |
Classes/AppSettingConfigRepository.cs | 環境変数(AB_BASE_URL、AB_CLIENT_ID、AB_CLIENT_SECRET、AB_NAMESPACE、ITEM_ID_TO_GRANT)を型付きプロパティに読み込みます。 |
Classes/DebugLoggerServerInterceptor.cs | gRPC インターセプター — 受信するすべての呼び出しについて、メソッド名とヘッダーをログに記録します。 |
Classes/ExceptionHandlingInterceptor.cs | gRPC インターセプター — 未処理の例外をキャッチし、適切な gRPC ステータスコードを返します。 |
Protos/iam/account/v1/account.proto | AGS IAM アカウントイベントの proto 定義です。 |
appsettings.json | 静的な設定 — Kestrel エンドポイントのバインディング(ポート 6565 と 8080)、ログレベルです。 |
ポート番号(appsettings.json で設定):
| ポート | 用途 |
|---|---|
6565 | gRPC サーバー — Kafka Connect からのイベントおよびシミュレートされた grpcurl 呼び出しを受信します |
8080 | HTTP サーバー — Prometheus メトリクスエンドポイント(/metrics) |
サービスをローカルで実行する
ターミナルから
# .envファイルからすべての変数をエクスポート
export $(grep -v '^#' .env | xargs)
dotnet run --project src/AccelByte.PluginArch.EventHandler.Demo.Server/AccelByte.PluginArch.EventHandler.Demo.Server.csproj
VS Code から
Terminal → Run Task → "Run: App" を使用してください。
このタスクは .vscode/tasks.json で定義されており、.env ファイルを自動的に読み込みます。
サービスが起動していることを確認する
次のようなログ出力が表示されるはずです。
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://0.0.0.0:8080
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://0.0.0.0:6565
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
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: App",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build: App",
"program": "${workspaceFolder}/src/AccelByte.PluginArch.EventHandler.Demo.Server/bin/Debug/net8.0/AccelByte.PluginArch.EventHandler.Demo.Server.dll",
"args": [],
"cwd": "${workspaceFolder}/src/AccelByte.PluginArch.EventHandler.Demo.Server",
"envFile": "${workspaceFolder}/.env",
"console": "integratedTerminal",
"justMyCode": true
}
手順:
共通ガイドのデバッガーのアタッチの手順に従い、ドロップダウンから "Debug: App" を選択します。
VS Code は(Build: App プレローンチタスクによって)プロジェクトをビルドし、.NET デバッガー(coreclr)をアタッチします。デバッガーを別途設定する必要はありません。
ヒント —
justMyCode: デフォルトではjustMyCode: trueにより、サードパーティのライブラリコードへのステップインがスキップされます。AccelByte SDK や gRPC の内部にステップインする必要がある場合は、.vscode/launch.jsonでこれをfalseに変更してください。
その他の IDE — リモートアタッチによる dotnet
アプリケーションを起動し、対応する .NET デバッガー(例: JetBrains Rider や Visual Studio)をアタッチします。
export $(grep -v '^#' .env | xargs)
dotnet run --project src/AccelByte.PluginArch.EventHandler.Demo.Server/AccelByte.PluginArch.EventHandler.Demo.Server.csproj
その後、IDE の Attach to Process 機能を使用して AccelByte.PluginArch.EventHandler.Demo.Server プロセスを選択します。
ブレークポイントを設置する場所
主要なロジックはサービスハンドラーのファイルにあります。まずはそこから確認を始めてください。
| 調査したい内容 | ファイルと場所 |
|---|---|
| ログインイベントの到着全般 | Services/UserLoggedInService.cs — OnMessage の先頭 |
| サードパーティログインイベントの到着 | Services/UserThirdPartyLoggedInService.cs — OnMessage の先頭 |
| エンタイトルメント付与ロジック | Services/Entitlement.cs — GrantEntitlement の内部 |
| サービスがまったく起動しない | Program.cs — Environment.Exit(1) 呼び出しの直前 |
| 起動時の認証情報チェック | Classes/DefaultAccelByteServiceProvider.cs — コンストラクタ、Sdk.LoginClient(true) の後 |
| gRPC 呼び出しのトレース | Classes/DebugLoggerServerInterceptor.cs — UnaryServerHandler |
受信イベントのペイロードを調べる
デバッガーが OnMessage の内部で一時停止したとき、request パラメータにはイベントの全体が含まれています。Variables パネルで展開すると、そのイベントが持つすべてのフィールド(UserId、Namespace、サードパーティイベントの場合は PlatformId、および Protos/iam/account/v1/account.proto で定義されているその他のフィールド)を確認できます。
条件付きブレークポイントの構文
ブレークポイントを右クリック → Edit Breakpoint → C# の式を入力します。例:
request.UserId == "test-user-001"
条件付きブレークポイントの構文の詳細な例については、C# 言語ガイドを参照してください。
テスト用にイベントをトリガーする
イベントシミュレーションのオプションと grpcurl コマンドについては、メインガイドのテスト用にイベントをトリガーするを参照してください。
サービスメソッドを記述する
proto メソッドの正確なフィールド名を知る必要がある場合は、grpcurl describe を使用します。
grpcurl -plaintext localhost:6565 \
describe accelbyte.iam.account.v1.UserAuthenticationUserLoggedInService.OnMessage
これにより、そのメソッドの完全な proto 定義が出力されます。-d ペイロードに含めるべきフィールドを正確に知りたいときに役立ちます。
ログを読む
このサービスは ASP.NET Core の Microsoft.Extensions.Logging を使用しており、標準出力に書き込みます。1 行のログは次のようになります。
info: AccelByte.PluginArch.EventHandler.Demo.Server.Services.UserLoggedInService[0]
Received UserLoggedIn event: { "userId": "test-user-001", "namespace": "mygame" }
ログレベル
デフォルトのログレベルは appsettings.json で設定されています。
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
ローカル開発中により詳細な出力を確認するには、DOTNET_ENVIRONMENT=Development 環境変数を設定してレベルを上書きする("Run: App" VS Code タスクではすでに設定済み)か、appsettings.Development.json にオーバーライドを追加します。
{
"Logging": {
"LogLevel": {
"Default": "Debug"
}
}
}
gRPC 呼び出しのパターン
DebugLoggerServerInterceptor は受信するすべての gRPC 呼び出しをログに記録します。
info: AccelByte.PluginArch.EventHandler.Demo.Server.DebugLoggerServerInterceptor[0]
REQUEST /accelbyte.iam.account.v1.UserAuthenticationUserLoggedInService/OnMessage
info: AccelByte.PluginArch.EventHandler.Demo.Server.DebugLoggerServerInterceptor[0]
RESPONSE /accelbyte.iam.account.v1.UserAuthenticationUserLoggedInService/OnMessage
REQUEST 行だけが表示され、その後に RESPONSE 行が続かない場合、ハンドラーは応答を返す前にエラーに遭遇しています。その前後にある fail: または error: の行を確認してください。
ログをフィルタリングする
ターミナルで必要な出力に絞り込むには grep を使用します。
# エラーレベルの行のみを表示
dotnet run ... 2>&1 | grep -E '^fail:|^crit:'
# OnMessage呼び出しのみを表示
dotnet run ... 2>&1 | grep "OnMessage"
# 特定ユーザーに関連する行を表示
dotnet run ... 2>&1 | grep "test-user-001"
C# 固有のトラブルシューティング
ITEM_ID_TO_GRANT が未設定 — サービスが即座に終了する
症状:
fail: AccelByte.PluginArch.EventHandler.Demo.Server.Program[0]
ITEM_ID_TO_GRANT environment variable is required.
原因: .env ファイルに ITEM_ID_TO_GRANT が設定されていません。
対処法: .env に ITEM_ID_TO_GRANT=<your-item-id> を追加してから再起動します。このアイテム ID は、AB_NAMESPACE で指定した名前空間内の公開済みストアに存在する必要があります。
サービスが終了する — クライアント認証情報によるログインが失敗する
症状:
fail: AccelByte.PluginArch.EventHandler.Demo.Server.DefaultAccelByteServiceProvider[0]
Error unable to login using clientId and clientSecret
または DefaultAccelByteServiceProvider コンストラクタから例外がスローされます。
原因: AB_CLIENT_ID または AB_CLIENT_SECRET が間違っているか、AB_BASE_URL が間違った環境を指しています。
対処法:
-
.envの認証情報を再確認します。 -
AB_BASE_URLに到達可能であることを確認します。curl "$AB_BASE_URL/iam/v3/public/config" -
OAuth クライアントで
CLIENT_CREDENTIALSグラントタイプが Admin Portal で有効になっていることを確認します。
デバッガーが起動する前にビルドが失敗する
症状: F5 を押すとターミナルにビルドエラーが表示され、デバッガーがアタッチされません。
原因: Build: App プレローンチタスクが失敗しました。
対処法:
- Terminal → Run Task → "Build: App" タスクを直接開き、コンパイラの完全な出力を確認します。
- コンパイルエラーを修正してから、再度 F5 を押します。
ターミナルからビルドすることもできます。
dotnet build src/plugin-arch-event-handler-grpc-server.sln
ポートの競合を確認する
「address already in use」と表示される場合:
ss -tlnp | grep -E '6565|8080'
古いプロセスを終了してから、再度起動してください。
grpcurl が "Failed to dial" を返す
症状:
Failed to dial target host "localhost:6565": ...
原因: gRPC サーバーがまだ起動していない、起動時にクラッシュした、または別のポートでリスニングしています。
対処法:
- 起動時のエラー(
fail:またはcrit:の行)についてサービスログを確認します。 - ポート 6565 が開いていることを確認します:
ss -tlnp | grep 6565。 grpcurl -plaintext localhost:6565 listを再実行してください。成功すればサーバーは起動しています。
ハンドラーが Internal を返すが、エラーログが表示されない
症状: grpcurl が Code: Internal を報告しますが、ログには対応するエラー行が表示されません。
原因: アプリケーションのロガーに到達する前に AccelByte SDK 内で例外がキャッチされている、または justMyCode: true によってスタックフレームが隠されています。
対処法:
Services/Entitlement.csのGrantEntitlement内にブレークポイントを設置し、FulfillItemOp.Executeによってスローされる例外を調べます。.vscode/launch.jsonでjustMyCode: falseを設定し、SDK の内部にステップインできるようにします。appsettings.jsonでログの詳細度を上げます("Default": "Debug"を設定)。
デバッガーがブレークポイントで一時停止しない
考えられる原因と対処法:
| 原因 | 対処法 |
|---|---|
デバッガーの代わりに Run: App タスクでサービスを起動した | VS Code の "Debug: App" 起動設定(F5)を使用してください |
| プロジェクトがリリースモードでビルドされていた | 起動設定は bin/Debug/net8.0/ を対象としています。-c Release でビルドしていないことを確認してください |
| すでに別のインスタンスが実行中で、イベントを処理している | ポートの競合を確認してください: ss -tlnp | grep 6565 を実行し、古いプロセスを停止します |
justMyCode: true によってファイルがスキップされる | ファイルがメインプロジェクトの一部であり、参照ライブラリではないことを確認します。justMyCode: false の設定も試してください |
grpcurl が間違ったポートを対象にしている | grpcurl -plaintext localhost:6565 list でポート 6565 を確認してください |
proto の変更が反映されない
症状: Protos/ 内のファイルを編集したが、サービスの動作が変わりません。
原因: 生成された C# のスタブが再生成されていません。
対処法: プロジェクトの proto 生成ステップを実行し(リポジトリのルートにある Makefile や proto.sh スクリプトを確認してください)、その後サービスを再ビルドして再起動します。
dotnet build src/plugin-arch-event-handler-grpc-server.sln
AI アシスタンス
このアプリテンプレートには、.claude/skills/debugging-guide/SKILL.md に Claude エージェントスキルが同梱されています。
このスキルファイル全体を自分のリポジトリにコピーし、AI アシスタントで有効化してください。
スキルの全内容とプロンプトのコツについては、メインガイドのAI アシスタンスセクションを参照してください。