Go セグメントの計測

New Relic Go 監視を利用すると、セグメント を作成できます。セグメントから、トランザクション内の特定の function やコードブロックの処理時間についての詳しいデータを取得できます。

New Relic による Go アプリの監視に関する概要情報は、Go 用 New Relic をご覧ください。

セグメントとは?

Segments [セグメント]は、トランザクションの一部についての詳細なデータを計測するためのオプション機能です。セグメントは、外部呼び出し、データストアの呼び出し、バックグラウンドタスクなどの function やコードブロックの処理時間を計測します。

以下は、セグメントの利用例です。

チェックアウト処理に関するトランザクションがあるとします。このトランザクションは、配送情報とクレジットカード情報を扱います。セグメントを使うと、発送用にセグメントを一つ、支払い用にセグメントを一つといったように、トランザクションを二つに分割して計測が行えます。

コードブロック用のセグメントの作成

トランザクションを計測しているなら、そのトランザクション内で、1つ以上のセグメントを計測できる状態にあります。

以下のパターンを使って、コードブロックをセグメントとして計測します。

segment := newrelic.Segment{}
segment.Name = "mySegmentName"
segment.StartTime = newrelic.StartSegmentNow(txn)
// ... code you want to time here ...
segment.End()

txn は、Go トランザクションの計測にも記載しているように、トランザクションが格納されている変数です。

StartSegment は、便利なヘルパーです。セグメントの生成し、開始します。

segment := newrelic.StartSegment(txn, "mySegmentName")
// ... code you want to time here ...
segment.End()

function 用のセグメントの作成

function 用のセグメントを作成する方法は、基本的にコードブロック用の作成方法と同じです。主な違いは、function にはそれぞれ終端があるため、Go の defer 文を利用できるということです。

function 用のセグメントを作成するには、function の先頭に以下のコードを追加します。

defer newrelic.StartSegment(txn, "mySegmentName").End()

txn は、Go トランザクションの計測にも記載しているように、トランザクションが格納されている変数です。

セグメントのネスト

セグメントはネスト可能です。セグメントを終了する場合は、その対象は、直近で開始しているセグメントでなくてはなりません。

以下は、あるセグメントの内における別のセグメントの開始と終了の例です。

s1 := newrelic.StartSegment(txn, "outerSegment")
s2 := newrelic.StartSegment(txn, "innerSegment")
// s2 must end before s1
s2.End()
s1.End()

ゼロ値のセグメントは安全に終了することができます。したがって、以下のコードは、条件が失敗しても安全です。

var s newrelic.Segment
if txn, ok := w.(newrelic.Transaction); ok {
    s.StartTime = newrelic.StartSegmentNow(txn),
}
// ... code you wish to time here ...
s.End()

データストアのセグメントの作成

Go アプリケーションのデータストアも計測できます。データストアのセグメントは、New Relic UI の Breakdown テーブルTransactions ページDatabases タブに表示されます。

通常のセグメントと同様に、StartTime フィールドが設定されたときに、データストアのセグメントは開始し、End メソッドが呼ばれたときに終了します。データストアのセグメントを計測するには、以下のように監視する function の先頭に配置します。

s := newrelic.DatastoreSegment{
    Product: datastore.MySQL,
    Collection: "my_table",
    Operation: "SELECT",
}
s.StartTime = newrelic.StartSegmentNow(txn)
// ... make the datastore call
s.End()

ProductCollectionOperation 値の割り当て方法について詳しく知りたい場合は、GitHub にあるデータストアのセグメントに関するドキュメントをご覧ください。

function コール全体にまたがるデータストアコールを計測するには、以下のメソッドを呼ぶだけです。

defer newrelic.DatastoreSegment{
    StartTime:  newrelic.StartSegmentNow(txn),
    Product:    datastore.MySQL,
    Collection: "my_table",
    Operation:  "SELECT",
}.End()

外部セグメントの作成

ウェブサービス、クラウド上のリソース、そのほかのネットワーク呼び出しなどの外部サービスに関する Go アプリケーションの呼び出しも計測できます。外部セグメントは、New Relic UI の Breakdown テーブルExternal services ページ に表示されます。

外部セグメントを計測する方法は、以下の二通りあります。

  1. Use ExternalSegment を使用して、エンドポイントを示す外部セグメントのパラメーターとして、URL または、 Request フィールドを設定します。

    func external(txn newrelic.Transaction, url string) (*http.Response, error) {
        defer newrelic.ExternalSegment{
            Start: newrelic.StartSegmentNow(txn),
            URL:   url,
        }.End()
    
        return http.Get(url)
    }

    RequestResponse フィールドの利用を推奨。理由としては、それらが外部呼び出しについての詳しい情報を提供するため。

  2. 別の方法として、以下のように StartExternalSegment ヘルパーが利用できます。ヘッダーを使っている New Relic アプリ間のアクティビティをトレースする際に使われるため、この方法は推奨されています。

    func external(txn newrelic.Transaction, req *http.Request) (*http.Response, error) {
        s := newrelic.StartExternalSegment(txn, req)
        response, err := http.DefaultClient.Do(req)
        s.Response = response
        s.End()
        return response, err
    }

NewRoundTripper は、PrepareRequestEndRequest 上に構築されたオプションのヘルパーです。HTTP リクエスト上で特殊な制御を可能にする Go RoundTripper インターフェースにアクセスします。これは、トランザクションと同じゴルーチン内で使う必要があります。

以下は、NewRoundTripper 計測の例です。

client := &http.Client{}
client.Transport = newrelic.NewRoundTripper(txn, nil)
resp, err := client.Get("http://example.com/")

関連情報

関連する情報は以下のとおりです。