Kaynağa Gözat

Fixed #TASK_QT-9810 对接apm白名单

Carl 1 yıl önce
ebeveyn
işleme
86d9112f27

+ 15 - 0
common/app_info.go

@@ -0,0 +1,15 @@
+package common
+
+const (
+	APP_NAME    = "app_name"
+	APP_ID      = "app_id"
+	AGENT_ID    = "agent_id"
+	INSTANCE_ID = "instance_id"
+)
+
+type AppInfo struct {
+	AppName    string `json:"app_name"`
+	AppId      int64  `json:"app_id"`
+	AgentId    int64  `json:"agent_id"`
+	InstanceId int64  `json:"instance_id"`
+}

+ 37 - 0
common/code_type.go

@@ -98,6 +98,43 @@ func (p CodeType) Topic() string {
 	}
 }
 
+func (p CodeType) WhiteCodeString() string {
+	switch p {
+	case CodeTypeGo:
+		return "go"
+	case CodeTypeJava:
+		return "java"
+	//case CodeTypeJavaAot:
+	//	return "JAVA_AOT"
+	case CodeTypePHP:
+		return "php"
+	case CodeTypePython:
+		return "python"
+	//case CodeTypeDotNet:
+	//	return "DOTNET"
+	case CodeTypeNode:
+		return "node"
+	case CodeTypeC:
+		return "c"
+	case CodeTypeNetCore:
+		return "dc"
+	//case CodeTypeNetCoreAot:
+	//	return "NETCORE_AOT"
+	//case CodeTypeLua:
+	//	return "LUA"
+	//case CodeTypeJavaC:
+	//	return "JAVA_C"
+	//case CodeTypeRuby:
+	//	return "RUBY"
+	//case CodeTypeWaitCheck:
+	//	return "WAIT_CHECK"
+	//case CodeTypeUnknown:
+	//	return "UNKNOWN:Language"
+	default:
+		return ""
+	}
+}
+
 func (p CodeType) Int() int {
 	return int(p)
 }

+ 80 - 31
containers/container.go

