Go collector: 一般的な操作に関するFAQ

以下のセクションでは、 Go コレクターの一般的な操作に関する質問について確認できます:

構成

Go コレクターの設定に関するよくある質問について解説します。

一般

以下のセクションでは、 Go コレクターの設定に関する一般的な質問について説明します

Go コレクターを初期化する方法

Go コレクターを初期化するには、関 main() 数の先頭で instana.InitSensor() を呼び出し、設定オブジェクト *instana.Options を指定します:

import instana "github.com/instana/go-sensor"

func main() {
    instana.InitSensor(&instana.Options{
        // ...
    })

    // ...
}
 

Go コレクタは、 関数 instana.InitSensor() に渡される構成オブジェクトの初期化されていないフィールドに対して、 instana.DefaultOptions() の値を使用します。

注: この初期化処理により、 Go サービスが Instana のUIに表示され、その実行時メトリクスが報告されます。 トレース情報を確認するには、 まずアプリのコードに計測コードを組み込む必要があります。

Go コレクターをレディネスプローブに組み込む方法は?

トラフィックをインスタンスに送信する前に、 Go Collector がアナウンス処理を完了し、トレースの収集準備が整っていることを確認するには、次の instana.Ready() メソッドを使用します:

// Every 100ms whether Go Collector is ready and return on success
func awaitInstanaReady(ctx context.Context) error {
    ticker := time.NewTicker(100*time.Millisecond)
    defer ticker.Stop()

    for {
        select {
        case <-ticker.C:
            if instana.Ready() {
                return nil
            }
        case <-ctx.Done():
            return ctx.Err()
        }
    }

    return nil
}
 

シャットダウン前にすべてのトレースデータが送信されたことを確認するにはどうすればよいですか?

収集されたすべてのトレースがホストエージェントまたはサーバーレスアクセプターに確実に送信されるようにするため、 Go コレクター( API )では メソッド instana.Flush() を提供しています。 このメソッドは、エージェント・クライアントがバッファーに入れられたすべてのデータを即時に送信するように強制します。 これはブロッキング操作であり、サービスが正常に終了できるように、この操作のタイムアウトまたは締切を定義することをお勧めします。

func main() {
    var srv http.Server

    // Initialize and use http.Server
    // ...

    // Server shutdown sequence:
    // 1. Finalize all pending requests and close the server
    shutdownCtx, _ := context.WithTimeout(ctx, 5 * time.Second)
    if err := srv.Shutdown(shutdownCtx); err != nil {
        // ...
    }
    // 2. Flush all buffered traces to the agent
    flushCtx, _ := context.WithTimeout(ctx, 5 * time.Second)
    if err := instana.Flush(flushCtx); err != nil {
        // ...
    }
    // ...
}
 

サービスが AWS Lambda instana.Flush() で実行されている場合、ハンドラーが完了すると Go Collector によって自動的に呼び出されるため、これを手動で行う必要はありません。

注: instana.Flush() は Go Collector のデータ伝送サイクルを妨害する可能性があります。これを使用することは、サービス存続期間中 (例えば、HTTP 要求の処理の終了時) にトレース・データの配信に影響を与えることは推奨されません。 Go Collector がこのメソッドを呼び出した後も操作可能な状態を維持する保証はありません。

サーバーレス環境で稼働するように Go コレクターを構成する方法

サーバーレス環境 (AWS Fargate や Google Cloud Run など) で実行されるサービスのモニターに Go コレクターを使用するには、タスク定義で INSTANA_ENDPOINT_URL 環境変数と INSTANA_AGENT_KEY 環境変数が設定されていることを確認してください。 この実行方法の詳細な説明については、Instana 文書の個々のセクションを参照してください。

注: アプリがサーバーレスモードで実行されている場合、環境変数 ` INSTANA_AGENT_PORT ` INSTANA_AGENT_HOST および `` は無視されます。

サーバーレス環境で実行されているサービスは、メトリクスやトレースデータを Instana バックエンドに送信するためにホストエージェントを使用しないため、通常のように ファイル configuration.yaml を使用してアプリ内コレクターを設定する方法は適用できません。 代わりに、オプションとしてサービス・タスク定義で構成できる一連の環境変数があります。

