Datadog APMをGoで使う


はじめに

Datadog APMの簡単な特徴とGoで使用するための方法をまとめました。

公式サイトのドキュメントを見ていただくことを勧めますが、
補足資料として見ていただければと思います。

公式ドキュメント
TraceパッケージのGoDoc

また、ここではDatadogのAPM以外の機能については割愛します。

APMとは

Application Performance Managementの頭文字をとった略語で、一般的にはアプリケーションやシステムの性能を管理・監視するものです。

DatadogのAPMではマネージドクライド、オンプレミスに関わらず分散トレーシングに対応しています。
Flame GraphやSpan Listなど整理された形でトレース結果を取得できるようになっています。

  • Flame Graph
  • Span List

使用するには

  • Agentのインストールと起動
  • APM用パッケージを取得

Agentのインストール

下記のページから各環境に合わせてインストールとAgentの起動を実施します。
https://app.datadoghq.com/account/settings#agent

基本的には上記のページに従ってインストールを実施すればAgentプロセス起動も実施してくれるが、再起動等を行う場合や設定を変更する場合は下記を参照してくだしあ

APM用パッケージを取得

go get gopkg.in/DataDog/dd-trace-go.v1/ddtrace

トレースの仕方

TraceとSpan

トレースを行うにあたり下記の要素が存在します。

用語 内容
Trace アプリケーションにおけるトレースの開始・実行の単位
Span 1ロジックの開始・終了の実行時間を計測する単位。Traceは1つ以上のSpanを持つ。Span同士は親子関係をもたせられる
Service 処理の名前。複数Spanを一つのService名にすることも、各々独自のService名にすることも可能
Resource 処理の中身を示す。DBにおけるSQLクエリやHTTPにおけるクエリなどを格納する

Span

トレースしたい処理の開始から終了までの計測単位を指します。
Spanはさらに細かいSpanを配下に持つことが可能です。

トレースの中における親子Spanの関係

例えばWebの1リクエストにおけるトランザクションを親Spanとし
その配下にDBのSpan、キャッシュのSpan、外部通信のSpanやさらには特定のロジックなどを子Spanとすること可能です。

ソース

Datadog APM用のパッケージは下記の通りです。

GitHub
説明

こちらをトレース開始・終了、必要Spanの開始終了に伴い実行していく

1. トレース開始

tracer.Start()  
defer trace.Stop() // Close 

2. 汎用的なSpan

Spanの開始と終了

span, ctx := tracer.StartSpanFromContext(ctx, 
    "parent-op", // operation Name
    tracer.ServiceName("parent-service"), // Service Name(必要であれば入れる)
    tracer.ResourceName("parent-resource"), // Resource Name(必要であれば入れる)
)

defer span.Finish()

子Spanの使用

先程作成したSpanの配下に子Spanを設ける場合
親が投入されたcontext.Contextを使用して子Spanの開始すれば親Span情報が継承されます。

子Spanの開始と終了

span, ctx := tracer.StartSpanFromContext(ctx, 
    "child-op", // operation Name
    tracer.ServiceName("child-service"), // Service Name(必要であれば入れる)
    tracer.ResourceName("child-resource"), // Resource Name(必要であれば入れる)
)

defer span.Finish()

専用Spanパッケージを使用する

各パッケージのGoDoc一覧

Web(HTTP Routing)用Span

アプリケーションのHTTPのRoutingで下記のいずれかのパッケージを使用していた場合は専用のパッケージが存在します。

もともと使用しているpackage Datadog APM package
net/http https://godoc.org/gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http
gorilla/mux https://godoc.org/gopkg.in/DataDog/dd-trace-go.v1/contrib/gorilla/mux
julienschmidt/httprouter https://godoc.org/gopkg.in/DataDog/dd-trace-go.v1/contrib/julienschmidt/httprouter

gorilla/mux使用の場合

router = muxtrace.NewRouter(    
    muxtrace.WithServiceName("web-service"),  // ServiceName設定
)

router.HandleFunc("/", handler)
http.ListenAndServe(":8080", router)

DB用Span

database/sql使用の場合

// 登録(DBはMySQLの場合、ServiceNameは省略可)
sqltrace.Register("mysql", &mysql.MySQLDriver{}, sqltrace.WithServiceName("db"))

// traceに登録済のdriverを使用してDBをオープン
db, err := sqltrace.Open("mysql", "user:password@/dbname")
if err != nil {
    log.Fatal(err)
}

// Span作成・開始
span, ctx := tracer.StartSpanFromContext(ctx, 
    "db", // operation Name(必要であれば入れる)
    tracer.SpanType(ext.SpanTypeSQL),
    tracer.ServiceName("db"), // DB用Service Name(必要であれば入れる)
    tracer.ResourceName("db-access"), // Resource Name(必要であれば入れる)
)

// contextを通じて親Spanを継承している
rows, err := db.QueryContext(ctx, "SELECT * FROM memo")
if err != nil {
    log.Fatal(err)
}
rows.Close()
span.Finish(tracer.WithError(err)) // Span終了

その他

Agent関連

Agentのインストールの詳細

Agentのインストールを実施するとdatadog.yamlが指定の場所にダウンロードされます。Agentはそのyamlファイルを設定ファイルとして使用します。

datadog.yamlの設定サンプルはこちら

ダウンロードしたデフォルト設定のままでAPMは使用可能ですが、
API Keyを変えたりAPM関連の設定を変えたりした場合はdatadog.yamlの中身をチェックする必要があります。

  • API Keyが正しく指定されているか
  • APM関連の各種設定

設定変更後はAgentの再起動を行う
再起動コマンドはこちら

Agentコマンド

Agentの起動・終了・再起動コマンド
https://docs.datadoghq.com/ja/agent/guide/agent-commands/?tab=agentv6v7

Grpcの場合

こちらを参考にgRPC Client側/Server側それぞれにTraceとSpanを設けた場合

下記のようにトレースされます。

OpenTracing, OpenCensus, OpenTelemetry

分散トレーシング標準仕様でOpenTracing, OpenCensusに対応済み

OpenTelemetryはまだ正式なRegistoryには入っていない模様(2020/04/10現在)
https://opentelemetry.io/registry/

この辺は今後も見ていきたいです。

最後に

以上のようにセットアップも非常に簡単です。
また、有料サービスだけあって専用サーバー管理がいらないのは楽で良いです。

ただ、もし実導入するようであればトレーシングによるアプリの負荷については注意深く見ておく必要があると思います。(Datadogに限った話ではないのですが)