The Application Real-Time Monitoring (ARMS) agent for Go provides custom extensions. You can add custom features without changing the code, facilitating error location based on request parameters and the request body. This topic explains how to use custom extensions of the ARMS agent for Go to create an OpenTelemetry span.
Prerequisites
The application is running on Go V1.18 or later.
Your Go application is monitored by ARMS.
ImportantEnsure that the compilation is changed to
./instgo go build xxxas required by the reference document.You have enabled the opentelemetry-plugin switch.
Procedure
Outside the directory of the current project, create a folder named
hookand run thego mod init hookcommand to initialize it. In thehookfolder, create a file namedhook.gowith the following code, which provides custom extensions: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" ) // The first argument of the hook function must be api.CallContext followed by parameters matching the target function. 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() } // The first argument of the hook function must be api.CallContext followed by parameters matching 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()Develop a test demo.
In a separate directory from the
hookfolder, create a demo application folder and run thego mod init democommand to initialize it. In thedemofolder, create a file namedmain.gowith the following code:
If the project already relies on OpenTelemetry, you do not need to add _ "go.opentelemetry.io/otel" in the main.go file.
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
_ "go.opentelemetry.io/otel"
)
func main() {
// 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)
// Close the response body before the function returns.
defer resp.Body.Close()
}
Use the following code to create a
conf.jsonconfiguration file in thedemofolder:[{ "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 }]The code instructs the ARMS agent for Go to inject the custom code
hookinto thedatabase/sql::(*DB).Query()function.Go to the
demodirectory and use instgo to compile and run the program to verify the protection against SQL injection.$ ./instgo set --rule=./conf.json $ ./instgo go buildStart the demo program locally by specifying environment variables:
Specify environment variables:
export ARMS_ENABLE=true export ARMS_APP_NAME=xxx # The application name. export ARMS_REGION_ID=xxx # The region ID of your Alibaba Cloud account. export ARMS_LICENSE_KEY=xxx # The license key you retrieved in step 1.Start the demo program:
./demo
NoteAlternatively, deploy the program in a containerized environment.
Log on to ARMS console. In the left-side navigation pane, choose and view the monitoring data of the application.