Jaegerとは
Jaegerはアプリケーションの内部の処理フローの情報をモニタリングするOSSのツールです。
マイクロサービス化されたサービスに対してユーザからのリクエストが来た際、その処理時の内部での各サービスとの通信処理時の経過時間等を一連のフローとしてモニタリングができます。
OpenTracingというPJでトレース処理に関する標準仕様が定められています。
OpenTracingの実装の一つがJaegerです。その他にはZipkin等のツールが該当します。
今回はこのJaegerという分散トレーシングツールを試しに動かしてみた内容を紹介します。
Jaeger導入済みのDockerコンテナを稼働
Jaegerが導入済みのDockerコンテナが公式に公開されているので活用します。
$ docker run -d --name=jaeger -p 5775:5775/udp -p 16686:16686 jaegertracing/all-in-one:latest
All in oneのdocker imageなので、この状態で、以下にアクセスするとJaeger UIが起動しています。
Go言語でJaegerにTrace情報を連携
Trace情報をプログラム側から連携します。今回はGoのプログラムで試してみました。
ライブラリのインストール
$ go get github.com/uber/jaeger-client-go
$ go get github.com/opentracing/opentracing-go
$ go get github.com/pkg/errors
jaeger-client-goのインストール時にエラーが出る場合、
https://github.com/jaegertracing/jaeger-client-go/issues/255
こちらの記事を参考にthriftのバージョンを0.11.0未満(0.10.0)に変更してインストールし直します。
$ cd src/github.com/apache/thrift
$ git checkout 0.10.0
$ go get github.com/uber/jaeger-client-go
これで実装する準備が完了。
Goのプログラム作成
以下の内容で実装します。
package main
import (
"fmt"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
"github.com/uber/jaeger-client-go/config"
"time"
)
func main() {
cfg := config.Configuration{
Sampler: &config.SamplerConfig{
Type: "const",
Param: 1,
},
Reporter: &config.ReporterConfig{
LogSpans: true,
BufferFlushInterval: 1 * time.Second,
LocalAgentHostPort: "127.0.0.1:5775", //先程作成したDockerコンテナの5775ポートをレポート先ホストとして指定して設定(UDP通信)
},
}
tracer, closer, err := cfg.New(
"trace_sample",
config.Logger(jaeger.StdLogger),
)
if err != nil {
fmt.Println(err)
}
opentracing.SetGlobalTracer(tracer) //Tracerを作成
defer closer.Close()
someFunction()
}
func someFunction() {
parent := opentracing.GlobalTracer().StartSpan("hello") // helloという名前のspanを作成
defer parent.Finish()
child := opentracing.GlobalTracer().StartSpan(
"world", opentracing.ChildOf(parent.Context())) // worldという名前のspanを作成
defer child.Finish()
}
この処理はtrace_sampleという名前のTracerを1つ作成し、そのTracerの中にhelloとworldの2種類のspanが流れるサンプルです。
実行
$ go run jaeger_sample.go
2018/04/17 00:47:16 Initializing logging reporter
2018/04/17 00:47:16 Reporting span f0c17aac0381b01:2616aa5ab70a3528:f0c17aac0381b01:1
2018/04/17 00:47:16 Reporting span f0c17aac0381b01:f0c17aac0381b01:0:1
先程のJaeger UIから確認してみます。
Serviceの欄に先程のコード内で指定したサービス名「trace_sample」が出てきます。
Find tracesを実行するとtrace_sampleのサービスで記録されたTrace情報が1件出てきます。
この情報の詳細をチェックすると以下の図のように、helloとworldの2つのspanが登録されていることがわかります。
まとめ
今回はこちらのOpenTracingのQuick Startに記載のサンプルコードを動かして挙動を確認した程度ではありますが、アプリケーションの中で複数のサービスと連携して処理フローが走るようなものに対して、トレース処理のコードを組み込めば、どの部分でボトルネックになっているかなどが分析しやすくなるかと思います。
うまく活用できると便利になるのではないでしょうか。