通过自定义扩展完成自动染色注入

本文通过net/http来展示如何通过自定义扩展来完成自动染色。

操作步骤

一、创建一个hook文件夹(名称可自定义)

mkdir hook
go mod init hook
说明

此处不需要go mod tidy来同步。

二、编写注入规则文件

httpdemo作为示例,在httpclientRoundTrip注入代码。

image.png

规则如下所示:

[
  {
    "ImportPath":"net/http",
    "Function":"RoundTrip",
    "OnEnter":"httpClientEnter",
    "ReceiverType": "\\*Transport",
    "Path": "/extension/rules" //替换为rules文件夹的绝对路径
  }
]

http 的serverRoundTrip 注入代码

image.png

规则如下所示:

[
  {
    "ImportPath":"net/http",
    "Function": "ServeHTTP",
    "ReceiverType": "serverHandler",
    "OnEnter":"httpServerEnter",
    "Path": "/extension/rules" //替换为rules文件夹的绝对路径
  }
]

三、编写hook代码:

说明
  • hook文件夹下的代码package 不能为main

  • hook.go 文件的 import 中添加_ "unsafe"

示例Client端代码如下所示

package rules

import (
    "context"
    "github.com/alibaba/loongsuite-go-agent/pkg/go-sdk/otel/baggage"
    "github.com/alibaba/loongsuite-go-agent/pkg/api"
    "net/http"
    _ "unsafe"
)

//go:linkname httpClientEnter net/http.httpClientEnter
func httpClientEnter(call api.CallContext, t *http.Transport, req *http.Request) {
    mem, _ := baggage.NewMember("abc2", "abc2")
    b, _ := baggage.New(mem)
    ctx := baggage.ContextWithBaggage(context.Background(), b)
    req = req.WithContext(ctx)
    call.SetParam(1, req)
}

Server端代码如下所示

package rules

import (
    "context"
    "github.com/alibaba/loongsuite-go-agent/pkg/go-sdk/otel/baggage"
    "github.com/alibaba/loongsuite-go-agent/pkg/api"
    "net/http"
    _ "unsafe"
)

//go:linkname httpServerEnter net/http.httpServerEnter
func httpServerEnter(call api.CallContext, _ interface{}, w http.ResponseWriter, r *http.Request) {
    b := baggage.FromContext(context.Background())
    mem := b.Member("abc2")
    fmt.Printf("%v\n", mem.Value())
}

相关文档

Go自定义扩展编写规范和字段说明