この連載記事では、gRPC通信をしている.NETアプリに関してNew Relic .NET Agentを使ってgRCP部分の計装がどこまでできたかに関する調査をまとめたいと思います。

調査の動機としては、ドキュメント上にはサポートされるラリブラリとしてgRPCの記載がないことが挙げられます。

.NET agent: compatibility and requirements for .NET Core | New Relic Documentation

そのため、検証結果によらずgRPC関連の計測に関してはサポート対象外となります。が、検証した限り、ある程度の計測は可能だと分かりましたので、お客様が利用するかどうかの判断の助けになるよう結果を共有することにしました。

まず最初の記事として、一番基本的なgRPCサーバーとコンソールアプリによる通信の計測を取り上げます。計測対象となるアプリは、.NET のドキュメントにある手順で作成したものになります。

チュートリアル: ASP.NET Core で gRPC のクライアントとサーバーを作成する

今回はクライアントとしてはコンソールアプリケーションでサーバーがASP.NET Coreを利用しており、両者とも.NET Coreで動作します。また、検証ではdocker desktopを使った環境で行っています。

実際に動かしたコードはGitHubで公開しています。

New Relic .NET AgentによるgRPCアプリの計測デモアプリ

さて、結果ですが、gRPC向けの特別な計装コードを追加することなくExternalとして計測し分散トレーシングがつながることが確認できました。ただし、コンソールアプリケーションではトランザクションとして計測するためにはカスタム計装が必要です。これはgRPC通信に限らない挙動となっています。カスタム計装についてはこちらのドキュメントに説明があります。

.NETカスタムインストゥルメンテーションの概要

今回必要なカスタム計装はトランザクションとして計測したいメソッドにNewRelic.Agent.ApiパッケージのTransaction属性を追加するだけです。

準備できたら、用意したdocker composeファイルを使ってクライアントとサーバーアプリの両方を起動します。しばらくするとNew Relic UIでDOTNET_GRPC_ClientとDOTNET_GRPC_Serviceという名前で2つのアプリが確認できます。

まず、クライアント側のDOTNET_GRPC_Clientから見ていきましょう。属性を追加した処理のスループット(サンプルでは1分間に1回)や所要時間の時間変化が確認できます。

grpc client APM

External servicesのUIに移ると、gRPCによる通信先であるGRPC_DOTNET_ServiceアプリがExternal Entityとして表示され、そのパフォーマンスが確認できます。

gRPC Client External UI

Distributed tracingのUIから該当のトレースを表示するとクライアントスパンとサーバースパンがそれぞれ確認でき、分散トレーシングがgRPC通信でも繋がっていることが確認できます。

grpc distributed trace

また、スパンの属性を見ると、gRPC通信で付与されるHTTPのヘッダーを確認できます。

grpc distributed trace span attribute

そして、サーバー側であるGRPC_DOTNET_Serviceアプリを開くと、gRPC通信を行なっているサーバーサイドの処理が計測できていることがわかります。サーバーサイドに関してはNew Relic .NET Agentをインストールしただけの状態で計測できています。

grpc server APM
grpc server APM Traces

以上のように、gRPC通信は特別な計装なく.NET Agentでも計測できることがわかりました。今後はもう少し複雑なケースでの検証を進めたいと思います。検証してほしいシナリオなどがありましたら、ぜひご連絡ください。