@@ -2,6 +2,8 @@ package containers
 
 import (
 	debugelf "debug/elf"
+	"fmt"
+	. "github.com/coroot/coroot-node-agent/utils/modelse"
 	"os"
 	"strconv"
 	"strings"
@@ -148,11 +150,17 @@ type Container struct {
 
 	done chan struct{}
 
-	traceMap   map[uint64]*tracing.Trace
-	instanceID utils.ID
-	Symbols    []debugelf.Symbol
-	Uprobes    []tracer.Uprobe
-	UprobesMap map[string]tracer.Uprobe
+	traceMap     map[uint64]*tracing.Trace
+	instanceID   utils.ID
+	Symbols      []debugelf.Symbol
+	Uprobes      []tracer.Uprobe
+	UprobesMap   map[string]tracer.Uprobe
+	l7EventReady bool
+	l7Attach     bool
+	// 白名单详情
+	WhiteSettingInfo WhiteSettingInfo
+	// 应用详情
+	AppInfo common.AppInfo
 }
 
 func NewContainer(id ContainerID, cg *cgroup.Cgroup, md *ContainerMetadata, hostConntrack *Conntrack, pid uint32) (*Container, error) {
@@ -1073,7 +1081,7 @@ func (c *Container) revalidateListens(now time.Time, actualListens map[netaddr.I
 			if !found {
 				continue
 			}
-			klog.Warningln("missing listen found:", addr, pid)
+			//klog.Warningln("missing listen found:", addr, pid)
 			c.onListenOpen(pid, addr, true)
 		}
 	}
@@ -1090,24 +1098,33 @@ func (c *Container) revalidateListens(now time.Time, actualListens map[netaddr.I
 	}
 }
 
-func (c *Container) attachUprobes(tracer *ebpftracer.Tracer, pid uint32) {
+func (c *Container) attachUprobes(tracer *ebpftracer.Tracer, pid uint32) error {
+	fmt.Println("=============attachUprobes")
 	if tracer.DisableL7Tracing() {
-		return
+		return nil
 	}
 	codeType := c.GetCodeTypeFromCache(pid)
 	if codeType.IsUnknownCode() {
-		return
+		return nil
 	}
+	var err error
 	switch codeType {
 	case common.CodeTypeJava:
-		c.attachJVMUprobes(tracer, pid)
+		err = c.attachJVMUprobes(tracer, pid)
 	case common.CodeTypeJavaAot:
-		c.attachJVMUprobes(tracer, pid)
+		err = c.attachJVMUprobes(tracer, pid)
 	case common.CodeTypeGo:
-		c.attachTlsUprobes(tracer, pid)
+		err = c.attachTlsUprobes(tracer, pid)
 	case common.CodeTypeNetCoreAot:
-		c.attachNetCoreUprobes(tracer, pid)
+		err = c.attachNetCoreUprobes(tracer, pid)
+	}
+	if err != nil {
+		fmt.Println(err)
+		c.errorClose(pid)
+		return err
 	}
+	c.l7AttachSuccess()
+	return nil
 }
 
 func (c *Container) GetCodeTypeFromCache(pid uint32) common.CodeType {
@@ -1121,73 +1138,105 @@ func (c *Container) GetCodeTypeFromCache(pid uint32) common.CodeType {
 	return p.codeType
 }
 
-func (c *Container) attachTlsUprobes(tracer *ebpftracer.Tracer, pid uint32) {
+func (c *Container) attachTlsUprobes(tracer *ebpftracer.Tracer, pid uint32) error {
 	p := c.processes[pid]
 	if p == nil {
-		return
+		return nil
 	}
 	if !p.openSslUprobesChecked {
-		p.uprobes = append(p.uprobes, tracer.AttachOpenSslUprobes(pid)...)
+		sslProbes, err := tracer.AttachOpenSslUprobes(pid)
+		if err != nil {
+			return err
+		}
+		p.uprobes = append(p.uprobes, sslProbes...)
 		p.openSslUprobesChecked = true
 	}
 	if !p.goTlsUprobesChecked {
 		codeType := c.GetCodeTypeFromCache(pid)
-		p.uprobes = append(p.uprobes, tracer.AttachGoTlsUprobes(pid, c.instanceID, uint16(codeType))...)
+		goProbes, err := tracer.AttachGoTlsUprobes(pid, c.instanceID, uint16(codeType))
+		if err != nil {
+			return err
+		}
+		p.uprobes = append(p.uprobes, goProbes...)
 		p.goTlsUprobesChecked = true
 	}
+	return nil
 }
 
-func (c *Container) attachJVMUprobes(tracer *ebpftracer.Tracer, pid uint32) {
+func (c *Container) attachJVMUprobes(tracer *ebpftracer.Tracer, pid uint32) error {
 	ENV_PID := os.Getenv("FILTER_PID")
 	if ENV_PID != "" {
 		filterPid, _ := strconv.ParseInt(ENV_PID, 10, 64)
 		if filterPid != int64(pid) {
-			return
+			return nil
 		}
 	}
 	p := c.processes[pid]
 	if p == nil {
-		return
+		return nil
 	}
 	if !p.jvmUprobesChecked {
 		codeType := c.GetCodeTypeFromCache(pid)
 		tracer.InitKProcInfo(pid, c.instanceID, uint16(codeType))
 
 		libNioProbes, err := tracer.AttachJavaNioReadUprobes(pid, codeType)
-		if err == nil {
-			p.uprobes = append(p.uprobes, libNioProbes...)
-		} else {
+		if err != nil {
 			klog.Error(err)
+			return err
 		}
+		p.uprobes = append(p.uprobes, libNioProbes...)
+
 		libNetProbes, err := tracer.AttachJavaNetWriteUprobes(pid)
-		if err == nil {
-			p.uprobes = append(p.uprobes, libNetProbes...)
-		} else {
+		if err != nil {
 			klog.Error(err)
+			return err
 		}
+		p.uprobes = append(p.uprobes, libNetProbes...)
 		p.jvmUprobesChecked = true
 	}
+	return nil
 }
 
-func (c *Container) attachNetCoreUprobes(tracer *ebpftracer.Tracer, pid uint32) {
+func (c *Container) errorClose(pid uint32) {
+	p := c.processes[pid]
+	if p != nil {
+		p.DynamicClose()
+	}
+}
+
+func (c *Container) attachNetCoreUprobes(tracer *ebpftracer.Tracer, pid uint32) error {
 	ENV_PID := os.Getenv("FILTER_PID")
 	if ENV_PID != "" {
 		filterPid, _ := strconv.ParseInt(ENV_PID, 10, 64)
 		if filterPid != int64(pid) {
-			return
+			return nil
 		}
 	}
 	p := c.processes[pid]
 	if p == nil {
-		return
+		return nil
 	}
 	if !p.jvmUprobesChecked {
 		codeType := c.GetCodeTypeFromCache(pid)
 		tracer.InitKProcInfo(pid, c.instanceID, uint16(codeType))
-		p.uprobes = append(p.uprobes, tracer.AttachNetCoreNetReadUprobes(pid, c.instanceID)...)
-		p.uprobes = append(p.uprobes, tracer.AttachNetCoreNetWriteUprobes(pid, c.instanceID)...)
+
+		readProbes, err := tracer.AttachNetCoreNetReadUprobes(pid, c.instanceID)
+		if err != nil {
+			klog.Error(err)
+			return err
+		}
+		p.uprobes = append(p.uprobes, readProbes...)
+
+		WriteProbes, err := tracer.AttachNetCoreNetWriteUprobes(pid, c.instanceID)
+		if err != nil {
+			klog.Error(err)
+			return err
+		}
+		p.uprobes = append(p.uprobes, WriteProbes...)
 		p.jvmUprobesChecked = true
 	}
+
+	return nil
 }
 
 func resolveFd(pid uint32, fd uint64) (mntId string, logPath string) {

+ 103 - 2
containers/container_apm.go

@@ -7,6 +7,7 @@ import (
 	"github.com/coroot/coroot-node-agent/ebpftracer"
 	"github.com/coroot/coroot-node-agent/ebpftracer/l7"
 	"github.com/coroot/coroot-node-agent/ebpftracer/tracer"
+	"github.com/coroot/coroot-node-agent/proc"
 	"github.com/coroot/coroot-node-agent/tracing"
 	"github.com/coroot/coroot-node-agent/utils"
 	"github.com/pkg/errors"
@@ -224,16 +225,26 @@ func (c *Container) onL7RequestApm(pid uint32, fd uint64, timestamp uint64, r *l
 	return nil
 }
 
-func (c *Container) buildInstanceID() {
+func (c *Container) buildIDs(pid uint32) {
 	c.lock.Lock()
 	defer c.lock.Unlock()
+	p := c.processes[pid]
+	if p != nil {
+		p.cmdline = string(proc.GetRealCmdline(pid))
+	}
 	for address, val := range c.getListens() {
 		if val == 1 {
 			ip := address.IP()
 			if ip.Is4() && !ip.IsLoopback() {
 				// 获取端口号
 				port := address.Port()
-				c.instanceID.IntVal, c.instanceID.HashtVal = utils.SetInsID(fmt.Sprintf("%s:%d", ip, port))
+				//c.instanceID.IntVal, c.instanceID.HashtVal, _ =
+				strInstanceID := utils.BuildInt64ID(fmt.Sprintf("%s:%d", ip, port))
+				c.instanceID.IntVal, _ = strInstanceID.ToInt64()
+				c.instanceID.HashtVal = strInstanceID.ToHashByte()
+				c.AppInfo.InstanceId = c.instanceID.IntVal
+				strAgentID := utils.BuildInt64ID(fmt.Sprintf("%s:%s", strInstanceID, string(proc.GetExe(pid))))
+				c.AppInfo.AgentId, _ = strAgentID.ToInt64()
 				break
 			}
 		}
@@ -399,3 +410,93 @@ func (c *Container) GetUprobe(event ebpftracer.StackEvent, tracer *ebpftracer.Tr
 	err = errors.New("uprobe not found")
 	return
 }
+
+func (c *Container) eventReady() {
+	c.lock.Lock()
+	defer c.lock.Unlock()
+	c.l7EventReady = true
+}
+
+func (c *Container) checkEventReady() bool {
+	c.lock.Lock()
+	defer c.lock.Unlock()
+	return c.l7EventReady
+}
+
+func (c *Container) checkL7AttachReady() bool {
+	c.lock.Lock()
+	defer c.lock.Unlock()
+	return c.l7Attach
+}
+
+func (c *Container) l7AttachSuccess() {
+	c.l7Attach = true
+}
+
+func (c *Container) verifyAttachConditions(r *Registry, pid uint32) bool {
+
+	p := c.processes[pid]
+	if p != nil && c.checkEventReady() {
+		codeType := c.GetCodeTypeFromCache(pid)
+		cmdline := p.GetCmdline()
+		fmt.Printf("checkEventReady %v [%d] cmdline='%s' len(cmdline)[%d]\n", c.checkEventReady(), pid, cmdline, len(cmdline))
+
+		if len(cmdline) == 0 {
+			return false
+		}
+		fmt.Println("r.getWhiteListByCodeType(codeType):")
+		fmt.Println(r.getWhiteListByCodeType(codeType))
+		// 当前语言的白名单规则
+		for _, setting := range r.getWhiteListByCodeType(codeType) {
+			ruleVal := setting.Filters
+			if ruleVal == "" {
+				continue
+			}
+			fmt.Println("strings.Contains(cmdline, ruleVal)")
+			fmt.Println(cmdline)
+			fmt.Println(ruleVal)
+			// 判断规则
+			if strings.Contains(cmdline, ruleVal) {
+				fmt.Println("------------", pid, ruleVal)
+				c.WhiteSettingInfo = setting
+				return true
+			}
+		}
+	}
+	return false
+}
+
+func (c *Container) RegisterAppInfo(pid uint32) error {
+	if c.WhiteSettingInfo.AppName == "" {
+		return fmt.Errorf("AppName is empty")
+	}
+	var err error
+	originAppName := c.AppInfo.AppName
+	if originAppName != c.WhiteSettingInfo.AppName {
+		c.AppInfo.AppName = c.WhiteSettingInfo.AppName
+		c.AppInfo.AppId, err = utils.BuildInt64ID(c.AppInfo.AppName).ToInt64()
+
+		// 注册
+		fmt.Println("注册")
+	}
+
+	// ip:port + process_name + exe路径生成
+	//c.instanceID.IntVal + proc.GetExe(pid)
+	//c.AppInfo.AgentId =
+
+	return err
+
+}
+
+func (c *Container) detachUprobes(pid uint32) {
+	c.lock.Lock()
+	defer c.lock.Unlock()
+	// close uprobe
+	if p := c.processes[pid]; p != nil {
+		if len(p.uprobes) > 0 {
+			fmt.Println("卸载")
+			p.DynamicClose()
+			c.l7Attach = false
+		}
+	}
+}

+ 16 - 0
containers/process.go

@@ -30,6 +30,7 @@ type Process struct {
 	stackUprobesChecked   bool
 
 	codeType common.CodeType
+	cmdline  string
 }
 
 func NewProcess(pid uint32, stats *taskstats.Stats) *Process {
@@ -78,3 +79,18 @@ func (p *Process) Close() {
 		_ = u.Close()
 	}
 }
+
+func (p *Process) DynamicClose() {
+	for _, u := range p.uprobes {
+		_ = u.Close()
+	}
+	p.goTlsUprobesChecked = false
+	p.openSslUprobesChecked = false
+	p.jvmUprobesChecked = false
+	p.stackUprobesChecked = false
+	p.uprobes = []link.Link{}
+}
+
+func (p *Process) GetCmdline() string {
+	return p.cmdline
+}

+ 90 - 19
containers/registry.go

@@ -3,6 +3,10 @@ package containers
 import (
 	"bytes"
 	"fmt"
+	. "github.com/coroot/coroot-node-agent/utils"
+	"github.com/coroot/coroot-node-agent/utils/try"
+	. "github.com/coroot/coroot-node-agent/utils/worker"
+	log "github.com/sirupsen/logrus"
 	"os"
 	"regexp"
 	"strings"
@@ -49,6 +53,10 @@ type Registry struct {
 	ip2fqdnLock          sync.Mutex
 
 	processInfoCh chan<- ProcessInfo
+
+	whiteListRules       WhiteListMap
+	whiteLastUpdatedTime int
+	connServer           ServerWorker
 }
 
 var (
@@ -111,11 +119,35 @@ func NewRegistry(reg prometheus.Registerer, kernelVersion string, processInfoCh
 
 		processInfoCh: processInfoCh,
 
-		tracer: ebpftracer.NewTracer(kernelVersion, *flags.DisableL7Tracing, *flags.DisableE2ETracing, *flags.DisableStackTracing),
+		tracer:         ebpftracer.NewTracer(kernelVersion, *flags.DisableL7Tracing, *flags.DisableE2ETracing, *flags.DisableStackTracing),
+		whiteListRules: make(WhiteListMap),
+	}
+	// 初始化软负载集群节点
+	proxyClient, clientErr := NewProxyClient("10.0.12.192:18080", false)
+	if clientErr == nil {
+		// 负载健康检测
+		try.Go(proxyClient.CheckEndpoints, CatchFn)
+		log.Infof("New Proxy Client success.config_server is [%s]", "")
+	} else {
+		log.WithError(clientErr).Errorf("New Proxy Client error")
+		return nil, clientErr
 	}
+
+	r.connServer, err = NewServerHTTPWorker()
+	if err != nil {
+		log.Errorf("init connServer error:%s.", err)
+		return nil, err
+	}
+
 	if err = reg.Register(r); err != nil {
 		return nil, err
 	}
+
+	_, err = r.connWhiteList()
+	if err != nil {
+		return nil, err
+	}
+
 	go r.handleEvents(r.events)
 	if err = r.tracer.Run(r.events); err != nil {
 		close(r.events)
@@ -148,18 +180,47 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 	for {
 		select {
 		case now := <-gcTicker.C:
-			for pid, c := range r.containersByPid {
-				cg, err := proc.ReadCgroup(pid)
-				if err != nil {
-					delete(r.containersByPid, pid)
-					if c != nil {
+			// todo IDS
+			updateFlag, err := r.connWhiteList()
+			if err != nil {
+				log.WithError(err).Errorf("connWhiteList error")
+			}
+			if updateFlag && err == nil {
+				for pid, c := range r.containersByPid {
+					// attach
+					if c.verifyAttachConditions(r, pid) {
+						fmt.Println("verifyAttachConditions ok-------", pid)
+						c.GetCodeTypeFromCache(pid)
+						err := c.RegisterAppInfo(pid)
+						if err != nil {
+							klog.Warningln(err)
+							continue
+						}
+						fmt.Println("start attcah -------", pid)
+						err = c.attachUprobes(r.tracer, pid)
+						fmt.Println(err)
+						fmt.Println("attcah ok -------", pid)
+						//err := c.stackTrace(r.tracer, pid)
+						//if err != nil {
+						//	klog.Errorf("Stack trace error", err)
+						//}
+					} else {
+						// detach
+						c.detachUprobes(pid)
+					}
+
+					cg, err := proc.ReadCgroup(pid)
+					if err != nil {
+						delete(r.containersByPid, pid)
+						if c != nil {
+							c.onProcessExit(pid, false)
+						}
+						continue
+					}
+					if c != nil && cg.Id != c.cgroup.Id {
+						delete(r.containersByPid, pid)
 						c.onProcessExit(pid, false)
 					}
-					continue
-				}
-				if c != nil && cg.Id != c.cgroup.Id {
-					delete(r.containersByPid, pid)
-					c.onProcessExit(pid, false)
 				}
 			}
 			activeIPs := map[netaddr.IP]struct{}{}
@@ -236,17 +297,21 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 				}
 
 			case ebpftracer.EventTypeListenOpen:
-				//fmt.Println("ebpftracer.EventTypeConnectionOpen==================", e.Pid)
+				//fmt.Println("ebpftracer.EventTypeListenOpen==================", e.Pid)
 				if c := r.getOrCreateContainer(e.Pid); c != nil {
 					c.onListenOpen(e.Pid, e.SrcAddr, false)
-					c.buildInstanceID()
+					// cmdline InstanceID agentID
+					c.buildIDs(e.Pid)
+					//c.GetCodeTypeFromCache(e.Pid)
 					//c.attachTlsUprobes(r.tracer, e.Pid)
 					// c.attachJVMUprobes(r.tracer, e.Pid)
-					c.attachUprobes(r.tracer, e.Pid)
-					err := c.stackTrace(r.tracer, e.Pid)
-					if err != nil {
-						klog.Errorf("Stack trace error", err)
-					}
+					//c.attachUprobes(r.tracer, e.Pid)
+					//err := c.stackTrace(r.tracer, e.Pid)
+					//if err != nil {
+					//	klog.Errorf("Stack trace error", err)
+					//}
+					// can attach
+					c.eventReady()
 				} else {
 					klog.Infoln("TCP listen open from unknown container", e)
 				}
@@ -261,7 +326,10 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 					c.onConnectionOpen(e.Pid, e.Fd, e.SrcAddr, e.DstAddr, e.Timestamp, false)
 					//c.attachTlsUprobes(r.tracer, e.Pid)
 					// c.attachJVMUprobes(r.tracer, e.Pid)
-					c.attachUprobes(r.tracer, e.Pid)
+					//c.attachUprobes(r.tracer, e.Pid)
+					//c.GetCodeTypeFromCache(e.Pid)
+					// can attach
+					c.eventReady()
 				} else {
 					klog.Infoln("TCP connection from unknown container", e)
 				}
@@ -292,6 +360,9 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 					continue
 				}
 				if c := r.containersByPid[e.Pid]; c != nil {
+					if !c.checkL7AttachReady() {
+						continue
+					}
 					ip2fqdn := c.onL7RequestApm(e.Pid, e.Fd, e.Timestamp, e.L7Request)
 					r.ip2fqdnLock.Lock()
 					for ip, fqdn := range ip2fqdn {

+ 48 - 0
containers/white_list.go

@@ -0,0 +1,48 @@
+package containers
+
+import (
+	"github.com/coroot/coroot-node-agent/common"
+	. "github.com/coroot/coroot-node-agent/utils/modelse"
+	log "github.com/sirupsen/logrus"
+)
+
+type WhiteListMap map[string][]WhiteSettingInfo
+
+func (r *Registry) getWhiteListByCodeType(codeType common.CodeType) []WhiteSettingInfo {
+	return r.whiteListRules[codeType.WhiteCodeString()]
+}
+
+func (r *Registry) setWhiteList(whiteData WhiteData) {
+	whiteListMap := make(WhiteListMap)
+	for _, scop := range whiteData.Appscope {
+		code := scop.Code
+		for _, setting := range scop.Settings {
+			whiteListMap[code] = append(whiteListMap[code], setting)
+		}
+	}
+	r.whiteListRules = whiteListMap
+}
+
+func (r *Registry) connWhiteList() (bool, error) {
+	whiteListReq := WhiteListReq{
+		HostId:    10154813500555812,
+		AccountId: 110,
+	}
+	whiteData, err := r.connServer.WhiteList(whiteListReq)
+
+	if err != nil {
+		log.Errorf("report WhiteList info error is %v.", err)
+		return false, err
+	}
+
+	// 不用更新
+	if r.whiteLastUpdatedTime >= 0 && r.whiteLastUpdatedTime == whiteData.LastUpdatedTime {
+		return false, nil
+	}
+
+	// 更新时间
+	r.whiteLastUpdatedTime = whiteData.LastUpdatedTime
+
+	r.setWhiteList(whiteData)
+	return true, nil
+}

+ 11 - 11
ebpftracer/netcore.go

@@ -164,9 +164,9 @@ func (t *Tracer) getFunctionOffsetDBG(libPath, functionName string) (elf.Symbol,
 	return elf.Symbol{}, fmt.Errorf("function %s not found", functionName)
 }
 
-func (t *Tracer) AttachNetCoreNetReadUprobes(pid uint32, insID utils.ID) []link.Link {
+func (t *Tracer) AttachNetCoreNetReadUprobes(pid uint32, insID utils.ID) ([]link.Link, error) {
 	if t.DisableL7Tracing() {
-		return nil
+		return nil, nil
 	}
 
 	var links []link.Link
@@ -178,21 +178,21 @@ func (t *Tracer) AttachNetCoreNetReadUprobes(pid uint32, insID utils.ID) []link.
 	l, err := ex.Uprobe(functionSym.Name, t.uprobes["SystemNative_Receive"], &link.UprobeOptions{Address: functionSym.Value, Offset: 113})
 	if err != nil {
 		fmt.Println("failed to attach SystemNative_Receive uprobe", err, functionSym)
-		return nil
+		return nil, err
 	}
 
 	links = append(links, l)
 
 	if len(links) == 0 {
-		return nil
+		return nil, nil
 	}
 	fmt.Println("netcore uprobes attached, pid is ", pid)
-	return links
+	return links, nil
 }
 
-func (t *Tracer) AttachNetCoreNetWriteUprobes(pid uint32, insID utils.ID) []link.Link {
+func (t *Tracer) AttachNetCoreNetWriteUprobes(pid uint32, insID utils.ID) ([]link.Link, error) {
 	if t.DisableL7Tracing() {
-		return nil
+		return nil, nil
 	}
 	//
 	//if pid != 251719 {
@@ -204,7 +204,7 @@ func (t *Tracer) AttachNetCoreNetWriteUprobes(pid uint32, insID utils.ID) []link
 	var links []link.Link
 	ex, err := link.OpenExecutable(libnetSo)
 	if err != nil {
-		return nil
+		return nil, err
 	}
 	opt := link.UprobeOptions{
 		Offset: 16,
@@ -212,14 +212,14 @@ func (t *Tracer) AttachNetCoreNetWriteUprobes(pid uint32, insID utils.ID) []link
 	}
 	upread02, err := ex.Uprobe(sys, t.uprobes["netcore_asmnop"], &opt)
 	if err != nil {
-		return nil
+		return nil, err
 	}
 	links = append(links, upread02)
 
 	if len(links) == 0 {
-		return nil
+		return nil, nil
 	}
 	fmt.Println("netcore client uprobes attached", pid)
 
-	return links
+	return links, nil
 }

+ 36 - 32
ebpftracer/tls.go

@@ -36,13 +36,13 @@ var (
 	opensslVersionRe = regexp.MustCompile(`OpenSSL\s(\d\.\d+\.\d+)`)
 )
 
-func (t *Tracer) AttachOpenSslUprobes(pid uint32) []link.Link {
+func (t *Tracer) AttachOpenSslUprobes(pid uint32) ([]link.Link, error) {
 	if t.DisableL7Tracing() {
-		return nil
+		return nil, nil
 	}
 	libPath, version := getSslLibPathAndVersion(pid)
 	if libPath == "" || version == "" {
-		return nil
+		return nil, nil
 	}
 
 	log := func(msg string, err error) {
@@ -61,7 +61,7 @@ func (t *Tracer) AttachOpenSslUprobes(pid uint32) []link.Link {
 	exe, err := link.OpenExecutable(libPath)
 	if err != nil {
 		log("failed to open executable", err)
-		return nil
+		return nil, err
 	}
 	var links []link.Link
 	writeEnter := "openssl_SSL_write_enter"
@@ -97,7 +97,7 @@ func (t *Tracer) AttachOpenSslUprobes(pid uint32) []link.Link {
 			l, err := exe.Uprobe(p.symbol, t.uprobes[p.uprobe], nil)
 			if err != nil {
 				//log("failed to attach uprobe", err)
-				return nil
+				return nil, err
 			}
 			links = append(links, l)
 		}
@@ -105,19 +105,19 @@ func (t *Tracer) AttachOpenSslUprobes(pid uint32) []link.Link {
 			l, err := exe.Uretprobe(p.symbol, t.uprobes[p.uretprobe], nil)
 			if err != nil {
 				//log("failed to attach uretprobe", err)
-				return nil
+				return nil, err
 			}
 			links = append(links, l)
 		}
 	}
 
 	//log("libssl uprobes attached", nil)
-	return links
+	return links, nil
 }
 
-func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16) []link.Link {
+func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16) ([]link.Link, error) {
 	if t.DisableL7Tracing() {
-		return nil
+		return nil, nil
 	}
 
 	path := proc.Path(pid, "exe")
@@ -140,24 +140,24 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 	bi, err := buildinfo.ReadFile(path)
 	if err != nil {
 		log("failed to read build info", err)
-		return nil
+		return nil, err
 	}
 
 	name, err = os.Readlink(path)
 	if err != nil {
 		log("failed to read name", err)
-		return nil
+		return nil, err
 	}
 	version = strings.Replace(bi.GoVersion, "go", "v", 1)
 	if semver.Compare(version, minSupportedGoVersion) < 0 {
 		log(fmt.Sprintf("go_versions below %s are not supported", minSupportedGoVersion), nil)
-		return nil
+		return nil, err
 	}
 
 	ef, err := elf.Open(path)
 	if err != nil {
 		log("failed to open as elf binary", err)
-		return nil
+		return nil, err
 	}
 	defer ef.Close()
 
@@ -165,28 +165,28 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 	if err != nil {
 		if errors.Is(err, elf.ErrNoSymbols) {
 			log("no symbol section", nil)
-			return nil
+			return nil, err
 		}
 		log("failed to read symbols", err)
-		return nil
+		return nil, err
 	}
 
 	textSection := ef.Section(".text")
 	if textSection == nil {
 		log("no text section", nil)
-		return nil
+		return nil, err
 	}
 	textSectionData, err := textSection.Data()
 	if err != nil {
 		log("failed to read text section", err)
-		return nil
+		return nil, err
 	}
 	textSectionLen := uint64(len(textSectionData) - 1)
 
 	exe, err := link.OpenExecutable(path)
 	if err != nil {
 		log("failed to open executable", err)
-		return nil
+		return nil, err
 	}
 
 	offset, ok := tracer.GetOffset(tracer.NewID("std", "runtime", "g", "goid"), path)
@@ -199,14 +199,17 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			major, err = strconv.Atoi(parts[0])
 			if err != nil {
 				log("Error converting major version:", err)
+				return nil, err
 			}
 			minor, err = strconv.Atoi(parts[1])
 			if err != nil {
 				log("Error converting minor version:", err)
+				return nil, err
 			}
 			revision, err = strconv.Atoi(parts[2])
 			if err != nil {
 				log("Error converting revision version:", err)
+				return nil, err
 			}
 			goVersion := ((major & 0xFF) << 16) + ((minor & 0xFF) << 8) + min(revision, 255)
 
@@ -243,6 +246,7 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			_, err = tracer.UpdateProcInfoToMap(t.collection, pid, info)
 			if err != nil {
 				klog.Error("failed to update program info", err)
+				return nil, err
 			}
 		}
 	}
@@ -277,7 +281,7 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			if err != nil {
 				log("failed to attach write_enter uprobe", err)
 				klog.Infoln("runtime.execute no")
-				return nil
+				return nil, err
 			} else {
 				klog.Infoln("runtime.execute ok")
 			}
@@ -287,7 +291,7 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			l, err := exe.Uprobe(s.Name, t.uprobes["enter_runtime_newproc1"], &link.UprobeOptions{Address: address})
 			if err != nil {
 				log("failed to attach newproc1 uprobe", err)
-				return nil
+				return nil, err
 			}
 			links = append(links, l)
 			sStart := s.Value - textSection.Addr
@@ -299,13 +303,13 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			returnOffsets := getReturnOffsets(ef.Machine, sBytes)
 			if len(returnOffsets) == 0 {
 				log("failed to attach enter_runtime_newproc1 uprobe", fmt.Errorf("no return offsets found"))
-				return nil
+				return nil, err
 			}
 			for _, offset := range returnOffsets {
 				l, err := exe.Uprobe(s.Name, t.uprobes["exit_runtime_newproc1"], &link.UprobeOptions{Address: address, Offset: uint64(offset)})
 				if err != nil {
 					log("failed to attach exit_runtime_newproc1 uprobe", err)
-					return nil
+					return nil, err
 				}
 				links = append(links, l)
 			}
@@ -329,13 +333,13 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			returnOffsets := getReturnOffsets(ef.Machine, sBytes)
 			if len(returnOffsets) == 0 {
 				log("failed to attach uprobe_HandlerFunc_ServeHTTP uprobe", fmt.Errorf("no return offsets found"))
-				return nil
+				return nil, err
 			}
 			for _, offset := range returnOffsets {
 				l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_HandlerFunc_ServeHTTP_Returns"], &link.UprobeOptions{Address: address, Offset: uint64(offset)})
 				if err != nil {
 					log("failed to attach exit_runtime_newproc1 uprobe", err)
-					return nil
+					return nil, err
 				}
 				links = append(links, l)
 			}
@@ -363,13 +367,13 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			returnOffsets := getReturnOffsets(ef.Machine, sBytes)
 			if len(returnOffsets) == 0 {
 				log("failed to attach uprobe_Transport_roundTrip uprobe", fmt.Errorf("no return offsets found"))
-				return nil
+				return nil, err
 			}
 			for _, offset := range returnOffsets {
 				l, err := exe.Uprobe(s.Name, t.uprobes["uprobe_Transport_roundTrip_Returns"], &link.UprobeOptions{Address: address, Offset: uint64(offset)})
 				if err != nil {
 					log("failed to attach exit_runtime_newproc1 uprobe", err)
-					return nil
+					return nil, err
 				}
 				links = append(links, l)
 			}
@@ -378,14 +382,14 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			l, err := exe.Uprobe(s.Name, t.uprobes["go_crypto_tls_write_enter"], &link.UprobeOptions{Address: address})
 			if err != nil {
 				log("failed to attach write_enter uprobe", err)
-				return nil
+				return nil, err
 			}
 			links = append(links, l)
 		case goTlsReadSymbol:
 			l, err := exe.Uprobe(s.Name, t.uprobes["go_crypto_tls_read_enter"], &link.UprobeOptions{Address: address})
 			if err != nil {
 				log("failed to attach read_enter uprobe", err)
-				return nil
+				return nil, err
 			}
 			links = append(links, l)
 			sStart := s.Value - textSection.Addr
@@ -397,23 +401,23 @@ func (t *Tracer) AttachGoTlsUprobes(pid uint32, insID utils.ID, codeType uint16)
 			returnOffsets := getReturnOffsets(ef.Machine, sBytes)
 			if len(returnOffsets) == 0 {
 				log("failed to attach read_exit uprobe", fmt.Errorf("no return offsets found"))
-				return nil
+				return nil, err
 			}
 			for _, offset := range returnOffsets {
 				l, err := exe.Uprobe(s.Name, t.uprobes["go_crypto_tls_read_exit"], &link.UprobeOptions{Address: address, Offset: uint64(offset)})
 				if err != nil {
 					log("failed to attach read_exit uprobe", err)
-					return nil
+					return nil, err
 				}
 				links = append(links, l)
 			}
 		}
 	}
 	if len(links) == 0 {
-		return nil
+		return nil, err
 	}
 	log("crypto/tls uprobes attached", nil)
-	return links
+	return links, nil
 }
 
 func getSslLibPathAndVersion(pid uint32) (string, string) {

+ 18 - 0
proc/proc.go

@@ -2,6 +2,7 @@ package proc
 
 import (
 	"bytes"
+	"fmt"
 	"os"
 	"path"
 	"strconv"
@@ -28,6 +29,23 @@ func GetCmdline(pid uint32) []byte {
 	return bytes.TrimSuffix(cmdline, []byte{0})
 }
 
+func GetRealCmdline(pid uint32) []byte {
+	cmdline, err := os.ReadFile(Path(pid, "cmdline"))
+	if err != nil {
+		return nil
+	}
+	return bytes.ReplaceAll(cmdline, []byte("\x00"), []byte(" "))
+}
+
+func GetExe(pid uint32) []byte {
+	exe, err := os.ReadFile(Path(pid, "exe"))
+	if err != nil {
+		fmt.Printf("Error reading executable path for PID %d: %v\n", pid, err)
+		return nil
+	}
+	return bytes.TrimSuffix(exe, []byte{0})
+}
+
 func GetNsPid(pid uint32) uint32 {
 	data, err := os.ReadFile(Path(pid, "status"))
 	if err != nil {

+ 44 - 5
utils/id.go

@@ -42,6 +42,26 @@ type ID struct {
 	HashtVal HashByte
 }
 
+type ID_STRING string
+
+func (id ID_STRING) ToString() string {
+	return string(id)
+}
+
+func (id ID_STRING) ToInt64() (int64, error) {
+	intID, err := strconv.ParseInt(id.ToString(), 10, 64)
+	if err != nil {
+		return 0, err
+	}
+	return intID, nil
+}
+
+func (id ID_STRING) ToHashByte() HashByte {
+	var charArray HashByte
+	hexStringToBPFBytes(id.ToString(), &charArray)
+	return charArray
+}
+
 func init() {
 
 }
@@ -56,20 +76,39 @@ var (
 	INSTANCE_ID_BYTE HashByte
 )
 
-func SetInsID(str string) (int64, HashByte) {
+func BuildInt64ID(str string) ID_STRING {
+	srcCode := md5.Sum([]byte(str))
+	code := fmt.Sprintf("%x", srcCode)
+
+	id_string := md5ToDec(code)
+	fmt.Println(id_string)
+	return ID_STRING(id_string)
+	//
+	//id, err := strconv.ParseInt(id_string, 10, 64)
+	//if err != nil {
+	//	return 0, HashByte{}, ""
+	//}
+	////INSTANCE_ID_INT64 = id
+	//var charArray HashByte
+	//hexStringToBPFBytes(id_string, &charArray)
+	////INSTANCE_ID_BYTE = charArray
+	//return id, charArray, id_string
+}
+
+func BuildInt64ID2(str string) (int64, HashByte, string) {
 	srcCode := md5.Sum([]byte(str))
 	code := fmt.Sprintf("%x", srcCode)
 	id_string := md5ToDec(code)
 	fmt.Println(id_string)
 	id, err := strconv.ParseInt(id_string, 10, 64)
 	if err != nil {
-		return 0, HashByte{}
+		return 0, HashByte{}, ""
 	}
-	INSTANCE_ID_INT64 = id
+	//INSTANCE_ID_INT64 = id
 	var charArray HashByte
 	hexStringToBPFBytes(id_string, &charArray)
-	INSTANCE_ID_BYTE = charArray
-	return id, charArray
+	//INSTANCE_ID_BYTE = charArray
+	return id, charArray, id_string
 }
 
 func GetHostID() (int64, HashByte) {