環境変数 デフォルト値 説明
INSTANA_TIMEOUT 500 Instana バックエンド接続のタイムアウト (ミリ秒)
INSTANA_SECRETS contains-ignore-case:secret,key,password シークレット・フィルター (プロセス環境変数にも適用)
INSTANA_EXTRA_HTTP_HEADERS なし 着信要求から収集する HTTP ヘッダーをセミコロンで区切ったリスト
INSTANA_ENDPOINT_PROXY なし Instana バックエンドへの接続に使用するプロキシー URL
INSTANA_TAGS なし ECS タスクに関連付けるオプション値が含まれたタグをコンマで区切ったリスト
INSTANA_ZONE <Current AWS availability zone> 当該サービスのカスタム Instana ゾーン名

これらの変数およびその値の形式に関する詳細については、 Instana のドキュメントをご参照ください。

機密データを編集するように Go コレクターを構成する方法

Instana が提供する一部のインスツルメンテーション・ラッパー (HTTP サーバーとクライアントのラッパーなど) が収集するデータには、機密情報 (パスワード、鍵、シークレットなど) が含まれていることがあります。 これらの値が漏えいしないようにするために、Go Collector はエージェントに送信する前にこれらの値を <redacted> に置き換えます。 パラメータ名マッチャーのリストは、 Host Agent設定 com.instana.secrets ファイルのセクションで定義され、アナウンスフェーズ中にアプリ内トレーサーに送信されます(エージェント Go トレースプラグイン com.instana.sensor-golang-tracev1.3.0 以降が必要です)。

シークレット・マッチャーのデフォルト設定は contains-ignore-case で、用語のリストは keypasswordsecretです。 これにより、大/小文字を無視したこれらのストリングを含むいずれかに名前を付けるパラメーターの値が編集されます。

HTTP の追加ヘッダーを収集するにはどうすればよいですか?

HTTP インスツルメンテーション・ラッパーは、HTTP ヘッダーを収集し、着信または発信要求スパンと一緒に送信することができます。 大文字小文字を区別しないヘッダー名のリストは、 に渡される instana.InitSensor() オプションオブジェクトの フィールド内 (instana.Options).Tracer.CollectableHTTPHeaders と、 ホストエージェント設定ファイルの両方で指定できます。 後者の設定が優先され、エージェントの Go トレース・プラグイン com.instana.sensor-golang-trace v1.3.0 以降のバージョンが必要です。

instana.InitSensor(&instana.Options{
        // ...
        Tracer: instana.TracerOptions{
                // ...
                CollectableHTTPHeaders: []string{"x-request-id", "x-loadtest-id"},
        },
})
 

この設定は、ホストエージェント設定ファイルにおける以下の設定に相当します:

com.instana.tracing:
  extra-http-headers:
    - 'x-request-id'
    - 'x-loadtest-id'
 

HTTP インスツルメンテーションでは、デフォルトではヘッダーが収集されません。

ロギング

Go Collector は、レベル・ロガーを使用して内部エラーおよび診断情報をログに記録します。 デフォルトの github.com/instana/go-sensor/logger.Logger は、log.Lstdflags で構成された log.Logger をバックエンドとして使用し、メッセージを os.Stderr に書き込みます。

サード・パーティーのロガーを使用して Go コレクターのログを出力する方法

Go コレクターを、この instana.LeveledLogger インターフェースに準拠したサードパーティ製のロガーを使用するように設定できます。 たとえば、 や github.com/sirupsen/logrus については go.uber.org/zap 、[ instana.SetLogger()][ instana.SetLogger ] の方法を使用します:

import (
    "github.com/uber-go/zap"
    instana "github.com/instana/go-sensor"
)

func main() {
    logger, _ := zap.NewProduction()
    defer logger.Sync()

    instana.SetLogger(logger)
}
 
