一般作業

配置

一般

如何起始設定 Go 收集器?

若要在 main() 函數的開頭起始設定 Go 收集器呼叫 instana.InitSensor() ,請提供 *instana.Options 配置物件:

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

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

    // ...
}

針對提供給 instana.InitSensor() 函數之配置物件的未起始設定欄位, Go 收集器將使用 instana.DefaultOptions() 的值。

附註: 這會讓您的 Go 服務出現在 Instana 使用者介面中,並報告其執行時期度量值。 若要查看追蹤資訊,您需要 先檢測應用程式碼

如何將 Go 收集器併入就緒探測?

若要確保 Go 收集器已完成公告處理程序,並已準備好在將資料流量傳送至實例之前收集追蹤資料,請使用 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 收集器會在完成處理程式之後自動呼叫該服務,因此不需要手動執行此動作。

附註: instana.Flush() 可能會干擾 Go 收集器的資料傳輸週期,因此不建議使用它來影響服務生命期限內的追蹤資料遞送,例如在完成處理 HTTP 要求時。 在呼叫此方法之後,不保證 Go 收集器會保持運作

如何將 Go 收集器配置為在無伺服器環境中執行?

若要使用 Go 收集器來監視在無伺服器環境 (例如 AWS Fargate 或 Google Cloud Run) 中執行的服務,請確定您在作業定義中已設定 INSTANA_ENDPOINT_URLINSTANA_AGENT_KEY 環境變數。 如需如何執行此動作的詳細說明,請參閱 Instana 文件的個別小節:

附註: 當應用程式以無伺服器模式執行時,將忽略 INSTANA_AGENT_HOSTINSTANA_AGENT_PORT 環境變數。

在無伺服器環境中執行的服務不會使用主機代理程式將度量值及追蹤資料傳送至 Instana 後端,因此透過 configuration.yaml 檔案配置應用程式內收集器的一般方式不適用。 相反地,在服務作業定義中可以選擇性地配置一組環境變數:

環境變數 預設值 說明
INSTANA_TIMEOUT 500 Instana 後端連線逾時值 (毫秒)
INSTANA_SECRETS contains-ignore-case:secret,key,password 密鑰過濾器 (也會套用至程序環境變數)
INSTANA_EXTRA_HTTP_HEADERS 要從送入要求收集的 HTTP 標頭清單 (以分號區隔)
INSTANA_ENDPOINT_PROXY 用來連接 Instana 後端的 Proxy URL
INSTANA_TAGS 以逗點區隔的標籤清單,具有要與 ECS 作業相關聯的選用值
INSTANA_ZONE <Current AWS availability zone> 此服務的自訂 Instana 區域名稱

如需這些變數及其值格式的更詳細說明,請參閱 Instana 文件

如何配置 Go 收集器以編寫機密資料?

Instana 提供的某些檢測封套 (例如 HTTP 伺服器和用戶端封套) 會收集可能包含機密性資訊 (例如密碼、金鑰和密碼) 的資料。 為了避免洩漏這些值,在傳送至代理程式之前,「Go 收集器」會將它們取代為 <redacted> 。 參數名稱配對器清單定義在 主機代理程式配置檔com.instana.secrets 區段中,並將在公告階段期間傳送至應用程式內追蹤程式 (需要代理程式 Go 追蹤外掛程式 com.instana.sensor-golang-trace v1.3.0 及更高版本)。

密鑰比對器的預設值是 contains-ignore-case ,具有下列術語清單: keypasswordsecret。 這會編寫名稱為 包含 下列任何字串且不區分大小寫的參數值。

如何收集額外的 HTTP 標頭?

HTTP 檢測封套可以收集 HTTP 標頭,並將它們與送入或送出要求跨距一起傳送。 在傳遞至 instana.InitSensor() 的 options 物件的 (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

如何使用 3rd-party 日誌程式來印出 Go 收集器日誌?

您可以將 Go 收集器配置為使用符合 instana.LeveledLogger 介面的協力廠商日誌程式。 例如,若為 github.com/sirupsen/logrusgo.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)
}

