Golang探針提供自訂擴充能力,您可以在不修改原有代碼的基礎上注入自訂功能,從而實現通過請求參數、Body來定位問題。本文介紹如何使用Golang探針的自訂擴充能力建立OpenTelemetry Span。
前提條件
確認當前應用的Golang版本在1.18及以上。
- 重要
請確認編譯語句已參考接入文檔修改為
./instgo go build xxx。
操作步驟
在非當前專案的目錄下建立hook檔案夾,並使用
go mod init hook命令初始化該檔案夾,然後在hook檔案夾下建立包含以下代碼的hook.go檔案。以下代碼即為需要注入的自訂擴充功能。
package hook import ( "encoding/json" "fmt" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/api" "net/http" ) // 注意:注入代碼第一個參數必須是api.CallContext,後續參數和目標函數參數一致 func httpClientEnterHook(call api.CallContext, t *http.Transport, req *http.Request) { header, _ := json.Marshal(req.Header) fmt.Println("request header is ", string(header)) tracer := otel.GetTracerProvider().Tracer("") _, span := tracer.Start(context.Background(), "Client/User defined span") span.SetAttributes(attribute.String("client", "client-with-ot")) span.SetAttributes(attribute.Bool("user.defined", true)) span.End() } // 注意:注入代碼第一個參數必須是api.CallContext,後續參數和目標函數傳回值一致 func httpClientExitHook(call api.CallContext, res *http.Response, err error) { header, _ := json.Marshal(res.Header) fmt.Println("response header is ", string(header)) }以上代碼中,建立Span的代碼部分為:
tracer := otel.GetTracerProvider().Tracer("") _, span := tracer.Start(context.Background(), "Client/User defined span") span.SetAttributes(attribute.String("client", "client-with-ot")) span.SetAttributes(attribute.Bool("user.defined", true)) span.End()編寫測試Demo。
在不同於hook檔案夾的目錄下建立一個demo應用的檔案夾,並使用
go mod init demo命令初始化,然後在demo檔案夾下建立包含以下代碼的main.go檔案。說明如果專案之前已經依賴OpenTelemetry,在main中就不需要再添加
_ "go.opentelemetry.io/otel",如果沒有則需要添加。package main import ( "context" "fmt" "io/ioutil" "log" "net/http" _ "go.opentelemetry.io/otel" ) func main() { // 定義請求的URL req, _ := http.NewRequestWithContext(context.Background(), "GET", "http://www.aliyun.com", nil) req.Header.Set("otelbuild", "true") client := &http.Client{} resp, _ := client.Do(req) // 確保在函數結束時關閉響應的主體 defer resp.Body.Close() }在demo檔案夾下建立包含以下代碼的conf.json設定檔。
以下代碼用於告訴Golang探針將自訂的hook代碼注入到
database/sql::(*DB).Query()函數中。[{ "ImportPath":"net/http", "Function":"RoundTrip", "OnEnter":"httpClientEnterHook", "ReceiverType": "*Transport", "OnExit": "httpClientExitHook", "Path": "/path/to/hook" # Path修改為hook代碼的本地路徑 }]切換到demo目錄,使用instgo工具編譯並執行程式,以驗證SQL注入保護的效果。
$ ./instgo set --rule=./conf.json $ ./instgo go build啟動demo程式。
本地啟動可以直接聲明環境變數啟動,您也可以選擇通過容器化部署demo程式。
聲明環境變數
export ARMS_ENABLE=true export ARMS_APP_NAME=xxx # 應用程式名稱。 export ARMS_REGION_ID=xxx # 對應的阿里雲帳號的RegionID。 export ARMS_LICENSE_KEY=xxx # 步驟一擷取到的LicenseKey。啟動demo程式。
./demo
在ARMS控制台的頁面查看該應用的監控資料。