はじめに
こんにちは、Datadog Japan で Sales Engineer をしている AoTo です。
この投稿は AoTo Advent Calendar 2023 12日目の記事です。
Orchestrion はご存知でしょうか。
Golang はコンパイル型の言語のため、Java, Python のように実行時にコードを追加することができません。アプリケーションの計装を行うには手動計装か、最近では eBPF を利用した自動計装が知られています。
これに対し Datadog は Orchestrion と呼ばれる自動的計装のツールを公開しています。
Orchestrion による automatic instrumentation Compile-time instrumentation(正式名称がつきました) は現在 Private beta版です。 GA(一般公開) されました!(2024年12月)
GA(一般公開) に伴い、Datadog 公式ドキュメント にも Compile-time instrumentation としてガイドが用意されています。
Orchestrion とは
Orchestrion は Go によって書かれたコードを自動的に計装できるツールです。これはいわゆる「自動計装」とは違い、コンパイル前に自動的に「手動計装」を行なうことができるということです。
現在サポートされているライブラリは net/http, database/sql, google.golang.org/grpc, github.com/gin-gonic/gin, github.com/labstack/echo/v4, github.com/go-chi/chi/v5, github.com/gorilla/muxの7つです。この対象は順次拡大予定です🐶
この自動的な計装(automatic instrumentation) は、コードへのinstrumentライブラリのインポート・初期化を行う内容を追加し、アプリケーションのラップ処理を追加を行ってくれます。これにより、アプリケーションの処理単位でのスパンの生成と、トレースコンテキストの伝搬、トレース情報の収集が可能になります。
追加されたコードの前後にはコメントが付与されるため、その内容を見ることで差分を把握することができます。
package automaticinstrumentation
import {
"net/http"
+ "github.com/datadog/orchestrion/instrument"
}
func main() {
+ //dd:startinstrument
+ defer instrument.Init()()
+ //dd:endinstrument
mux := http.NewServeMux()
- mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("Hello World!"))
- })
+ //dd:startwrap
+ mux.HandleFunc("/", instrument.WrapHandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Write([]byte("Hello World!"))
+ }))
+ //dd:endwrap
http.ListenAndServe(":8080", mux)
}
まず、importに"github.com/datadog/orchestrion/instrument"が追加されているのが分かります。計装する対象によって、自動的に追加のインポートを行うことがあります。
続いて、//dd:startinstrumentから//dd:endinstrumentまでにdefer instrument.Init()()という形で、インポートしたinstrumentライブラリを初期化しているのが分かります。
その後、//dd:startwrapから//dd:endwrapまでに処理をinstrumentライブラリでラップしています。これによって対象の処理に準じたスパンが作成されます。
導入方法
Orchestrion の導入は、たったの2ステップで簡単に行えます。
1. Orchestrion のインストール
go installを利用して GitHub に公開されている datadog/orchestrion をインストールします。
$ go install github.com/datadog/orchestrion@latest
2. Orchestrion の実行
計装対象のコードがあるディレクトリで、orchestrionコマンドを実行します。
コマンドの通り、対象のパスを指定しても実行可能です。
$ orchestrion -w ./
検証の際はorchestrionコマンドを実行できるようexport PATH=$PATH:go env GOPATH/binなどで PATH を通しておきましょう。
完了です。問題がなければ overwriting のメッセージまでが表示されます
Scanning Package ~/<my_go_project>
overwriting ~/<my_go_project>/main.go:
たったのこれだけで、Orchestrion がコードを上書きして自動的に計装されたコードが準備されます。その内容をgit diffなどで確認した後、go buildで Go アプリケーションを開始すれば、計装された状態で Go アプリケーションを実行することができます。
Orchestrion を利用することでコードの行番号が変わるため、ビルド前に確認する必要があります。
オプション
単に Orchetrion に任せて自動的に計装するだけではなく、特定のコメントを付与することで追加の設定を反映することができます。
//dd:spanコメント
//dd:spanコメントを用いることで、スパンタグの設定や処理名の指定が可能です。
このコメントでアノテーションされる関数やメソッドはcontext.Contextを最初のパラメーターとして持つか、*http.Requestをパラメーターとして持つ必要があります。
//dd:spanコメントの書き方は以下のように、key:value形式で複数のタグを設定できnameの後に処理名を定義できます。
//dd:span <key1>:<value1> <key2>:<value2> name <CustomMethodName>
計装の削除
計装の削除も簡単に行うことができます。-rmオプションを指定することで、対象のディレクトリの内容をスキャンして Orchestrion によって計装されたコードを削除します。
$ orchestrion -rm -w .
オプションの設定
Datadog Go APM のdd-trace-goで利用できるすべての構成オプションを使用できます。これにより、環境変数を利用して統合サービスタグ付けやサンプリングの設定を行えます。
おわりに
今回は、Orchestrion と呼ばれる、Go の計装を自動的に実行できるツールを紹介してみました。現在はプライベートベータの状態ですが GA(一般公開) されたため、誰でも簡単に試すことが可能です。
Go の手動計装をコードに記載する手間に懸念があったり、Go の eBPF による自動計装でのセキュリティやパフォーマンスの懸念がある際は試してみてはいかがでしょうか🐶