注: サードパーティ製のロガーを使用する場合、環境 INSTANA_DEBUG 変数は機能しません。 サード・パーティーのロガー・モジュールの資料を参照して、環境変数や構成ファイルからデバッグ・レベルを設定する方法を確認してください。

アプリケーション・コードを変更せずに Go コレクターのデバッグ・ログを有効にする方法

アプリケーション・コードを変更せずに Go コレクターがデバッグ・ログを書き込めるようにするには、INSTANA_DEBUG 環境変数を空でない値に設定します。以下に例を示します。

export INSTANA_DEBUG=true
./your-app
 

Go コレクターが生成するデバッグ・ログの量は、アプリケーションによって異なりますが、かなりの量になることがあります。 Instana サポートに問題を報告する前に、デバッグ・ログを一時的にオンにして情報を収集することをお勧めします。

注: この設定は、 Go Collectorが内部ログメッセージの出力に logger.Logger を使用している場合にのみ有効であり、アプリコード内からログレベルを変更しようとする試みをすべて上書きします。

誤った呼び出しに関連するログに記録されたエラーや警告を収集するにはどうすればよいですか?

Instana Go Collectorは、エラーおよび警告のログレコードを自動的に収集し、 github.com/sirupsen/logrus エージェントに送信するための 用ラッパーを提供します。 github.com/instana/go-sensor/instrumentation/instalogruslogrus.Hook 、あらゆるエラーや警告レコードを処理し、それらをレコード内に含まれるスパン context.Contextに関連付ける実装を提供します。 以下に、グローバル logrus.Loggerを装備し、装備された http.Handler内で使用する方法の例を示します。

func main() {
        // ...

        // Register instalogrus hook within the global logger
        logrus.AddHook(instalogrus.NewHook(sensor))
}

func myMethod(w http.ResponseWriter, req *http.Request) {
        // ...

    // When logging an error, make sure to provide the context.Context containing
    // an active span, so that instrumentation hook could associate this message
    // with a call.
    logrus.WithContext(req.Context()).Error("something went wrong")

    // ...
}
 

より詳しい例については、パッケージのドキュメントを参照してください。

Instana AutoProfile™

Instana AutoProfile™ プロセスプロファイルを生成し、 Instana に報告します。 開発時のプロファイラーやオンデマンドのプロファイラーではユーザーが手動でプロファイル作成を開始する必要がありますが、それとは異なり、AutoProfile は重要な実稼働環境に適したプロファイル作成を自動的にスケジュールし、継続的に実行します。

アプリケーション・コード内から継続的なプロファイル作成を永続的に有効にする方法

サービスの継続的なプロファイル作成を永続的に有効にするには、センサーの初期化中に EnableAutoProfile: true を指定します。

func main() {
    instana.InitSensor(&instana.Options{
                EnableAutoProfile: true,
                // ... other options
        })

        // ...
}
 

アプリケーション・コードを変更せずに継続的なプロファイル作成を有効にする方法

コードを変更せずにアプリに対して AutoProfile™ を有効にするには、以下のように INSTANA_AUTO_PROFILE=true 環境変数を設定します。

export INSTANA_AUTO_PROFILE=true
./your-app
 
注: デバッグログの有効化と同様に INSTANA_DEBUG 、この設定値が優先され、アプリケーションコード内からプロファイリングを無効にしようとする試みはすべて上書きされます。

インスツルメンテーション

トレース・データを収集して Instana に送信するには、アプリケーション・コードを変更する必要があります。 このプロセスはコード・インスツルメンテーションと呼ばれます。

Go コレクターでは、2 つの方法でコードをインスツルメントできます。

  1. 付属のコード・ラッパーを使用する方法。 ごくわずかな変更が必要なコードをインスツルメントする場合は、これが最も簡単な方法です。 Instana は、データベース・ドライバー、HTTP フレームワークなど、最も一般的な サードパーティ ライブラリー用のインスツルメンテーション・モジュールを提供することを目的としています。 まだ対応する計測モジュールがないライブラリを使用している場合は、 Instana の「機能提案」 機能を利用して、機能リクエストを提出することを検討してください。
  2. OpenTracing の使用方法 API. より低レベルなアプローチであり、場合によってはコード・ベースに大量の変更を加える必要があります。 一方で、ビジネス固有のコード部分をインスツルメントする場合は、きわめて柔軟に対応できます。

