全部產品
Search
文件中心

Cloud Monitor:使用Golang自訂擴充建立OpenTelemetry Span

更新時間:Sep 05, 2025

Golang探針提供自訂擴充能力,您可以在不修改原有代碼的基礎上注入自訂功能,從而實現通過請求參數、Body來定位問題。本文介紹如何使用Golang探針的自訂擴充能力建立OpenTelemetry Span。

前提條件

操作步驟

  1. 在非當前專案的目錄下建立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()
  2. 編寫測試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()
    }
    
  3. 在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代碼的本地路徑
    }]
  4. 切換到demo目錄,使用instgo工具編譯並執行程式,以驗證SQL注入保護的效果。

    $ ./instgo set --rule=./conf.json
    $ ./instgo go build 
  5. 啟動demo程式。

    本地啟動可以直接聲明環境變數啟動,您也可以選擇通過容器化部署demo程式。

    1. 聲明環境變數

      export ARMS_ENABLE=true
      export ARMS_APP_NAME=xxx   # 應用程式名稱。
      export ARMS_REGION_ID=xxx   # 對應的阿里雲帳號的RegionID。
      export ARMS_LICENSE_KEY=xxx   # 步驟一擷取到的LicenseKey。
    2. 啟動demo程式。

      ./demo
  6. ARMS控制台應用監控 > 應用列表頁面查看該應用的監控資料。

相關文檔

使用Golang探針的自訂擴充能力