使用自定义扩展创建OpenTelemetry Span

更新时间:2025-03-06 09:07

Golang探针提供自定义扩展能力,您可以在不修改原有代码的基础上注入自定义功能,从而实现通过请求参数、Body来定位问题。本文介绍如何使用Golang探针的自定义扩展能力创建OpenTelemetry Span。

前提条件

  • 确认当前应用的Golang版本在1.18及以上。

  • 将Golang应用接入到ARMS

    重要

    请确认编译语句已参考接入文档修改为./instgo go build xxx

操作步骤

  1. 在非当前项目的目录下创建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()
  2. 编写测试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()
    }
    
  3. 在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代码的本地路径
    }]
  4. 切换到demo目录,使用instgo工具编译并执行程序,以验证SQL注入保护的效果。

    $ ./instgo set --rule=./conf.json
    $ ./instgo go build 
  5. 启动demo程序。

    本地启动可以直接声明环境变量启动,您也可以选择通过容器化部署demo程序。

    1. 声明环境变量

      export ARMS_ENABLE=true
      export ARMS_APP_NAME=xxx   # 应用名称。
      export ARMS_REGION_ID=xxx   # 对应的阿里云账号的RegionID。
      export ARMS_LICENSE_KEY=xxx   # 步骤一获取到的LicenseKey。
    2. 启动demo程序。

      ./demo
  6. ARMS控制台应用监控 > 应用列表页面查看该应用的监控数据。

相关文档

使用Golang探针的自定义扩展能力

  • 本页导读 (1)
  • 前提条件
  • 操作步骤
  • 相关文档
文档反馈
phone 联系我们

立即和Alibaba Cloud在线服务人员进行交谈,获取您想了解的产品信息以及最新折扣。

alicare alicarealicarealicare