gRPC に限った話ではありませんが、ネットワークを介して送受信しているデータをダンプして目視確認したいことは頻繁にあります。このようなとき、たいてい以下のような方法が採られます。
用途 | 実装 |
---|---|
個別 | ダンプしたい箇所にデバッグコードを仕込む |
全体 | 全 API の入口/出口となる箇所にデバッグコードを仕込む |
MagicOnion には後者 (全通信内容をダンプする) の機能が標準で用意されているので、今回はこれを利用してみます。
ダンプ用のロガーを仕込む
方法は非常に簡単で、MagicOnionEngine
の生成時にロガーを仕込んだオプションを設定するだけです。
using System; using Grpc.Core; using Grpc.Core.Logging; using MagicOnion.Server; namespace MagicOnionSample.Service { class Program { static void Main() { //--- gRPC のログをコンソールに出力 GrpcEnvironment.SetLogger(new ConsoleLogger()); //--- MagicOnion 側のログを gRPC のログに流し込む //--- そのとき名前付き (JSON 形式) でデータをダンプ var logger = new MagicOnionLogToGrpcLoggerWithNamedDataDump(); var options = new MagicOnionOptions(true){ MagicOnionLogger = logger }; var service = MagicOnionEngine.BuildServerServiceDefinition(options); //--- いつも通りの起動 var port = new ServerPort("localhost", 12345, ServerCredentials.Insecure); var server = new Server(){ Services = { service }, Ports = { port } }; server.Start(); // launch gRPC server Console.ReadLine(); } } }
実行してみる
これでダンプの準備は整いました。では、以下のような API で通信してみましょう。
using MagicOnion; namespace MagicOnionSample.ServiceDefinition { public interface ISampleApi : IService<ISampleApi> { UnaryResult<double> Sample(Vector2 value); } }
using System; using MagicOnion; using MagicOnion.Server; using MagicOnionSample.ServiceDefinition; namespace MagicOnionSample.Service { public class SampleApi : ServiceBase<ISampleApi>, ISampleApi { public async UnaryResult<double> Sample(Vector2 value) { //--- テキトーにピタゴラスでも var x2 = value.X * value.X; var y2 = value.Y * value.Y; return Math.Sqrt(x2 + y2); } } }
using System; using System.Threading.Tasks; using Grpc.Core; using MagicOnion.Client; using MagicOnionSample.ServiceDefinition; namespace MagicOnionSample.Client { class Program { static void Main() => MainAsync().Wait(); static async Task MainAsync() { var channel = new Channel("localhost", 12345, ChannelCredentials.Insecure); var client = MagicOnionClient.Create<ISampleApi>(channel); //--- こんな感じのデータを投げてみる var v = new Vector2(3, 4); var result = await client.Sample(v); Console.ReadLine(); } } }
実行すると以下のようなログが出力されます。
D0911 13:58:21.959994 BeginInvokeMethod type:Unary method:/ISampleApi/Sample size:11 dump:{"X":3,"Y":4} D0911 13:58:21.979015 EndInvokeMethod type:Unary method:/ISampleApi/Sample size:9 elapsed:86.2561 dump:5
たった 1 行 2 行の簡単なログですが、ここから以下のことが読み取れます。
- 通信した時刻
- API に入ったときか出て行くときか
- 通信方法は何か (Unary / ServerStreaming / ClientStreaming / DuplexStreaming)
- どの API にアクセスしたか
- データサイズはどれだけか
- API の処理時間
- データをダンプした結果
デバッグ時に非常に役立つと思うので、ぜひ使ってみてください :)