雑なメモ書き

気楽にいきます

OpenCensusについて調べてみた

OpenCensusとは

  • https://opencensus.io/
  • サービスからメトリクスと配布トレースを収集する単一のライブラリ
  • 各言語のライブラリが出ているが今回はGoを調べる
  • サポートされているバックエンドも多い
  • 所謂分散トレーシングシステムへ格納する
    • Azure Monitor、Datadog、Instana、Jaeger、SignalFX、Stackdriver、およびZipkin

分散トレーシングシステムとは

  • https://techlife.cookpad.com/entry/2017/09/06/115710

  • 2種類のアプローチがある

    • Black-box schemes
    • Annotation-based schemes
      • 特定のリクエストを分析することがでる
        • トレースIDを発行することによりログを追跡を可能にする
        • スパンIDを使用することによりログの親子関係を識別可能にする
  • 今回対象にしているのは後者のAnnotation-based schemesの方

取得データ

この2種類がある。

Trace

git clone https://github.com/opencensus-otherwork/opencensus-quickstarts
cd opencensus-quickstarts/go/tracing-to-zipkin
go get go.opencensus.io/* && go get go.opencensus.io/exporter/zipkin
# zipkinのインストール
curl -sSL https://zipkin.io/quickstart.sh | bash -s
# zipkin起動
java -jar zipkin.jar
  • サンプルを実行して以下へアクセス
  • 各Spanとそれにかかった処理時間等が表示される

サンプルの内容

  • サンプルは以下の内容が実行される
1. Configure exporter to export traces to Zipkin.
2. Configure 100% sample rate, otherwise, few traces will be sampled.
3. Create a span with the background context, making this the parent span.
4. Start a child span. This will be a child span because we've passed
5. Make the span close at the end of this function.
6. Set status upon error
7. Annotate our span to capture metadata about our operation

traceへのexporterの登録

traceへ生成したexporterを登録している

trace.RegisterExporter(ze)
  • このopencensusは設計上複数のexporterが持てるので
  • exportersMapへexporterを登録している
func RegisterExporter(e Exporter) {
    exporterMu.Lock()
    new := make(exportersMap)
    if old, ok := exporters.Load().(exportersMap); ok {
        for k, v := range old {
            new[k] = v
        }
    }
    new[e] = struct{}{}
    exporters.Store(new)
    exporterMu.Unlock()
}

traceのサンプルレート

  • このtraceのconfigへセットしているDefaultSampler
trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})

これはsetIsSampledで収集対象にするかに使用されている

span.spanContext.setIsSampled(sampler(SamplingParameters{
    ParentContext:   parent,
    TraceID:         span.spanContext.TraceID,
    SpanID:          span.spanContext.SpanID,
    Name:            name,
    HasRemoteParent: remoteParent}).Sample)

ここを遡っていくとatomicが出てくる

func (sc *SpanContext) setIsSampled(sampled bool) {
    if sampled {
        sc.TraceOptions |= 1
    } else {
        sc.TraceOptions &= ^TraceOptions(1)
    }
}

出力結果

  • 各処理の経過時間が取れている
  • stackdriver/traceの方を使用すると割と詳しい内容が出る

f:id:hiroyukim:20190310114104p:plain