Instana では、インフラストラクチャーの相関と呼び出しの表現が正しく行われるように、特殊なスパン・タグのセットを使用していることに注意してください。 トレース・データを最大限に活用するには、OpenTracing API アプローチではなく、付属のコード・ラッパーの使用を優先してください。 必要であれば、コード・ラッパーと低レベルのアプローチを併用して、既存の保守されているコードを活用しながら、ビジネス固有のコード部分を柔軟にインスツルメントすることを検討できます。

HTTP サービス

Go コレクターでは、net/http パッケージを使用するクライアントとサーバーのインスツルメンテーションが可能です。 有効化されると(詳細は後述)、この監視ツールは受信および送信されるリクエストに関する情報を自動的に収集し、 Instana エージェントに送信します。

サードパーティ製の HTTP フレームワーク向けのインストルメンテーションモジュールは、個別の Go モジュールとして提供されており、 HTTP サービスのインストルメンテーションをより便利に行うことができます。

HTTP サーバー・ハンドラーをインスツルメントする方法

Instana は、http.HandlerFunc のラップをサポートしているため、要求のトレース、および要求スパンのコンテキストで実行される子スパンの収集を簡単に実現します。

Instana で必要な情報をキャプチャーできるようにするための変更は最小限で済みます。 現在ある http.HandlerFunc をラップするだけで、Instana は必要な情報を自動的に収集して挿入します。

つまり、以下のような単純なハンドラー関数が、通常どおりに簡単にラップされて登録されます。

以下のサンプルコードは、 HTTP ハンドラを: を使用して計測する instana.TracingHandlerFunc()方法を示しています

sensor := instana.NewSensor("my-http-server")

http.HandleFunc("/", instana.TracingHandlerFunc(sensor, "/", func(w http.ResponseWriter, req *http.Request) {
        // ...
}))
 

ハンドラーが http.Handler として実装されている場合は、代わりにその ServeHTTP メソッドを渡します。

h := http.FileServer(http.Dir("./"))
http.HandleFunc("/files", instana.TracingHandlerFunc(sensor, "index", h.ServeHTTP))
 

完全な例については example/http-database-greeter 、 をご覧ください。

HTTP クライアントをインスツルメントする方法

一般に、他のシステム (通常は外部システム) にデータや情報を要求する場合は、HTTP 要求が使用されます。 トレースにすべてのスパン、特にさまざまなシステムにわたるスパンが含まれるようにするには、一定のスパン情報を HTTP 要求ヘッダーに挿入してから送信する必要があります。 Instana の Go Collector は、このプロセスを可能な限り自動化するためのサポートを提供します。

Instana にリクエストヘッダーへの情報書き込みを行わせるには、を作成し http.Client、その Transport をでラップして、以下の例 instana.RoundTripper() のように使用します。

req, err := http.NewRequest("GET", url, nil)
client := &http.Client{
        Transport: instana.RoundTripper(sensor, nil),
}

ctx := instana.ContextWithSpan(context.Background(), parentSpan)
resp, err := client.Do(req.WithContext(ctx))
 

`provided` parentSpan は、リクエストハンドラーからの着信リクエスト(前の例を参照)であり、子スパンを作成してリクエストに挿入するために必要なトレース情報とスパン情報を提供します。

データベース・クライアント

Go コレクタは、`.` を使用して行われるSQL database/sqlデータベース呼び出しを監視するために、`and` instana.WrapSQLConnector() および `(`( Go 以降、 v1.10+instana.InstrumentSQLDriver() ))を提供します。 これによりトレーサーは、Query 呼び出しと Exec 呼び出しを自動的にキャプチャーし、照会に関する情報 (ステートメントや実行時間など) を収集し、転送して、トレースの一部として表示されるようにします。

