全部产品
Search
文档中心

Application Real-Time Monitoring Service:Gunakan fitur ekstensi kustom agen Golang

更新时间:Nov 30, 2025

Agen Golang menyediakan fitur ekstensi kustom yang memungkinkan Anda menyisipkan fungsi kustom tanpa mengubah kode asli. Fitur ini membantu mengidentifikasi masalah dengan memeriksa parameter dan isi permintaan (request). Topik ini menggunakan Net/HTTP sebagai contoh untuk menunjukkan cara menggunakan fitur ekstensi kustom agen Golang guna mengambil header permintaan dan respons.

Prasyarat

  • Pastikan aplikasi Anda menggunakan Golang 1.18 atau versi yang lebih baru.

  • Anda telah menghubungkan aplikasi Golang Anda ke ARMS.

    Penting

    Pastikan pernyataan kompilasi telah diubah menjadi ./instgo go build xxx sebagaimana dijelaskan dalam dokumen integrasi.

Batasan

  • Fitur ekstensi kustom tidak mendukung instrumentasi untuk fungsi pengguna dalam package main.

  • Fitur ekstensi kustom tidak mendukung instrumentasi untuk fungsi yang ReceiverType-nya adalah `any`.

Spesifikasi

  • Jangan gunakan package main dalam kode hook.

  • Jika Anda menggunakan kode versi 2.0.0 atau yang lebih baru, tambahkan "_ unsafe" ke pernyataan import seperti berikut:

    import (
    	"encoding/json"
    	"fmt"
    	"github.com/alibaba/loongsuite-go-agent/pkg/api"
    	"net/http"
            _ "unsafe"
    )
  • Parameter pertama fungsi OnEnter harus berupa call api.CallContext. Parameter kedua, jika ada, adalah ReceiverType. Parameter selanjutnya merupakan parameter input dari fungsi yang diinstrumentasi.

    Catatan

    Jika ReceiverType mengandung *, Anda harus menambahkan awalan \\ dalam file JSON untuk melakukan escape karakter tersebut.

  • Parameter pertama fungsi OnExit harus berupa call api.CallContext. Parameter selanjutnya merupakan nilai kembali dari fungsi yang diinstrumentasi.

Sebagai contoh, fungsi net/http::(*Transport).RoundTrip adalah sebagai berikut:

func (t *Transport) RoundTrip(req *Request) (*Response, error) {
	return t.roundTrip(req)
}

Receiver type dari RoundTrip adalah *Transport. Oleh karena itu, parameter kedua fungsi OnEnter adalah *Transport dan parameter ketiga adalah req *Request. Parameter kedua dan ketiga fungsi OnExit adalah nilai kembali dari RoundTrip, yaitu *Response, error.

Jika ReceiverType merupakan kelas yang tidak diekspos (dimulai dengan huruf kecil), gunakan _ interface{} sebagai tipenya. Anda juga dapat menggunakan _ interface{} sebagai placeholder untuk parameter apa pun yang ingin Anda abaikan.

Prosedur

  1. Buat folder `rules` di luar direktori proyek Anda saat ini. Inisialisasi folder tersebut dengan menjalankan perintah go mod init rules. Kemudian, buat file `rules.go` di folder `rules` yang berisi kode berikut.

    Kode ini mendefinisikan fungsi ekstensi kustom yang akan disisipkan.

    package rules
    
    import (
    	"encoding/json"
    	"fmt"
    	"github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/api"
    	"net/http"
            _ "unsafe"
    )
    
    //go:linkname httpClientEnterHook1 net/http.httpClientEnterHook1
    func httpClientEnterHook1(call api.CallContext, t *http.Transport, req *http.Request) {
    	header, _ := json.Marshal(req.Header)
    	fmt.Println("request header is ", string(header))
    }
    
    //go:linkname httpClientExitHook1 net/http.httpClientExitHook1
    func httpClientExitHook1(call api.CallContext, res *http.Response, err error) {
    	header, _ := json.Marshal(res.Header)
    	fmt.Println("response header is ", string(header))
    }
  2. Ubah file konfigurasi config.json. Tambahkan konten berikut untuk menyisipkan kode hook ke net/http::(*Transport).RoundTrip.

    [
      {
        "ImportPath":"net/http",
        "Function":"RoundTrip",
        "OnEnter":"httpClientEnterHook1",
        "ReceiverType": "\\*Transport",
        "OnExit": "httpClientExitHook1",
        "Path": "/extension/rules" // Ganti dengan jalur mutlak folder rules
      }
    ]
  3. Buat aplikasi contoh.

    Di direktori di luar folder `rules`, buat folder baru untuk aplikasi sampel. Inisialisasi folder ini dengan menjalankan perintah go mod init demo. Kemudian, buat file `net_http.go` di folder `demo` yang berisi kode berikut.

    package main
    
    import (
    	"context"
    	"net/http"
    )
    
    func main() {
    	req, err := http.NewRequestWithContext(context.Background(), "GET", "http://www.baidu.com", nil)
    	if err != nil {
    		panic(err)
    	}
    	req.Header.Set("otelbuild", "true")
    	client := &http.Client{}
    	resp, err := client.Do(req)
    	defer resp.Body.Close()
    
    }
    
  4. Berpindah ke direktori demo. Gunakan tool instgo untuk mengompilasi dan menjalankan program.

    $ ./instgo set --rule=../config.json
    $ INSTGO_CACHE_DIR=./ ./instgo go build net_http.go
    
    # Untuk menjalankan di Linux
    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 INSTGO_CACHE_DIR=./ ./instgo go build net_http.go
    $ ./net_http

    Jika output berikut ditampilkan, hal ini menunjukkan bahwa penyisipan berhasil dan ekstensi aktif.

    image.png

    Untuk contoh kode lengkap, lihat nethttp.

    Catatan

    Selain mengambil header permintaan dan respons, Anda juga dapat menggunakan fitur ekstensi kustom untuk tujuan lain, seperti deteksi Injeksi SQL, logging kustom, serta pengambilan parameter permintaan dan respons.