oinume journal

Scratchpad of what I learned

OpenTelemetryとhttptrace.ClientTraceを使ってHTTPリクエストのlatencyを可視化する

この記事は OpenCensusとhttptrace.ClientTraceを使ってHTTPリクエストのlatencyを可視化する - oinume journal のOpenTelemetry版。OpenTelemetryについては OpenTelemetryとは何か、そしてなぜそれが計装器の未来なのか? | New Relic を見てもらうのが手っ取り早くて、httptrace.ClientTraceについては先のブログを見てもらえればと。

OpenTelemetry Tracing + httptrace.ClientTrace

早速本題に入ってしまうと、以下のようなコードを書くことでhttp.ClientでHTTPリクエストを送った際のlatencyを可視化することが可能になる。

以下のように otelhttptrace.NewClientTraceで生成したClientTraceをctxにセットし、そのctxをhttp.Requestにセットするだけで良い。

clientTrace := otelhttptrace.NewClientTrace(ctx)
ctx = httptrace.WithClientTrace(ctx, clientTrace)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
...

Jaeger UIでの確認

https://github.com/oinume/go-http-client-trace-sample/ のリポジトリをcloneしてdocker-compose up -dするとJaegerが立ち上げることができる。

$ git clone https://github.com/oinume/go-http-client-trace-sample
$ docker-compose up -d
$ go run ./examples/otelhttp_client_trace/main.go

のように、Jaegerを立ち上げてサンプルコードを実行するとJaegerのexporterにトレースの情報が送られる。そのトレースの情報は http://localhost:16686/search にブラウザでアクセスすると見ることができる。以下のスクショを見てもらうとわかるように、http.getconnhttp.dnshttp.tlsなど、httptrace.ClientTraceのコールバックメソッドごとにSpanが作成され、それがどのぐらい時間がかかっているのかがわかるようになっている。

OpenCensusとOpenTelemetryの違い

httptrace.ClientTraceに関わるところで、OpenCensusとOpenTelemetryで微妙に挙動が違うところがあったので、メモしておく。

OpenCensusの場合はデフォルトではhttp.getconnhttp.dnsなどの情報がSpanにならないが、OpenTelemetryの場合はそれぞれSpanになっている。この挙動で注意した方が良いのは、例えばGCPのCloud Traceだとスパン単位で従量課金されるので、場合によっては金額が大きくなってしまうかもしれない。しかし、以下のようにWithoutSubSpansを指定することでSpanを生成しないようにすることができる。

clientTrace := otelhttptrace.NewClientTrace(ctx, otelhttptrace.WithoutSubSpans())

最後に

OpenTelemetryのTracingについては各言語のSDKも揃ってきて、クラウドベンダーの対応もされてきているので、そろそろ実戦投入していこうと思った。