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控制台的 页面查看该应用的监控数据。
相关文档
该文章对您有帮助吗?