対数犬度関数

140字以上のことを書きます

OpenTelemetryのTracingについてまとめる NettyなどにおけるContext管理編

これは何

以前の記事において,OTelのJava向け実装ではTheadLocalValueを用いてスレッドごとのContext管理を行っていることがわかりました.

しかし,JavaのModuleでは1スレッドにおいて複数のリクエストを処理するものがあり(Nettyなど),これらの場合はスレッド単位でのContext分離が実現できないと考えられます.

今回は,これらのModuleの計装を調査しどのようにContextを管理しているのかを調査します.

本ブログの内容は GitHub - open-telemetry/opentelemetry-java-instrumentation at release/v2.13.x の内容に基づきます.

まとめ

わかったこと

  • ChannelInboundHandlerchannelReadメソッド内でContextを作成し,ChannelのAttributeに紐づけている
    • ChannelがEventloopに割り当てられてリクエストが処理される+ChannelのAttributeは安全な形で値を扱えるため,リクエストごとにContextを分離できる

わからなかったこと

  • このContext管理では,ユーザーはOTelのAPI経由でリクエスト内で対応するSpanを参照できないのでは?
    • ChannelのAttributeに紐づくため,OTel Contextからの参照でなくChannnelのAttribureからContextを参照しないと対応するContextが安全に取得できない

調査

Auto-Instrumentationの実装を見る

Netty 4.1向けの計装処理を見ていきます.

github.com

libraryディレクトリ以下はライブラリ特有の拡張機能を用いた計装処理の実装が記載されているため,こちらを見ていきます.

github.com

serverディレクトリ以下にサーバー向けの実装が配置されています. リクエスト受信時の処理と考えられるopentelemetry-java-instrumentation/instrumentation/netty/netty-4.1/library/src/main/java/io/opentelemetry/instrumentation/netty/v4_1/internal/server/HttpServerRequestTracingHandler.java at release/v2.13.x · open-telemetry/opentelemetry-java-instrumentation · GitHub を見ていきましょう.

github.com

ここで,io.netty.channel.ChannelInboundHandlerAdapterインターフェースを継承した HttpServerRequestTracingHandlerが定義されています. io.netty.channel.ChannelInboundHandlerAdapterはソケットからアプリケーションまでのデータの流れの中で実行する処理をまとめたクラスであり,channelReadメソッドはChannelがリクエストを受け取った際に実行される処理です.

netty.io

yuya-hirooka.hatenablog.com

HTTPリクエストを受信した際の処理に注目して追っていくと,

  1. ServerContextsクラスのgetOrCreateを呼び出し(36行目)
  2. 新たなContextクラスのインスタンスを生成(57行目)
  3. ServerContextsクラスのインスタンスaddListを実行(58行目)
  4. ContextクラスのmakeCurrentを実行(60~70行目)

となっています. このうち2行目のServerContextsクラスの実装を見てみると,引数に与えたChannelのattributeにServerContexts自身を追加していることがわかります.

github.com

netty.io

ServerContextsクラスがDequeで管理しているServerContextはOTelのContextクラスのWrapperクラスと考えられます.

github.com

これらのことから,Netty用の計装の実装ではリクエスト受信時に実行されるハンドラーを使いChannelにOTelのContextを紐づけてContextの管理を行っていると考えられます.