Golang探针提供自定义扩展能力,您可以在不修改原有代码的基础上注入自定义功能,从而实现通过请求参数、Body来定位问题。本文以Net/HTTP为例介绍如何使用Golang探针的自定义扩展能力获取请求头和响应头。
前提条件
确认当前应用的Golang版本在1.18及以上。
- 重要
请确认编译语句已参考接入文档修改为
./instgo go build xxx
。
操作步骤
在非当前项目的目录下创建rules文件夹,并使用
go mod init rules
命令初始化该文件夹,然后在rules文件夹下新建包含以下代码的rules.go文件。以下代码即为需要注入的自定义扩展功能。
package rules import ( "encoding/json" "fmt" "github.com/alibaba/opentelemetry-go-auto-instrumentation/pkg/api" "net/http" ) func httpClientEnterHook(call api.CallContext, t *http.Transport, req *http.Request) { header, _ := json.Marshal(req.Header) fmt.Println("request header is ", string(header)) } func httpClientExitHook(call api.CallContext, res *http.Response, err error) { header, _ := json.Marshal(res.Header) fmt.Println("response header is ", string(header)) }
修改config.json配置文件,添加以下内容将hook代码注入到
net/http::(*Transport).RoundTrip
。[ { "ImportPath":"net/http", "Function":"RoundTrip", "OnEnter":"httpClientEnterHook", "ReceiverType": "*Transport", "OnExit": "httpClientExitHook", "Path": "/extension/rules" //替换为rules文件夹的绝对路径 } ]
编写测试Demo。
在不同于rules文件夹的目录下创建一个demo应用的文件夹,并使用
go mod init demo
命令初始化,然后在demo文件夹下新建包含以下代码的net_http.go文件。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() }
切换到demo目录,使用instgo工具编译并执行程序。
$ ./instgo set --rule=../config.json $ INSTGO_CACHE_DIR=./ ./instgo go build net_http.go 如果是需要在Linux系统运行 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 INSTGO_CACHE_DIR=./ ./instgo go build net_http.go $ 运行./net_http
如果输出以下内容, 表示注入成功,插件已生效。
完整的示例代码请参见nethttp。
说明除了上述介绍的通过扩展方式打印请求和返回的Header外,自定义扩展能力还可以用于SQL注入检测、日志打印、出参和入参打印等。