Browse Source

Feature #TASK_QT-15938 EBPF-euspace容器化部署-通过容器rootfs路径读取可执行文件&给java进程拷贝cwlibnet.so

Tom.Li 1 năm trước cách đây
mục cha
commit
28f97b64da
5 tập tin đã thay đổi với 79 bổ sung18 xóa
  1. 6 6
      containers/container_apm.go
  2. 1 0
      containers/registry.go
  3. 53 11
      containers/util.go
  4. 7 1
      ebpftracer/jvm.go
  5. 12 0
      flags/flags.go

+ 6 - 6
containers/container_apm.go

@@ -5,7 +5,9 @@ import (
 	"bytes"
 	"debug/elf"
 	"fmt"
+	"github.com/coroot/coroot-node-agent/flags"
 	"os"
+	"path"
 	"sort"
 	"strconv"
 	"strings"
@@ -23,7 +25,9 @@ import (
 	"inet.af/netaddr"
 )
 
-const TRACE_STATUS = 1
+const (
+	TRACE_STATUS = 1
+)
 
 func (c *Container) getTrace(traceId uint64) (*tracing.Trace, bool) {
 	trace, ok := c.traceMap[traceId]
@@ -195,8 +199,6 @@ func (c *Container) onL7RequestApm(pid uint32, fd uint64, timestamp uint64, r *l
 		}
 
 	case l7.ProtocolDM:
-		fmt.Println("---- onL7RequestApm ProtocolDM  start ---->")
-		fmt.Println("-------dm r.Status :", r.Status)
 		//统计dm的query次数
 		stats.observe(r.Status.String(), "", r.Duration)
 		//是否发送数据
@@ -206,13 +208,11 @@ func (c *Container) onL7RequestApm(pid uint32, fd uint64, timestamp uint64, r *l
 			}
 			query := conn.dmParser.Parse(r.Payload, r.StatementId)
 			apmTrace, err := c.getOrInitTrace(r.TraceId)
-			fmt.Println("-------dm r.TraceId:", r.TraceId)
 			if err == nil {
 				apmTrace.DmTraceQueryEvent(query, r, conn.ActualDest)
 				c.SendEvent(apmTrace, r.TraceId)
 			}
 		}
-		fmt.Println("---- onL7RequestApm ProtocolDM  end <----")
 	case l7.ProtocolMemcached:
 		stats.observe(r.Status.String(), "", r.Duration)
 		if c.l7Attach && c.valuableTrace(r.TraceId) {
@@ -550,7 +550,7 @@ func (c *Container) detachUprobes(pid uint32) {
 
 func (c *Container) getRootfs() string {
 	if c.metadata != nil && c.metadata.rootfs != "" {
-		return c.metadata.rootfs
+		return path.Join(*flags.HostDirPathPrefix, c.metadata.rootfs)
 	}
 	return ""
 }

+ 1 - 0
containers/registry.go

@@ -403,6 +403,7 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 					}
 				}
 			case ebpftracer.EventTypeL7Request:
+
 				//fmt.Println("e.L7Request Payload:", string(e.L7Request.Payload))
 				if e.L7Request == nil {
 					continue

+ 53 - 11
containers/util.go

@@ -3,6 +3,7 @@ package containers
 import (
 	"debug/elf"
 	"fmt"
+	"github.com/coroot/coroot-node-agent/flags"
 	. "github.com/coroot/coroot-node-agent/utils/modelse"
 	klog "github.com/sirupsen/logrus"
 	"os"
@@ -50,15 +51,28 @@ func isJavaAotProcess(pid uint32, rootfs string) bool {
 	// Get the executable path for the given PID
 	exePath, err := os.Readlink(fmt.Sprintf("%sproc/%d/exe", "/", pid))
 	if err != nil {
-		fmt.Printf("Error reading executable path for PID %d: %v\n", pid, err)
+		//fmt.Printf("Error reading executable path for PID %d: %v\n", pid, err)
+		klog.WithError(err).Errorf("isJavaAotProcess,failed to reading executable path for PID [%d]", pid)
 		return false
 	}
 
 	// Read the content of the executable file
-	content, err := os.ReadFile(fmt.Sprintf("%s%s", rootfs, exePath))
+	pathPrefix := rootfs
+	if pathPrefix == "" && *flags.RunInContainer {
+		pathPrefix = *flags.HostDirPathPrefix
+	}
+	content, err := os.ReadFile(fmt.Sprintf("%s%s", pathPrefix, exePath))
 	if err != nil {
-		klog.WithError(err).Errorf("Error reading executable file for PID %d\n", pid)
-		return false
+		if _, err = os.Stat(exePath); err == nil {
+			content, err = os.ReadFile(exePath)
+			if err != nil {
+				klog.WithError(err).Errorf("isJavaAotProcess,failed to reading executable file local for PID [%d]", pid)
+				return false
+			}
+		} else {
+			klog.WithError(err).Errorf("isJavaAotProcess,failed to reading executable file for PID [%d]", pid)
+			return false
+		}
 	}
 
 	// Check if the file contains the "graal_attach_thread" string
@@ -73,12 +87,26 @@ func isNetCoreProcess(pid uint32, rootfs string) bool {
 	path, err := getProcessPath(pid)
 	if err != nil {
 		//fmt.Printf("无法获取进程路径:%s\n", err)
+		klog.WithError(err).Errorf("isNetCoreProcess,failed to open as elf binary path for PID [%d]", pid)
 		return false
 	}
-	ef, err := elf.Open(rootfs + path)
+
+	pathPrefix := rootfs
+	if pathPrefix == "" && *flags.RunInContainer {
+		pathPrefix = *flags.HostDirPathPrefix
+	}
+	ef, err := elf.Open(pathPrefix + path)
 	if err != nil {
-		klog.WithError(err).Error("failed to open as elf binary")
-		return false
+		if _, err = os.Stat(path); err == nil {
+			ef, err = elf.Open(path)
+			if err != nil {
+				klog.WithError(err).Errorf("isNetCoreProcess,failed to open as elf binary file local for PID [%d]", pid)
+				return false
+			}
+		} else {
+			klog.WithError(err).Errorf("isNetCoreProcess,failed to open as elf binary file for PID [%d]", pid)
+			return false
+		}
 	}
 	defer ef.Close()
 
@@ -93,13 +121,27 @@ func isNetCoreProcess(pid uint32, rootfs string) bool {
 func isGoProcess(pid uint32, rootfs string) bool {
 	path, err := getProcessPath(pid)
 	if err != nil {
-		klog.WithError(err).Error("failed to open as elf binary")
+		klog.WithError(err).Errorf("isGoProcess,failed to open as elf binary path for PID [%d]", pid)
 		return false
 	}
-	ef, err := elf.Open(rootfs + path)
+
+	pathPrefix := rootfs
+	if pathPrefix == "" && *flags.RunInContainer {
+		pathPrefix = *flags.HostDirPathPrefix
+	}
+
+	ef, err := elf.Open(pathPrefix + path)
 	if err != nil {
-		fmt.Println("failed to open as elf binary", err)
-		return false
+		if _, err = os.Stat(path); err == nil {
+			ef, err = elf.Open(path)
+			if err != nil {
+				klog.WithError(err).Errorf("isGoProcess,failed to open as elf binary file local for PID [%d]", pid)
+				return false
+			}
+		} else {
+			klog.WithError(err).Errorf("isGoProcess,failed to open as elf binary file for PID [%d]", pid)
+			return false
+		}
 	}
 	defer ef.Close()
 

+ 7 - 1
ebpftracer/jvm.go

@@ -3,6 +3,7 @@ package ebpftracer
 import (
 	"errors"
 	"github.com/coroot/coroot-node-agent/ebpftracer/tracer/inject"
+	"github.com/coroot/coroot-node-agent/flags"
 	"github.com/coroot/coroot-node-agent/utils"
 	. "github.com/coroot/coroot-node-agent/utils/modelse"
 	klog "github.com/sirupsen/logrus"
@@ -146,7 +147,12 @@ func (t *Tracer) AttachJavaNetWriteUprobes(pid uint32, rootfs string) ([]link.Li
 	cwJvmLibPath := utils.GetDefaultLibsPath("jvm", "cwlibnet.so")
 	tmpSo := "/tmp/cwlibnet.so"
 	procLoadPath := cwJvmLibPath
-	if rootfs != "" {
+
+	pathPrefix := rootfs
+	if pathPrefix == "" && *flags.RunInContainer {
+		pathPrefix = *flags.HostDirPathPrefix
+	}
+	if pathPrefix != "" {
 		// copy
 		size, err := utils.CopyFile(cwJvmLibPath, rootfs+tmpSo)
 		if err != nil || size == 0 {

+ 12 - 0
flags/flags.go

@@ -20,6 +20,7 @@ var (
 	DisableL7Tracing    = kingpin.Flag("disable-l7-tracing", "Disable L7 tracing").Default("false").Envar("DISABLE_L7_TRACING").Bool()
 	DisableStackTracing = kingpin.Flag("disable-stack-tracing", "Disable stack tracing").Default("false").Envar("DISABLE_STACK_TRACING").Bool()
 	DisableE2ETracing   = kingpin.Flag("disable-e2e-tracing", "Disable e2e tracing").Default("false").Envar("DISABLE_E2E_TRACING").Bool()
+	RunInContainer      = kingpin.Flag("run-in-container", "run in container").Default("false").Envar("RUN_IN_CONTAINER").Bool()
 
 	ExternalNetworksWhitelist = kingpin.Flag("track-public-network", "Allow track connections to the specified IP networks, all private networks are allowed by default (e.g., Y.Y.Y.Y/mask)").Envar("TRACK_PUBLIC_NETWORK").Strings()
 	EphemeralPortRange        = kingpin.Flag("ephemeral-port-range", "Destination and Listen TCP ports from this range will be skipped").Default("").Envar("EPHEMERAL_PORT_RANGE").String()
@@ -45,6 +46,8 @@ var (
 	DumpApps       = kingpin.Flag("dump", "Dump app snap").Default("false").Bool()
 	LogLevel       = kingpin.Flag("log-level", "Log level").Envar("LOG_LEVEL").Default("info").String()
 	EbpfFilePath   = kingpin.Flag("ebpf-path", "Set ebpf file path").Envar("EBPF_FILE").Default("").String()
+
+	HostDirPathPrefix = kingpin.Flag("host-dir-path-prefix", "Set the prefix of path about the mount point of the host directory").Envar("HOST_DIR_PATH_PREFIX").Default("").String()
 )
 
 func GetString(fl *string) string {
@@ -83,6 +86,15 @@ func init() {
 	if *MetricsEndpoint != nil {
 		*ListenAddress = "127.0.0.1:10300"
 	}
+
+	if *RunInContainer {
+		if *HostDirPathPrefix == "" {
+			*HostDirPathPrefix = "/host"
+		}
+	} else {
+		*HostDirPathPrefix = ""
+	}
+
 }
 
 func DumpTableFeatures() {