はじめに
こんにちは、Datadog Japan で Sales Engineer をしている AoTo です。
この投稿は AoTo Advent Calendar 2023 12日目の記事です。
Orchestrion はご存知でしょうか。
Golang はコンパイル型の言語のため、Java, Python のように実行時にコードを追加することができません。アプリケーションの計装を行うには手動計装か、最近では eBPF を利用した自動計装が知られています。
これに対し Datadog は Orchestrion と呼ばれる自動的計装のツールを公開しています。
Orchestrion による automatic instrumentation は現在プライベートベータ版です。(2023/12/12現在)
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 の計装を自動的に実行できるツールを紹介してみました。現在はプライベートベータの状態ですが、誰でも簡単に試すことが可能です。
Go の手動計装をコードに記載するのが難しかったり、Go の eBPF による計装でのセキュリティやパフォーマンスの懸念がある際は試してみてはいかがでしょうか🐶