メインコンテンツまでスキップ

Local debugging guide — C#

Last updated on July 14, 2026

注釈:本資料はAI技術を用いて翻訳されています。

このガイドでは、C# で記述された Extend Event Handler アプリのデバッグに特化した内容を説明します。環境構築、VS Code のデバッグワークフロー、ログの読み方、よくある問題といった一般的なデバッグの概念については、以下を参照してください。

Extend App テンプレートを前提としています

このガイドに記載されているファイルパス、タスク名、クラス名は、AccelByte Extend Event Handler C# テンプレートを参照しています。 プロジェクトで異なる名前を使用している場合でも、考え方は同じです。パスは各自の構成に合わせて読み替えてください。


前提条件

インストール要件については、C# 言語セットアップガイドを参照してください。加えて、ローカル開発中に受信イベントをシミュレートするには grpcurl が必要です。インストールと使用方法については、メインガイドのテスト用にイベントをトリガーするを参照してください。


プロジェクト構成

ファイル / クラス役割
Program.csエントリーポイント — gRPC サーバー、Prometheus メトリクス、OpenTelemetry トレーシング、IAM ログイン、ヘルスチェックを組み立てます。
Services/UserLoggedInService.csuserLoggedIn イベントに対するビジネスロジック — イベントを受信し、Entitlement.GrantEntitlement を呼び出します。
Services/UserThirdPartyLoggedInService.csuserThirdPartyLoggedIn イベントに対するビジネスロジックUserLoggedInService.cs と同じパターンです。
Services/Entitlement.csAGS Fulfillment API を呼び出してユーザーにアイテムを付与する共有ヘルパーです。
Classes/DefaultAccelByteServiceProvider.cs設定を読み込み、AccelByteSDK インスタンスを構築し、初回のクライアント認証情報によるログインを実行します。
Classes/AppSettingConfigRepository.cs環境変数(AB_BASE_URLAB_CLIENT_IDAB_CLIENT_SECRETAB_NAMESPACEITEM_ID_TO_GRANT)を型付きプロパティに読み込みます。
Classes/DebugLoggerServerInterceptor.csgRPC インターセプター — 受信するすべての呼び出しについて、メソッド名とヘッダーをログに記録します。
Classes/ExceptionHandlingInterceptor.csgRPC インターセプター — 未処理の例外をキャッチし、適切な gRPC ステータスコードを返します。
Protos/iam/account/v1/account.protoAGS IAM アカウントイベントの proto 定義です。
appsettings.json静的な設定 — Kestrel エンドポイントのバインディング(ポート 65658080)、ログレベルです。

ポート番号appsettings.json で設定):

ポート用途
6565gRPC サーバー — Kafka Connect からのイベントおよびシミュレートされた grpcurl 呼び出しを受信します
8080HTTP サーバー — 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.csOnMessage の先頭
サードパーティログインイベントの到着Services/UserThirdPartyLoggedInService.csOnMessage の先頭
エンタイトルメント付与ロジックServices/Entitlement.csGrantEntitlement の内部
サービスがまったく起動しないProgram.csEnvironment.Exit(1) 呼び出しの直前
起動時の認証情報チェックClasses/DefaultAccelByteServiceProvider.cs — コンストラクタ、Sdk.LoginClient(true) の後
gRPC 呼び出しのトレースClasses/DebugLoggerServerInterceptor.csUnaryServerHandler

受信イベントのペイロードを調べる

デバッガーが OnMessage の内部で一時停止したとき、request パラメータにはイベントの全体が含まれています。Variables パネルで展開すると、そのイベントが持つすべてのフィールド(UserIdNamespace、サードパーティイベントの場合は 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 が設定されていません。

対処法: .envITEM_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 が間違った環境を指しています。

対処法:

  1. .env の認証情報を再確認します。

  2. AB_BASE_URL に到達可能であることを確認します。

    curl "$AB_BASE_URL/iam/v3/public/config"
  3. OAuth クライアントで CLIENT_CREDENTIALS グラントタイプが Admin Portal で有効になっていることを確認します。


デバッガーが起動する前にビルドが失敗する

症状: F5 を押すとターミナルにビルドエラーが表示され、デバッガーがアタッチされません。

原因: Build: App プレローンチタスクが失敗しました。

対処法:

  1. Terminal → Run Task → "Build: App" タスクを直接開き、コンパイラの完全な出力を確認します。
  2. コンパイルエラーを修正してから、再度 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 サーバーがまだ起動していない、起動時にクラッシュした、または別のポートでリスニングしています。

対処法:

  1. 起動時のエラー(fail: または crit: の行)についてサービスログを確認します。
  2. ポート 6565 が開いていることを確認します: ss -tlnp | grep 6565
  3. grpcurl -plaintext localhost:6565 list を再実行してください。成功すればサーバーは起動しています。

ハンドラーが Internal を返すが、エラーログが表示されない

症状: grpcurlCode: Internal を報告しますが、ログには対応するエラー行が表示されません。

原因: アプリケーションのロガーに到達する前に AccelByte SDK 内で例外がキャッチされている、または justMyCode: true によってスタックフレームが隠されています。

対処法:

  1. Services/Entitlement.csGrantEntitlement 内にブレークポイントを設置し、FulfillItemOp.Execute によってスローされる例外を調べます。
  2. .vscode/launch.jsonjustMyCode: false を設定し、SDK の内部にステップインできるようにします。
  3. 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 生成ステップを実行し(リポジトリのルートにある Makefileproto.sh スクリプトを確認してください)、その後サービスを再ビルドして再起動します。

dotnet build src/plugin-arch-event-handler-grpc-server.sln

AI アシスタンス

このアプリテンプレートには、.claude/skills/debugging-guide/SKILL.md に Claude エージェントスキルが同梱されています。 このスキルファイル全体を自分のリポジトリにコピーし、AI アシスタントで有効化してください。

スキルの全内容とプロンプトのコツについては、メインガイドのAI アシスタンスセクションを参照してください。


参考資料