附註: 使用 3rd-party 日誌程式時, INSTANA_DEBUG 環境變數沒有作用。 請參閱 3rd-party 日誌程式模組的文件,以瞭解如何透過環境變數或配置檔來設定除錯層次。

如何在不變更應用程式碼的情況下啟用 Go 收集器的除錯日誌?

若要啟用 Go 收集器寫入除錯日誌而不變更應用程式碼,請將 INSTANA_DEBUG 環境變數設為非空值,例如:

export INSTANA_DEBUG=true
./your-app

Go Collector 產生的除錯日誌數量視您的應用程式而定,可能很重要。 建議您先暫時開啟除錯日誌以收集資訊,然後再向 Instana 支援中心報告問題。

附註: 只有在 Go 收集器使用 logger.Logger 來輸出內部日誌訊息,並置換從應用程式碼內變更記載層次的任何嘗試時,此設定才會運作。

如何收集與錯誤呼叫相關聯的已記載錯誤和警告?

Instana Go 收集器為 github.com/sirupsen/logrus 提供檢測封套,以自動收集錯誤及警告日誌記錄並將其傳送至代理程式。 github.com/instana/go-sensor/instrumentation/instalogrus 提供 logrus.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 報告程序設定檔。 與開發時間及隨需應變側寫程式不同,使用者必須手動起始側寫,它會自動排程並持續執行適用於重要正式作業環境的側寫。

如何從應用程式碼內永久啟用連續側寫?

若要永久啟用服務的連續側寫,請在起始設定感應器時提供 EnableAutoProfile: true :

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

	// ...
}

如何從應用程式碼內暫時啟用/停用連續側寫?

若要從您的程式碼暫時開啟及關閉 AutoProfile™ ,請呼叫 autoprofile.Enable()autoprofile.Disable():

func expensiveCalculation() {
    autoprofile.Enable()
    defer autoprofile.Disable()

    // ...
}

如何啟用連續側寫而不變更應用程式碼?

若要針對應用程式啟用 AutoProfile™ 而不變更程式碼,請設定 INSTANA_AUTO_PROFILE=true 環境變數:

export INSTANA_AUTO_PROFILE=true
./your-app

附註: 與使用 INSTANA_DEBUG 啟用除錯記載類似,此值會優先處理,並置換從應用程式碼內部停用側寫的任何嘗試。

設備測試

您的應用程式碼需要修改,才能收集追蹤資料並將其傳送至 Instana。 此處理程序稱為程式碼檢測。

Go Collector 提供兩個用來檢測程式碼的選項:

  1. 使用提供的程式碼封套。 這是檢測程式碼最簡單的方法,只需要很少的變更。 Instana 旨在為最熱門的 3rd-party 程式庫 (例如資料庫驅動程式、HTTP 架構等) 提供檢測模組。 如果您使用的程式庫還沒有對應的檢測模組,請考量使用 Instana Idea 提交來存檔特性要求。
  2. 使用 OpenTracing API。 更低階的方法,可能需要對程式碼庫進行大量變更。 不過,在檢測您的商業特定程式碼組件時,它也提供很大的彈性。

請注意, Instana 使用一組非常特定的 span 標籤,以確保正確的基礎架構相關性和呼叫的表示法。 偏好使用提供的程式碼封套而非 OpenTracing API 方法,以充分利用您的追蹤資料。 必要時,您可以考慮將程式碼封套與低階方法混合,以利用已存在且已維護的程式碼,同時保持彈性來檢測您的商業特定程式碼組件。

HTTP 服務

Go Collector 為使用 net/http 套件的用戶端及伺服器提供檢測。 一旦啟動 (請參閱如下所示) ,此檢測即會自動收集送入及送出要求的相關資訊,並將其傳送至 Instana 代理程式。

3rd-party HTTP 架構的檢測模組 提供作為個別 Go 模組,並提供更方便的方法來檢測 HTTP 服務。

如何檢測 HTTP 伺服器處理程式?

藉由支援包裝 http.HandlerFunc, Instana 可快速新增追蹤要求的可能性,並收集在要求跨距的環境定義中執行的子跨距。

Instana 需要最少的變更,才能擷取必要的資訊。 只要包裝目前現有的 http.HandlerFunc Instana 即可自動收集並注入必要的資訊。

