Datadog Orchestrion導入を見送った理由
こんにちは、tacomsでSREをやっている佐野です。
Datadog Orchestrionというサービスの検証を行ったので、今回はその内容について書いていければと思います!
システムの課題
我々のシステム全体にトレース機能を導入したいという課題がありました。
どの処理にどれくらいの時間がかかっているのか、どこでエラーが発生しているのかを、迅速に把握できる状態にしたいと考えていました。
Datadog APMを使う
弊社ではバックエンドでGoを使用し、モニタリングではDatadogをメインで使用しています。なのでDatadog APMを使用しトレースを実装することにしていました。
実装方法としては、まず手動で作成する方法があります。
毎回StartSpanFromContext
メソッドを書かないといけないので結構面倒です。
func FetchData(ctx context.Context, url string) (string, error) {
childSpan, _ := tracer.StartSpanFromContext(ctx, "manualSpan1",
tracer.SpanType("web"),
tracer.ServiceName("noteshelper"),
)
childSpan.SetTag(ext.ResourceName, "privateMethod1")
defer childSpan.Finish()
}
もう一つの方法は、dd-trace-goパッケージのcontribディレクトリにあるものを使用することです。例えば、httpパッケージを以下のように使用することでhttpパッケージを使用する箇所のモニタリングが可能になります。
import (
"net/http"
httptrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http"
)
func main() {
mux := httptrace.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!\n"))
})
http.ListenAndServe(":8080", mux)
}
共通の課題
上記それぞれの方法を実現するためには、Goの各メソッドでcontext
を伝搬させておく必要があります。ですが、実際のコードではcontext
を伝搬をできていな箇所が多くありかつその実装回収をするのも非常に時間がかかりそうだとなっていました。そのため、このcontext
の実装回収をせずにトレースを実装できないかを検討しました。
Datadog Orchestrionとは
上記課題を検討した結果、Orchestrionというツールを知りました。Datadog Orchestrionとは、Datadog社が開発している自動計測ツールになります。これを使用することで、contextを伝搬させていなくてもトレースを実装することが可能になります。
設定
実装は非常に簡単です。以下ドキュメントに記載されている手順に従って設定していくだけとなります。
設定ファイルの生成、修正
orchestrion pin
コマンドを実行すると、以下のようなorchestrion.tool.go
ファイルが生成されます。このファイルにトレースしたいパッケージを追加することで自動で計測してくれるようになります。以下の例だと、sql, echo, httpパッケージをトレースするようにしています。
// This file was created by `orchestrion pin`, and is used to ensure the
// `go.mod` file contains the necessary entries to ensure repeatable builds when
// using `orchestrion`. It is also used to set up which integrations are enabled.
//go:build tools
//go:generate go run github.com/DataDog/orchestrion pin
package tools
// Imports in this file determine which tracer intergations are enabled in
// orchestrion. New integrations can be automatically discovered by running
// `orchestrion pin` again. You can also manually add new imports here to
// enable additional integrations. When doing so, you can run `orchestrion pin`
// to make sure manually added integrations are valid (i.e, the imported package
// includes a valid `orchestrion.yml` file).
import (
// Ensures `orchestrion` is present in `go.mod` so that builds are repeatable.
// Do not remove.
_ "github.com/DataDog/orchestrion"
// Provides integrations for essential `orchestrion` features. Most users
// should not remove this integration.
_ "github.com/DataDog/orchestrion/instrument" // integration
// 追加するパッケージ
_ "gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql" // integration
_ "gopkg.in/DataDog/dd-trace-go.v1/contrib/labstack/echo.v4" // integration
_ "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http" // integration
)
Dockerfileの修正
最後にDoclerfileの設定を修正したら完了です。
いくつか方法はあるのですが、今回はGOFLAGS
を使って対応をしました。
export GOFLAGS="${GOFLAGS} '-toolexec=orchestrion toolexec'"
アウトプット
設定後のトレースの画面は以下のようになります。
contextを伝搬させていないにも関わらず、スパンがつながっていることがわかります。
このスパンを生成する対象が、上記で設定したsql, echo, httpを元にしています。
Datadog Orchestrionの課題
Datadog Orchestrionは非常に便利なのですが、課題がいくつかあることを発見しました。
Datadog APMの料金が大幅に跳ねる可能性がある
自動計測なので、どれくらいDatadog APMの料金が跳ねるかは見積もっておく必要があります。指定したパッケージにおけるスパンが勝手に作成されるので、想像以上に多く作成されます。我々の場合は、カナリアリリースを活用し、事前に料金を計算する形をとりました。
ログとの紐付けができなさそう
これは私が分かってないだけかもしれませんが、Datadog Orchestrionで生成されたスパンとログを紐づける方法がわかっていません。これができないと、スパンでエラーがあった時に関連したログを確認することができるので、原因に早急に辿り着くことができます。
トレースが複数作成されてしまう
これが一番大きな問題になります。似たような問題はissueにもなっています。
具体的には全く同じ内容のスパンが最大3つまで重複してしまうことを観測しました。
おわりに
課題も記載した通り、Datadog Orchestrionにはクリティカルな課題である「ログとの紐付け」「トレースの複数作成」があるため、本番環境への導入はまだ早いかもしれませんね!
Discussion