[feat] WithOpenTelemetry()#76
Conversation
Signed-off-by: 卜部 昌平 <s-urabe@sakura.ad.jp>
Signed-off-by: 卜部 昌平 <s-urabe@sakura.ad.jp>
|
少し内部で話しましたが、profile/envvar等で https://github.com/sacloud/sacloud-otel-collector への設定をしたら、そこへ投げる機能も欲しいかなと思いました。そうすればsaclient-goを利用する各プロダクトでセットアップの重複がなくなります。 別のパッチで対応するのも問題ないかなと思います。 |
yamamoto-febc
left a comment
There was a problem hiding this comment.
otelt対応は是非にというところなのですが、otel SDK + contribへの依存が発生してしまう、かつ今の所これらは結構な頻度で更新されているイメージなので頻繁に取り込みが必要というのがなやましいですね...
saclient-goは低レベルなライブラリで他のSDKから依存される側なのである程度安定して欲しい思いがあります。
iaas-api-goではこの問題への対応としてotel対応については別のgoモジュールにして必要な人だけotel依存部分を使ってもらうようにしていました
https://github.com/sacloud/iaas-api-go/tree/main/trace/otel
salient-goの場合は現状の実装だと別モジュールにするのは厳しいですかね..??
http.Clientまたはhttp.ClientのTransport(RoundTripper)を差し替え可能にする方向に持っていくのもありかもですがちょっと大きな変更になるかもです。
|
プルリクエストをあしがかりに議論が進むのは良いことだと思います!少なくともこのプルリクエストは今のままの状態でいきなりマージはせず、方向性をもんでいきたいです。 現在、主にトレースしたくなっているのは go-retryablehttp の中でクライアントサイドでリトライが発生している場合、ですので、これをcontrib依存ぬきで実現するには、 |
|
contribを使うこと自体は問題ないと思っています。ただ、現状だと利用者の側でcontribに依存する/しないを選べず常に依存してしまうのでそれはなんとかしたいなと考えています。
また、必ずしもTransportをゼロから実装する必要はないと思います。
あたりをしておけばクライアント側はそこまで大変ではないかと思います。 |
|
https://pkg.go.dev/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp#NewTransport
この
になっていますけれど、これだと、DefaultTransportしか使えないじゃないですか? なにを言っているかというと、我々が c1, _ := saclient.Client{}.DupWith(WithTransport(t1))
c2, _ := c1.DupWith(WithTransport(t2), ...)みたいなことはできない(書いてもc2はt1かt2のどちらかしか動かないようにしか実装できない)ですよねえ。otelhttpとしては本来はそういう、多段階でRoundTripperをネストして使うみたいな用途では |
|
論点は2つですかね?
前者については
こちらの通り利用者側で組み立ててもらえば良いと思います。http.RoundTripperはインターフェースになっているのは、そこにどのような実装を当てはめるのかを利用者の責務としているからだと思っています。 これで行くと後者も差し替えで良いと思っていまして、c2ではt2を使えばOK、t2でt1とchainさせたいなら予め利用者側でそのようにRoundTripperを組み立ててね、とするのがシンプルそうです。 |
|
別の論点として仮に |
|
うーん、「利用者側」が、必ずしもすべての組み合わせをコントロールできるかというと、違うよなあというのがMiddlewareが求められた由来なのですよね。たとえば もう少し言うと、たとえば |
|
利用者がSDKとアプリなど複数の種類があり、最終利用者にRoundTripperの組み立て責務を寄せ切れない、という点は理解しました。 ただ、そのこと自体は「矛盾なく合成しやすい拡張ポイントが必要」という話であって、直ちに middleware を選ぶ理由ではないようにも見えています。 この議論は詰めていくべきだとは思うのですが、議論がPRでやりたかったことと少々ずれてきたように思います。 一旦 #76 (review) の議論に戻りたいのですが、
あたりを判断する必要がありそうです。 1)について、otel対応はぜひ使いたい、かつ後から依存を消すこともできるはずなので一旦otel依存は許容する、でも良いのではないかと思い始めています。 2)は別Issueにして引き続き議論するというのでいかがでしょうか? |
|
SDK で otel trace を扱えるというのは2段階あると思っています。
1だけやる場合 import "..../saclientotel" // 独立したgo.modをもってotel依存はここに持たせる
var c saclient.Client
err := c.SetWith(saclientotel.WithTracePropagation())のようにしてやれば、SDKを使う側は明示的にimport+client生成をすることになるので、使わない場合の依存は増えません。暗黙で ctx に入った trace を引き継いでしまうと、ユーザーとしては意図しないtraceの外部漏洩にもなりかねないので、opt-in のためにも必要そうです。 2までやる場合はotel依存が全体に差し込まれることになりますが、その場合も |
OpenTelemetry のトレーサーに対応します。そういったものは大抵プロセスグローバルな設定があり、SDKの外側からなんらかの方法で注入されることと思いますので、そのようなAPIを用意しました。