雖然如此,類似下列的簡式處理程式函數將會像正常一樣簡單包裝及登錄。

下列程式碼範例示範如何使用 instana.TracingHandlerFunc()來檢測 HTTP 處理程式:

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 收集器支援盡可能將此處理程序自動化。

如果要讓 Instana 注入資訊到要求標頭中,請建立 http.Client,使用 instana.RoundTripper() 來包裝其 Transport ,並使用它,如下列範例所示。

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))

提供的 parentSpan 是來自要求處理程式的送入要求 (請參閱上文) ,並提供必要的追蹤和跨距資訊,以建立子項跨距並將它注入要求中。

資料庫用戶端

Go Collector 提供 instana.InstrumentSQLDriver()instana.WrapSQLConnector() (從 Go v1.10+版開始) 來檢測使用 database/sql進行的 SQL 資料庫呼叫。 然後,追蹤程式會自動擷取 QueryExec 呼叫,收集查詢的相關資訊 (例如陳述式、執行時間等) ,並將它們轉遞以顯示為追蹤的一部分。

若要檢測 noSQL 資料庫用戶端 (例如 MongoDB) ,請檢查是否有為您的驅動程式提供 檢測模組

如何檢測以 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))

如何檢測 MongoDB 用戶端?

github.com/instana/go-sensor/instrumentation/instamongo 模組提供建構子方法,可建立 go.mongodb.org/mongo-driver 用戶端的新實例,並使用 Instana 來檢測它。

如需詳細範例和用法指示,請參閱 套件說明文件

如何檢測 Redis 用戶端?

  1. github.com/instana/go-sensor/instrumentation/instaredis 模組提供 go-redis 的函數封套,透過將連結鉤新增至 redis 用戶端來檢測 redis.Clientredis.ClusterClient 的實例。

    如需詳細範例和用法指示,請參閱 套件說明文件

  2. github.com/instana/go-sensor/instrumentation/instaredigo 模組提供 redigo 的封套,用來檢測 redis.Conn的實例。

    如需詳細範例和用法指示,請參閱 套件說明文件

gRPC 服務

github.com/instana/go-sensor/instrumentation/instagrpc 模組提供單元和串流攔截程式來檢測使用 google.golang.org/grpc的 gRPC 伺服器和用戶端。

如何檢測 gRPC 伺服器?

github.com/instana/go-sensor/instrumentation/instagrpc 模組同時提供 串流單元 呼叫攔截程式。 模組文件 提供如何使用它們來檢測使用 google.golang.org/grpc實作的 gRPC 伺服器的詳細說明。

如需完整範例,請參閱 example/grpc-client-server

如何檢測 gRPC 用戶端?

github.com/instana/go-sensor/instrumentation/instagrpc 模組同時提供 串流單元 呼叫攔截程式。 模組文件 提供如何使用它們來檢測使用 google.golang.org/grpc實作的 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 模組提供 amqp.Channel 的函數封套,以傳回 instaamqp.AmqpChannel 實例。 這個 Instana 物件提供 amqp.Channel.Publishamqp.Channel.Consume 方法的檢測,這些方法負責從傳送和接收的訊息追蹤資料。

請參閱 github.com/instana/go-sensor/blob/main/instrumentation/instaamqp中的完整範例。

使用 OpenTracing API 的手動檢測

Instana Go 收集器提供與 github.com/opentracing/opentracing-go相容的介面,因此可以用作廣域追蹤程式。 不過,建議的方法是使用所提供的 Instana 程式碼封套。 他們會設定許多語意資訊,以協助 Instana 儘可能取得應用程式的最佳圖景。 當您將呼叫與基礎架構產生關聯時,傳送適當的標籤特別重要。 這是因為大部分標籤都是字串,因此您可能會犯錯。

如何檢測方法?

使用 Go Collector 之方法的最小檢測包含兩個步驟:

  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)

附註: 如果 3rd-party 不支援將 context.Context 傳遞至處理程式方法,封套程式碼可能會使用注入作用中文字段環境定義的替代方法。 請參閱個別封套模組的文件,以瞭解在此情況下如何取得母項跨距環境定義。