The Golang probe offers custom extension capabilities, enabling you to inject custom features without altering the original code, which aids in issue identification through request parameters and body. This topic explains how to utilize the Golang probe's custom extension capabilities to create an OpenTelemetry span.
Prerequisites
Ensure the current application's Golang version is 1.18 or higher.
Connect the Golang application to ARMS.
ImportantEnsure the compile statement is modified to
./instgo go build xxx
as per the access document.
Procedure
Create a hook folder outside the current project's folder. Initialize the folder using the
go mod init hook
command and then create a hook.go file in the hook folder with the following code:Below is the custom extension feature to be injected:
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" ) // Note: The first parameter of the injected code must be api.CallContext, subsequent parameters must match the target function's parameters 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() } // Note: The first parameter of the injected code must be api.CallContext, subsequent parameters must match the target function's return values func httpClientExitHook(call api.CallContext, res *http.Response, err error) { header, _ := json.Marshal(res.Header) fmt.Println("response header is ", string(header)) }
The code segment responsible for creating the span is:
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()
Write a test demo.
Create a folder for the demo application in a separate directory from the hook folder. Initialize it with the
go mod init demo
command and then create a main.go file in the demo folder with the following code:NoteIf the project already depends on OpenTelemetry, you do not need to add
_ "go.opentelemetry.io/otel"
in main. If not, it is required.package main import ( "context" "fmt" "io/ioutil" "log" "net/http" _ "go.opentelemetry.io/otel" ) func main() { // Define the request URL req, _ := http.NewRequestWithContext(context.Background(), "GET", "http://www.aliyun.com", nil) req.Header.Set("otelbuild", "true") client := &http.Client{} resp, _ := client.Do(req) // Ensure the response body is closed when the function ends defer resp.Body.Close() }
Create a conf.json configuration file in the demo folder with the following code:
The code below instructs the Golang probe to inject the custom hook code into the
database/sql::(*DB).Query()
function.[{ "ImportPath":"net/http", "Function":"RoundTrip", "OnEnter":"httpClientEnterHook", "ReceiverType": "*Transport", "OnExit": "httpClientExitHook", "Path": "/path/to/hook" # Modify Path to the local path of the hook code }]
Navigate to the demo directory. Compile and execute the program using the instgo tool to verify SQL injection protection effectiveness.
$ ./instgo set --rule=./conf.json $ ./instgo go build
Launch the demo program.
You can start it locally by directly declaring environment variables, or opt to deploy the demo program in a containerized environment.
Declare the environment variables:
export ARMS_ENABLE=true export ARMS_APP_NAME=xxx # Application name. export ARMS_REGION_ID=xxx # RegionID of the corresponding Alibaba Cloud account. export ARMS_LICENSE_KEY=xxx # LicenseKey obtained in step one.
Start the demo program:
./demo
Monitor the application's data on the or the ARMS console on the page.