Go ベースの AWS Lambda 関数に対するネイティブトレースの設定

Go で記述された AWS Lambda 関数に対してネイティブトレースを設定するには、 Instana Go Tracerをインストールして設定します。

注:Instana では、どのリージョン( GovCloud のリージョンを含む)においても、 Go ベースの AWS Lambda 関数に対してLambdaレイヤーを提供していません。 Go ベースの ` AWS Lambda ` 関数に計測機能を追加したい場合は、` go-sensor ` パッケージを手動でインストールし、「 Go Tracer のインストール 」セクションに記載されている手順に従って、ハンドラ関数をラップしてください。

サポートされるランタイム

Instana Go 1.8 以降を使用するラン go1.x タイムのネイティブトレースをサポートしています。

Go Tracer のインストール

AWS Lambda の関数からトレースデータを収集するには、 Instana Go Tracer をインストールする必要があります。

Go Tracer をインストールする前に、ラムダ監視用の Instana AWS センサーが、 AWS Lambda からバージョンおよび実行時メトリクスを収集するように設定されていることを確認してください。 詳細については、 Lambda モニタリング用の AWS センサーを参照してください。

Instana Go Tracer をインストールするには、以下の手順に従ってください:

  1. 「 Go 」トレーサーモジュールをダウンロード:

    go get github.com/instana/go-sensor
    
  2. ファイル go.mod に Go のTracerモジュールを追加してください。

Go のTracerを更新中

注: 必ず最新バージョンのトレーサーを使用してください。

Go Tracerの最新バージョンを使用していることを確認するには、プロジェクト内のファイル go.mod を確認するか、次のコマンドを実行してください:

go get github.com/instana/go-sensor@latest

最新の Go Tracerをお持ちでない場合は、最新バージョンをダウンロードし、ファイル go.mod 内のバージョンを更新してください。

AWS Lambda 関数の設定

Instana Go Tracer をインストールすると、 AWS Lambda でサービスが実行されていることを自動的に検出し、サーバーレスモードに切り替わります。 トレーサーは、収集したトレースをホストエージェントに送信する代わりに、 Instana バックエンド内の Instana サーバーレスアクセプターエンドポイントに直接送信します。

収集したトレースを Instana バックエンドに送信するには、 AWS Lambda 関数に対して以下の環境変数を設定してください:

  • **INSTANA_ENDPOINT_URL**
  • **INSTANA_AGENT_KEY**

AWS コンソール UI でこれらの変数を AWS ハンドラーに提供するには、以下のステップを実行します。

  1. 「 AWS Lambda の設定」ページで、ご自身のLambda関数をクリックします。

  2. 「環境変数」 セクションで、 「編集」 をクリックし、以下の変数を追加します。

    環境変数の構成

オプションの環境変数を使用することで、収集する HTTP ヘッダーの一覧や使用するカスタムサービス名など、トレーサーのデフォルト設定を変更できます。

トレースの使用可能化

この aws-lambda-go パッケージを使用すると、 AWS Lambda 上で Go のコードを実行できます。

Instana を使用して、 AWS Lambda のトレース、イベントのトリガー、および AWS ハンドラ関数内で実行される内部および外部の呼び出しを監視するには、まずハンドラコードに計測コードを組み込む必要があります。

Instana の計測モジュールが提供するミドルウェア・ラッパーを使用することで、ハンドラ・ instalambda コードに計測機能を組み込むことができます。

Instana 計測モジュールの追加

Go Lambda プロジェクト instalambda にこのモジュールを追加するには、ファイル go.mod が含まれているフォルダから次のコマンドを実行してください:

go get github.com/instana/go-sensor/instrumentation/instalambda

このコマンドを実行すると、インスツルメンテーション・モジュールがプロジェクトの依存関係リストおよびメインの Go Tracerに追加されます。

ハンドラー関数のインスツルメント

以下のコードスニペットは、 Go で記述された典型的な AWS Lambda 関数を示しています:

package main