MongoDB,のようなnoSQLデータベースクライアントをインストゥルメントするには、ドライバに計装モジュールが提供されているかどうかを確認してください。

sql.Open() で作成されたデータベース接続をインスツルメントする方法

データベース・ドライバーをインスツルメントするには、まず instana.InstrumentSQLDriver() を使用して登録し、 sql.Open() の呼び出しを instana.SQLOpen()に置き換えます。 以下の例では、github.com/lib/pq PostgreSQL ドライバーに対してこの作業を行う方法を示します。

// Create a new instana.Sensor instance
sensor := instana.NewSensor("my-database-app")

// Instrument the driver
instana.InstrumentSQLDriver(sensor, "postgres", &pq.Driver{})

// Create an instance of *sql.DB to use for database queries
db, err := instana.SQLOpen("postgres", "postgres://...")
 

計測対象のドライバーは、 <original_name>_with_instanaという名前で登録されます。例えば、前の例の場合、その名前はとなります postgres_with_instana

完全な例については example/http-database-greeter 、 をご覧ください。

sql.OpenDB() で作成されたデータベース・クライアントをインスツルメントする方法

Go 以降、 v1.10 は、グローバルなドライバーレジストリ database/sql を使用する必要のない、新しい *sql.DB 初期化方法を提供します。 データベース・ドライバー・ライブラリーが database/sql/driver.Connector インターフェースに適合したタイプを提供していれば、それを使用してデータベース接続を作成できます。

driver.Connector インスタンスをインスツルメントするには、 instana.WrapSQLConnector()を使用してラップします。 以下の例では、github.com/go-sql-driver/mysql/ MySQL ドライバーに対してこの作業を実行する方法を示します。

// Create a new instana.Sensor instance
sensor := instana.NewSensor("my-database-app")

// Initialize a new connector
connector, err := mysql.NewConnector(cfg)
// ...

// Wrap the connector before passing it to sql.OpenDB()
db, err := sql.OpenDB(instana.WrapSQLConnector(sensor, "mysql://...", connector))
 

Redis クライアントに計測機能を組み込む方法は?

  1. この github.com/instana/go-sensor/instrumentation/instaredis モジュールは、 redis クライアントにフックを追加することで、 redis.Clientredis.ClusterClient その楽器のインスタンスや go-redis インスタンス用の関数ラッパーを提供します。

    詳しい例や使用方法については、パッケージのドキュメントを参照してください。

  2. この github.com/instana/go-sensor/instrumentation/instaredigo モジュールは、そのインストゥルメント redigo のインスタンスに対する redis.Connラッパーを提供します。

    詳しい例や使用方法については、パッケージのドキュメントを参照してください。

gRPC サービス

この github.com/instana/go-sensor/instrumentation/instagrpc モジュールは、 gRPC を使用するサーバーおよびクライアントを監視するために、単項 google.golang.org/grpc インターセプターとストリームインターセプターの両方を提供します。

gRPC サーバーをインスツルメントする方法

この github.com/instana/go-sensor/instrumentation/instagrpc モジュールは、ストリームおよび単項呼び出しのインターセプタの両方を提供します。 このモジュールのドキュメントには、 gRPC サーバー(で実装されたもの)に監視機能を組み込む google.golang.org/grpc ための使用方法について、詳しく説明されています。

完全な例については example/grpc-client-server 、 をご覧ください。

gRPC クライアントをインスツルメントする方法

この github.com/instana/go-sensor/instrumentation/instagrpc モジュールは、ストリームおよび単項呼び出しのインターセプタの両方を提供します。 このモジュールのドキュメントには、 gRPC クライアントを実装する際に、これらを使用して計測を行う方法 google.golang.org/grpc について詳しく説明されています。

完全な例については example/grpc-client-server 、 をご覧ください。

メッセージング・サービス

Kafka のプロデューサー/コンシューマーをどのように実装すればよいですか?

この github.com/instana/go-sensor/instrumentation/instasarama モジュールは、プロデューサー/コンシューマークライアントの新しいインスタンスを作成し、 Instana を組み込むためのコンストラクタメソッドを提供します。

