All Products
Search
Document Center

Application Real-Time Monitoring Service:Use custom extension to create OpenTelemetry span

Last Updated:Mar 06, 2025

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.

    Important

    Ensure the compile statement is modified to ./instgo go build xxx as per the access document.

Procedure

  1. 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()
  2. 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:

    Note

    If 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()
    }
    
  3. 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
    }]
  4. 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 
  5. 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.

    1. 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.
    2. Start the demo program:

      ./demo
  6. Monitor the application's data on the or the ARMS console on the Application Monitoring > Application List page.

References

Use the custom extension capabilities of the Golang probe