Ponz Dev Log

ゆるくてマイペースな開発日記

grpc-javaではX-Ray SDKのAWSXRayServletFilterが使えない

JavaでgRPCサーバーを立ててX-RayのトレースIDを取ろうとしたらハマった話です。

何が起きたのか?

某所でgRPCの検証をしていてX-Rayでトレースした時に、 AWS公式の"incoming request"のやり方でAWSXRayServletFilterを使用してもトレースを取得できませんでした。

docs.aws.amazon.com

検証した環境は以下の通りです。

  • grpc-java (1.35.1)
  • grpc-spring-boot-starter (4.4.4)
  • aws-xray-sdk-java (2.8.0)

原因は何か?

ドキュメントを斜め読みしてAWSXRayServletFilterクラスを使えば良いのだなと思っていたのですが、 よくよく上記の公式のやり方を読んでみると HTTPリクエストをトレースするには(Java EEServlet APIの)Filterクラスを使うよと記載があります。

Use a Filter to instrument incoming HTTP requests. When you add the X-Ray servlet filter to your application, the X-Ray SDK for Java creates a segment for each sampled request.

さらにgrpc-javaを調べてみると、サーバーサイド実装はNettyをベースにしています。

NettyはアプリケーションサーバーをJava EEServlet APIを使わず実装しているため、 タイトル通りX-Ray SDKのAWSXRayServletFilterが使えないということが分かりました。

github.com

同じ問題はNetty実装のSpring WebFluxでもあるそうです。

stackoverflow.com

どうやって解決するか?

調べた限り、トレースIDをリクエストヘッダーから取得してコンテキストに詰める独自のServerInterceptorを実装する方法しかないようです。

幸いにも下記のリンクに参考の実装がありました。 この通り実装したところ、トレースを取得してマネジメントコンソールのX-Ray Service Mapにトレースが表示されるようになりました。

shawn-xu.medium.com


ハマったら最初に公式ドキュメントを落ち着いて読むべし。

以上。