import (
    "github.com/aws/aws-lambda-go/lambda"
)

func main() {
    lambda.Start(Handle)
}

func Handle() (string, error) {
    // handler code
}

ハンドラ関数は最大2つの引数を受け取り、返すことができます。 ただし、ハンドラ関数が2つの引数を受け取る場合、最初の引数は を実装している必要があります context.Context

ハンドラー関数を装備するには、以下のステップを実行します。

  1. 元のハンドラ関数から、 を使用して instalambda.NewHandler() 、計測機能を備えたハンドラを作成します。
  2. インスツルメント・ハンドラーを lambda.StartHandler()に渡します。 以下のスニペットは、コード変更を示しています。
package main

import (
    "github.com/aws/aws-lambda-go/lambda"

    // Import the in-process sensor and instrumentation packages
    instana "github.com/instana/go-sensor"
    "github.com/instana/go-sensor/instrumentation/instalambda"
)

func main() {
    // Initialize the instana.Sensor instance
    sensor := instana.NewSensor("my-lambda-handler")

    // Create an instrumented handler from your handler function
    h := instalambda.NewHandler(Handle, sensor)

    // Pass the handler to the lambda.StartHandler() invoke loop
    lambda.StartHandler(h)
}

func Handle() (string, error) {
    // handler code
}

lambda.Handler のインスツルメント

以下のコードスニペットは、次のように実装された典型的な AWS Lambdalambda.Handlerハンドラを示しています:

package main

import (
    "github.com/aws/aws-lambda-go/lambda"
)

func main() {
    h := &Handler{
        // handler configuration
    }

    lambda.StartHandler(h, sensor)
}

type Handler struct {
    // ...
}

func (h *Handler) Invoke(ctx context.Context, payload []byte) ([]byte, error) {
    // handler code
}

このようなハンドラーを実装するには、それを で囲み instalambda.WrapHandler() 、: に渡します labmda.StartHandler()

package main

import (
    "github.com/aws/aws-lambda-go/lambda"

    // Import the in-process sensor and instrumentation packages
    instana "github.com/instana/go-sensor"
    "github.com/instana/go-sensor/instrumentation/instalambda"
)

func main() {
    // Initialize the instana.Sensor instance
    sensor := instana.NewSensor("my-lambda-handler")

    h := &Handler{
        // handler configuration
    }

    // Wrap and pass the handler to the lambda.StartHandler() invoke loop
    lambda.StartHandler(instalambda.WrapHandler(h, sensor))
}

type Handler struct {
    // ...
}

func (h *Handler) Invoke(ctx context.Context, payload []byte) ([]byte, error) {
    // handler code
}

トレースコンテキストの伝播を有効にする

トレース・コンテキスト伝搬を使用可能にするには、ハンドラー・コードを更新せずに main() 関数にいくつかの変更を加える必要がある最小限のインスツルメンテーションが必要です。 ただし、ハンドラー関数の引数のリストに context.Context を追加することはできます。 context.Context を引数として追加すると、 instalambda は Lambda トリガー・イベントのスパンをコンテキストに注入します。 これらのスパンを instana.SpanFromContext() で取得し、それらを親として使用して、ハンドラー内で行われる内部呼び出しおよび外部呼び出しをトレースすることができます。

func MyHandler(ctx context.Context) error {
    // Pass the handler context to a subcall to trace its execution
    subCall(ctx)

    // ...

    // Propagate the trace context within an HTTP request to another service monitored with Instana
    // using an instrumented http.Client
    req, err := http.NewRequest("GET", url, nil)
    client := &http.Client{
        Transport: instana.RoundTripper(sensor, nil),
    }

    client.Do(req.WithContext(ctx))

    // ...
}

func subCall(ctx context.Context) {
    if parent, ok := instana.SpanFromContext(ctx); ok {
        // start a new span, using the Lambda entry span as a parent
        sp = parent.Tracer().StartSpan(/* ... */)
        defer sp.Finish()
    }

    // ...
}