完全な例については example/kafka-producer-consumer 、 をご覧ください。

RabbitMQ のプロデューサー/コンシューマーをどのように実装すればよいですか?

この github.com/instana/go-sensor/instrumentation/instaamqp モジュールは、インスタンス instaamqp.AmqpChannel を返す関 amqp.Channel 数のラッパーを提供します。 この Instana オブジェクトは、送受信されたメッセージからのデータのトレースを担当するamqp.Channel.Publishメソッドおよびamqp.Channel.Consumeメソッドのインスツルメンテーションを提供します。

完全な例はこちらをご覧ください github.com/instana/go-sensor/blob/main/instrumentation/instaamqp

サービスの名前を変更する

Instana でコールのサービス名を変更するには、次の例のように、その span 要素に タグ service を追加します

span.SetTag("service", "name")
 

OpenTracing API を使用した手動でのインスツルメンテーション

Instana Go Collectorは、 github.com/opentracing/opentracing-go と互換性のあるインターフェースを提供しており、そのためグローバルトレーサーとして使用できます。 ただし、提供されている Instana コード・ラッパーを使用することをお勧めします。 彼らは多くのセマンティック情報を設定しており、これにより Instana はアプリケーションを可能な限り正確に把握できるようになります。 適切なタグを送信することは、呼び出しをインフラストラクチャーに相関させる場合に特に重要です。 これは、ほとんどのタグがストリングであるため、ミスをする可能性があるためです。

メソッドをインスツルメントする方法

Go コレクターでのメソッドの最小限のインスツルメンテーションは、以下の 2 つのステップで構成されます。

  1. で新しいスパンを開始 instana.Sensor します。
  2. メソッドが返される前にスパンをファイナライズします。

オプションのステップには、アクティブ・スパンに付加するためのこの呼び出しに関連する詳細の収集、および トレースの継続を確保するための context.Context へのアクティブ・スパンの注入が含まれます。

func MyMethod(sensor *instana.Sensor) {
    // Start a new span associated with this method execution
    span := sensor.Tracer().StartSpan("my-method")
    // Schedule span finalization to send it to Instana agent
    defer span.Finish()

    // Optionally attach any relevant information that would help you to identify this call later
    span.SetTag("key1", "value1")
    span.SetTag("answer", 42)

    // ...
}
 

より詳しい例については、 example/opentracing こちらをご覧ください。

サブ呼び出しの内部でトレースを続行する方法

サブコールをアクティブ・スパンに関連付けるには、サブコール・スパンの開始時に、 opentracing.ChildOf() 開始スパン・オプションを使用してそのコンテキストを指定します。

var spanOpts []opentracing.StartSpanOption

// Check whether there is an active trace by fetching the currently active span from context
if parent, ok := instana.SpanFromContext(ctx); ok {
    spanOpts = append(spanOpts, opentracing.ChildOf(parent.Context()))
}

// Start the subcall span
span := tracer.StartSpan("my-func", spanOpts...)
 

呼び出し元は、呼び出し先に渡される context.Context インスタンスに、が注入されたアクティブなスパンが含まれている instana.ContextWithSpan() ことを確認する責任があります:

// And inject it into context, so any subcalls could use it as a parent
SubCall(instana.ContextWithSpan(ctx, span))
 

ラップされたメソッドの内部で親スパンを取得する方法

Instana によって提供されるコード・ラッパーは、 context.Context を使用して、親スパンをサブコールに注入します。 つまり、計測対象のハンドラ/コールバック関数内では、 がラッパーメソッドによって開始されたスパンを返す instana.SpanFromContext() ものと見なすことができます:

parentSpan, ok := instana.SpanFromContext(ctx)
 
注: サード・パーティーが context.Context をハンドラー・メソッドに渡す処理に対応していない場合は、ラッパー・コードが別の方法でアクティブ・スパンのコンテキストを挿入する可能性があります。 この場合に親スパン・コンテキストを取得する方法については、それぞれのラッパー・モジュールの資料を参照してください。