Quellcode durchsuchen

Feature #TASK_QT-18250 中央国债 add more logs

Feature #TASK_QT-18250 中央国债x86 log

Feature #TASK_QT-18250 中央国债x86 2gb
Carl vor 9 Monaten
Ursprung
Commit
cdb51725ae

+ 1 - 1
Dockerfile

@@ -1,4 +1,4 @@
-FROM dockerproxy.net/library/ubuntu:22.04
+FROM harbor.cloudwise.com/apm/euspace-base:22.04-amd64
 ARG EUSPACE_BASE_PATH=/opt/cloudwise/apm/euspace
 RUN mkdir -p $EUSPACE_BASE_PATH
 #拷贝安装目录结构

+ 19 - 0
containers/apm_white_list_v2.go

@@ -1,10 +1,14 @@
 package containers
 
 import (
+	"encoding/json"
 	"fmt"
 	"github.com/coroot/coroot-node-agent/common"
+	"github.com/coroot/coroot-node-agent/utils"
 	. "github.com/coroot/coroot-node-agent/utils/modelse"
 	log "github.com/sirupsen/logrus"
+	"os"
+	"path"
 )
 
 func (r *Registry) getWhiteListAll() []WhiteSettingInfo {
@@ -56,5 +60,20 @@ func (r *Registry) pullWhiteListV2() (bool, error) {
 	//// 更新时间
 	r.whiteLastUpdatedTime = whiteData.LastUpdatedTime
 	r.setWhiteListV2(whiteData)
+	saveRule(whiteData)
 	return true, nil
 }
+
+func saveRule(runtimeApps WhiteDataV2) {
+	appStr, _ := json.Marshal(runtimeApps)
+	dumpPath := path.Join(utils.GetDefaultRuntimePath(), "memdump")
+	err := os.MkdirAll(dumpPath, 0755)
+	if err != nil {
+		log.Error(err)
+	}
+	fileName := path.Join(dumpPath, "rule.snap")
+	err = os.WriteFile(fileName, appStr, 0644)
+	if err != nil {
+		log.Error(err)
+	}
+}

+ 2 - 2
containers/container.go

@@ -1448,10 +1448,10 @@ func (c *Container) AttachUprobes(tracer *ebpftracer.Tracer, pid uint32, _type s
 		err = c.attachNetCoreUprobes(tracer, pid)
 	}
 	if err != nil {
-		klog.Errorf("[attach] error  %v :", err)
+		klog.WithField("pid", pid).Errorf("[attach] error  %v :", err)
 		deErr := c.DetachUprobes(tracer, pid, APP_UPROBE_ERROR)
 		if deErr != nil {
-			klog.Errorf("[attach] Detach Uprobes error  %v :", deErr)
+			klog.WithField("pid", pid).Errorf("[attach] Detach Uprobes error  %v :", deErr)
 		}
 		return err
 	}

+ 44 - 27
containers/container_apm.go

@@ -800,49 +800,66 @@ func (c *Container) getRootfs() string {
 }
 
 func (c *Container) BuildActiveApps(runtimeApps map[uint32]AppStatusInfo, pid uint32) {
-	if c != nil && c.AppInfo.AppName != "" {
-		detail := AppStatusInfo{
-			Pid:        pid,
-			ProcName:   c.containerName,
-			AppName:    c.AppInfo.AppName,
-			Language:   c.AppInfo.CodeType.String(),
-			AppID:      c.AppInfo.AppIdHash.IntVal,
-			AgentID:    c.AppInfo.AgentId,
-			InstanceID: c.AppInfo.InstanceIdHash.IntVal,
-			Sn:         c.AppInfo.Sn,
-			Sport:      c.AppInfo.Sport,
-			RegisterAt: time.Unix(c.AppInfo.RegisterAt, 0).Format("060102 15:04:05"),
-			PreStatus:  c.AppInfo.PreStatus,
-			Status:     c.AppInfo.Status,
-			Rule:       c.WhiteSettingInfo.Filters,
-		}
-		detail.Rule = fmt.Sprintf("%s|%d", c.WhiteSettingInfo.Filters, c.WhiteSettingInfo.WhiteStackSettingInfo.OpenStack)
-		if c.AppInfo.UpdateAt != 0 {
-			detail.UpdateAt = time.Unix(c.AppInfo.UpdateAt, 0).Format("060102 15:04:05")
-		}
-		p := c.processes[pid]
-		if p != nil {
-			detail.StackStatus = p.stackStatus.String()
-			detail.StackStatus += fmt.Sprintf("|vFailed:%v", p.versionFailed)
-		}
-		runtimeApps[pid] = detail
+	if c == nil {
+		//klog.WithField("pid", pid).Warningln("[BuildActiveApps] container_apm is nil.")
+		return
+	}
+	if c.AppInfo.AppName == "" {
+		return
+	}
+	klog.WithField("pid", pid).WithField("appname", c.AppInfo.AppName).Infof("[BuildActiveApps] container %s is running.", c.AppInfo.AppName)
+	detail := AppStatusInfo{
+		Pid:        pid,
+		ProcName:   c.containerName,
+		AppName:    c.AppInfo.AppName,
+		Language:   c.AppInfo.CodeType.String(),
+		AppID:      c.AppInfo.AppIdHash.IntVal,
+		AgentID:    c.AppInfo.AgentId,
+		InstanceID: c.AppInfo.InstanceIdHash.IntVal,
+		Sn:         c.AppInfo.Sn,
+		Sport:      c.AppInfo.Sport,
+		RegisterAt: time.Unix(c.AppInfo.RegisterAt, 0).Format("060102 15:04:05"),
+		PreStatus:  c.AppInfo.PreStatus,
+		Status:     c.AppInfo.Status,
+		Rule:       c.WhiteSettingInfo.Filters,
+		Container:  string(c.id),
+	}
+	detail.Rule = fmt.Sprintf("%s|%d", c.WhiteSettingInfo.Filters, c.WhiteSettingInfo.WhiteStackSettingInfo.OpenStack)
+	if c.AppInfo.UpdateAt != 0 {
+		detail.UpdateAt = time.Unix(c.AppInfo.UpdateAt, 0).Format("060102 15:04:05")
+	}
+	p := c.processes[pid]
+	if p != nil {
+		detail.StackStatus = p.stackStatus.String()
+		v := 0
+		if !p.versionFailed {
+			v = 1
+		}
+		detail.StackStatus += fmt.Sprintf("V=%d", v)
 	}
+	runtimeApps[pid] = detail
 
 }
 
 func (c *Container) AgentCtrl(r *Registry, pid uint32) {
+	if c == nil {
+		//klog.WithField("pid", pid).Warningln("[AgentCtrl] cannot find container.")
+		return
+	}
 	var err error
 	verifyAttachConditions, _ := c.verifyAttachConditions(r, pid)
 
-	// UNINSTALL
+	// fusing UNINSTALL
 	if r.isFusing && c.Isl7AttachSuccess() {
 		c.Detach(r.tracer, pid, APP_FUSE)
+		klog.WithField("pid", pid).Infoln("[AgentCtrl] fusing")
 		return
 	}
 
 	// verify UNINSTALL
 	if !verifyAttachConditions && c.Isl7AttachSuccess() {
 		c.Detach(r.tracer, pid, APP_UNINSTALL)
+		klog.WithField("pid", pid).Infoln("[AgentCtrl] rule uninstall.")
 		return
 	}
 

+ 75 - 8
containers/registry.go

@@ -56,8 +56,8 @@ type Registry struct {
 
 	hostConntrack *Conntrack
 
-	containersById       map[ContainerID]*Container
-	containersByCgroupId map[string]*Container
+	containersById       map[ContainerID]*Container // calcId
+	containersByCgroupId map[string]*Container      // fmt.Sprintf("%s/%d", cg.Id, pid)
 	containersByPid      map[uint32]*Container
 	ip2fqdn              map[netaddr.IP]string
 	ip2fqdnLock          sync.Mutex
@@ -73,6 +73,7 @@ type Registry struct {
 	nodeInfo                *NodeInfoT
 	isFusing                bool
 	IsFuseException         bool
+	RegistryApps            map[uint32]AppStatusInfo
 }
 
 var (
@@ -139,6 +140,7 @@ func NewRegistry(reg prometheus.Registerer, kernelVersion string, nodeInfo *Node
 		whiteListRules:       make(WhiteListMap),
 		trafficStatsUpdateCh: make(chan *TrafficStatsUpdate),
 		nodeInfo:             nodeInfo,
+		RegistryApps:         make(map[uint32]AppStatusInfo),
 	}
 	// 初始化软负载集群节点
 	proxyClient, clientErr := NewProxyClient(*flags.ConfigServer, false)
@@ -236,8 +238,34 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 				klog.WithError(err).Errorf("connWhiteList error")
 			}
 			runtimeApps := make(map[uint32]AppStatusInfo)
+
+			for pid, appInfo := range r.RegistryApps {
+				c, ok := r.containersByPid[pid]
+				if !ok {
+					klog.WithFields(map[string]interface{}{
+						"pid":     pid,
+						"appname": appInfo.AppName,
+					}).Infof("[handle] proc or container already deleted.")
+					continue
+				}
+				if c == nil {
+					klog.WithFields(map[string]interface{}{
+						"pid":     pid,
+						"appname": appInfo.AppName,
+					}).Infof("[handle] container exists but c.data not ready.")
+				}
+			}
+
 			for pid, c := range r.containersByPid {
-				if c != nil && !common.IsOpenFilter() && !fuseOnce {
+				if c == nil {
+					klog.WithField("pid", pid).Warningln("[handle] container is nil.")
+					app, ok := r.RegistryApps[pid]
+					if ok {
+						klog.WithFields(map[string]interface{}{"pid": pid, "appname": app.AppName}).
+							Infof("[handle] proc or container is deleted.")
+					}
+				}
+				if !common.IsOpenFilter() && !fuseOnce {
 					c.AgentCtrl(r, pid)
 				}
 				c.BuildActiveApps(runtimeApps, pid)
@@ -245,6 +273,10 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 				cg, err := proc.ReadCgroup(pid)
 				if err != nil {
 					delete(r.containersByPid, pid)
+					_, ok := r.RegistryApps[pid]
+					if ok {
+						klog.Infof("[handle] cgroup not find %d", pid)
+					}
 					if c != nil {
 						c.onProcessExit(pid, false)
 					}
@@ -252,10 +284,20 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 				}
 				if c != nil && cg.Id != c.cgroup.Id {
 					delete(r.containersByPid, pid)
+					_, ok := r.RegistryApps[pid]
+					if ok {
+						klog.Infof("[handle] cgroup id changed %d", pid)
+					}
 					c.onProcessExit(pid, false)
+					// 重新验证cgroup,可能需要重新创建容器
+					if newC := r.getOrCreateContainer(pid); newC != nil {
+						// 更新容器引用
+						r.containersByPid[pid] = newC
+					}
 				}
 			}
-			saveAppInfo(runtimeApps)
+			r.RegistryApps = runtimeApps
+			saveAppInfo(r.RegistryApps)
 			if r.isFusing {
 				fuseOnce = true
 			} else {
@@ -279,6 +321,11 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 				for pid, cc := range r.containersByPid {
 					if cc == c {
 						delete(r.containersByPid, pid)
+						app, ok := r.RegistryApps[pid]
+						if ok {
+							klog.WithFields(map[string]interface{}{"pid": pid, "appname": app.AppName}).
+								Infof("[handle] Dead proc or container is deleted from containers.")
+						}
 					}
 				}
 				if ok := prometheus.WrapRegistererWith(setLabels(string(id),
@@ -319,10 +366,20 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 				switch { // possible pids wraparound + missed `process-exit` event
 				case c == nil && seen: // ignored
 					delete(r.containersByPid, e.Pid)
+					app, ok := r.RegistryApps[e.Pid]
+					if ok {
+						klog.WithFields(map[string]interface{}{"pid": e.Pid, "appname": app.AppName}).
+							Infof("[handle] [EventTypeProcessStart nil] proc or container is deleted from containers.")
+					}
 				case c != nil: // revalidating by cgroup
 					cg, err := proc.ReadCgroup(e.Pid)
 					if err != nil || cg.Id != c.cgroup.Id {
 						delete(r.containersByPid, e.Pid)
+						app, ok := r.RegistryApps[e.Pid]
+						if ok {
+							klog.WithFields(map[string]interface{}{"pid": e.Pid, "appname": app.AppName}).
+								Infof("[handle] [EventTypeProcessStart cgroup] proc or container is deleted from containers.")
+						}
 						c.onProcessExit(e.Pid, false)
 					}
 				}
@@ -333,15 +390,25 @@ func (r *Registry) handleEvents(ch <-chan ebpftracer.Event) {
 					}
 				}
 			case ebpftracer.EventTypeProcessExit:
-				if c := r.containersByPid[e.Pid]; c != nil {
+				c := r.containersByPid[e.Pid]
+				cid := ""
+				if c != nil {
 					c.onProcessExit(e.Pid, e.Reason == ebpftracer.EventReasonOOMKill)
+					cid = string(c.id)
 				}
 				delete(r.containersByPid, e.Pid)
+				if app, ok := r.RegistryApps[e.Pid]; ok {
+					klog.WithFields(map[string]interface{}{
+						"pid":     e.Pid,
+						"appname": app.AppName,
+						"cid":     cid,
+					}).Info("[handle] EventTypeProcessExit proc or container is deleted from containers.")
+				}
 
 			case ebpftracer.EventTypeFileOpen:
-				if c := r.getOrCreateContainer(e.Pid); c != nil {
-					c.onFileOpen(e.Pid, e.Fd)
-				}
+				//if c := r.getOrCreateContainer(e.Pid); c != nil {
+				//	c.onFileOpen(e.Pid, e.Fd)
+				//}
 
 			case ebpftracer.EventTypeListenOpen:
 				//fmt.Println("ebpftracer.EventTypeListenOpen==================", e.Pid)

+ 1 - 1
ebpftracer/tracer.go

@@ -897,7 +897,7 @@ func (t *Tracer) InitKProcInfo(pid uint32, appInfo *AppInfo) error {
 func (t *Tracer) DelKProcInfo(pid uint32) error {
 	_, err := tracer.DelProcInfoFromMap(t.collection, pid)
 	if err != nil {
-		klog.Error("failed to delete proc info", err)
+		klog.WithField("pid", pid).Error("failed to delete proc info", err)
 	}
 	return err
 }

+ 70 - 62
ebpftracer/tracer/inject/inject_linux_amd64.go

@@ -26,6 +26,8 @@ import (
 const (
 	IO_FD_FDID_SYM_OFFSET = 129
 	NET_SEND_SYM_OFFSET   = 518
+	// 备份指令长度
+	ORIGIN_CODE_LEN = 12
 )
 
 type InstInfo struct {
@@ -46,6 +48,7 @@ type InnerSymbolInfo struct {
 }
 
 func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
+	klog.Infof("findReleaseAddressInfoFromMem start.")
 	funcAbsAddress := j.ReleaseLibNetInfo.FuncSymbol.SymAddr
 	releaseFuncSym := InnerSymbolInfo{}
 	code, err := j.readMemory(funcAbsAddress, j.ReleaseLibNetInfo.FuncSymbol.SymSize)
@@ -59,7 +62,7 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
 
 		inst, err := x86asm.Decode(code[pc:], 64)
 		if err != nil {
-			fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
+			klog.Errorf("Decode error at offset 0x%x: %v\n", pc, err)
 			pc++ // Skip this byte and try to decode again
 			continue
 		}
@@ -125,8 +128,7 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
 				releaseFuncSym.IO_fd_fdID = preContext
 				releaseFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Release)"
 				preInst := preContext.Inst
-				fmt.Println(preInst.Op)
-				fmt.Println((preInst.Args))
+				klog.Infof("[findReleaseAddressInfoFromMem] preInst %v\n]", preInst)
 				// 计算目标地址
 				if preInst.Op == x86asm.MOV &&
 					len(preInst.Args) == 4 &&
@@ -136,31 +138,29 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
 					if mem, ok := preInst.Args[1].(x86asm.Mem); ok && mem.Base == x86asm.RIP {
 						relOffset := mem.Disp // 直接从Mem结构体中读取偏移
 						targetAddress := preContext.SymAddr + uint64(preInst.Len) + uint64(relOffset)
-						fmt.Printf("Target address: 0x%x\n", targetAddress)
+						klog.Infof("[findReleaseAddressInfoFromMem] target address 0x%x\n", targetAddress)
 						releaseFuncSym.IO_fd_fdID.TargetAddr = targetAddress
 					} else {
 						return fmt.Errorf("The instruction does not use RIP-relative addressing.")
 					}
 				} else {
-					return fmt.Errorf("The decoded instruction is not a MOV to RDX.")
+					return fmt.Errorf("[findReleaseAddressInfoFromMem] The decoded instruction is not a MOV to RDX.")
 				}
 
-				//os.Exit(1)
 			}
 			callCount++
 			if callCount == 4 {
 				releaseFuncSym.NET_Send = currentData
-				fmt.Printf("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
-
+				klog.Infof("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
 				relOffset, ok := inst.Args[0].(x86asm.Rel)
 				if !ok {
 					return fmt.Errorf("The instruction does not use RIP-relative addressing.")
 				}
 				targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
 				releaseFuncSym.NET_Send.TargetAddr = targetAddress
-				fmt.Println(releaseFuncSym.NET_Send)
+				klog.Infof("[findReleaseAddressInfoFromMem] target address 0x%x\n", releaseFuncSym.NET_Send)
 				releaseFuncSym.NET_Send.SymName = "<NET_Send>(Release)"
-				fmt.Printf("Target address: 0x%x\n", targetAddress)
+				klog.Infof("[findReleaseAddressInfoFromMem] target address 0x%x\n", targetAddress)
 			}
 		}
 		preContext = InstInfo{
@@ -171,11 +171,12 @@ func (j *JvmInjector) findReleaseAddressInfoFromMem() error {
 		pc += uint64(inst.Len)
 	}
 	j.ReleaseLibNetInfo.InnerSymbol = releaseFuncSym
-	j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:12]
+	j.ReleaseLibNetInfo.FuncSymbol.OriginCode = code[0:ORIGIN_CODE_LEN]
 	return nil
 }
 
 func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
+	klog.Infof("[findDebugAddressInfoFromMem] Looking for debug address info from Mem")
 	funcAbsAddress := j.DebugLibNetInfo.FuncSymbol.SymAddr
 	debugFuncSym := InnerSymbolInfo{}
 	//debugFuncSym.FuncSymbol.SymAddr = funcAbsAddress
@@ -193,7 +194,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 	for pc < uint64(len(code)) {
 		inst, err := x86asm.Decode(code[pc:], 64)
 		if err != nil {
-			fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
+			klog.Errorf("Decode error at offset 0x%x: %v\n", pc, err)
 			pc++ // Skip this byte and try to decode again
 			continue
 		}
@@ -211,7 +212,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 			j.DebugLibNetInfo.FuncSymbol.OriginInst = currentData.Inst
 		}
 		if pc == IO_FD_FDID_SYM_OFFSET {
-			fmt.Printf("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
+			klog.Infof("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
 			debugFuncSym.IO_fd_fdID = currentData
 			debugFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Debug)"
 			// 计算目标地址
@@ -224,7 +225,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 					// 直接从Mem结构体中读取偏移
 					relOffset := mem.Disp
 					targetAddress := currentData.SymAddr + uint64(currentData.Inst.Len) + uint64(relOffset)
-					fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
+					klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
 					debugFuncSym.IO_fd_fdID.TargetAddr = targetAddress
 					// 保存原始数据
 					debugFuncSym.IO_fd_fdID.OriginTargetAddr = targetAddress
@@ -234,12 +235,12 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 					return 0, fmt.Errorf("The instruction does not use RIP-relative addressing.")
 				}
 			} else {
-				return 0, fmt.Errorf("The decoded instruction is not a MOV to RDX.")
+				return 0, fmt.Errorf("[findDebugAddressInfoFromMem] The decoded instruction is not a MOV to RDX.")
 			}
 		}
 		if pc == NET_SEND_SYM_OFFSET {
 			debugFuncSym.NET_Send = currentData
-			fmt.Printf("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
+			klog.Infof("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
 			relOffset, ok := (inst.Args[0].(x86asm.Rel))
 			if !ok {
 				return 0, fmt.Errorf("The decoded instruction is not a Rel.")
@@ -247,7 +248,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 			targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
 			debugFuncSym.NET_Send.TargetAddr = targetAddress
 			debugFuncSym.NET_Send.SymName = "<NET_Send>(Debug)"
-			fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
+			klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
 
 			// 保存原始数据
 			debugFuncSym.NET_Send.OriginTargetAddr = targetAddress
@@ -268,6 +269,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 }
 
 func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
+	klog.Infof("Checking debug function symbol after injection")
 	funcAbsAddress := j.DebugLibNetInfo.FuncSymbol.SymAddr
 	debugFuncSym := InnerSymbolInfo{}
 	code, err := j.readMemory(funcAbsAddress, j.DebugLibNetInfo.FuncSymbol.SymSize)
@@ -281,7 +283,7 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
 	for pc < uint64(len(code)) {
 		inst, err := x86asm.Decode(code[pc:], 64)
 		if err != nil {
-			fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
+			klog.Infof("Decode error at offset 0x%x: %v\n", pc, err)
 			pc++ // Skip this byte and try to decode again
 			continue
 		}
@@ -294,7 +296,7 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
 			Inst:    inst,
 		}
 		if pc == NET_SEND_SYM_OFFSET {
-			fmt.Printf("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
+			klog.Infof("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
 			debugFuncSym.IO_fd_fdID = currentData
 			debugFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Debug)"
 			// 计算目标地址
@@ -307,7 +309,7 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
 					// 直接从Mem结构体中读取偏移
 					relOffset := mem.Disp
 					targetAddress := currentData.SymAddr + uint64(currentData.Inst.Len) + uint64(relOffset)
-					fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
+					klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
 					debugFuncSym.IO_fd_fdID.TargetAddr = targetAddress
 					//j.PreCheck.IoFdCheck = true
 
@@ -315,19 +317,19 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
 						j.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.TargetAddr = targetAddress
 						j.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.Inst = currentData.Inst
 						j.AfterCheck.IoFdCheck = true
-						fmt.Println("ok")
+						klog.Infoln("ok")
 					}
 				} else {
 					return 0, fmt.Errorf("The instruction does not use RIP-relative addressing.")
 				}
 			} else {
-				return 0, fmt.Errorf("The decoded instruction is not a MOV to RDX.")
+				return 0, fmt.Errorf("[checkDebugFuncSymAfterChange] The decoded instruction is not a MOV to RDX.")
 			}
 		}
 		if pc == NET_SEND_SYM_OFFSET {
 			debugFuncSym.NET_Send = currentData
 			//fmt.Println(currentData.IntelInst)
-			//fmt.Printf("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
+			//klog.Infof("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
 			relOffset, ok := (inst.Args[0].(x86asm.Rel))
 			if !ok {
 				return 0, fmt.Errorf("The decoded instruction is not a Rel.")
@@ -335,7 +337,7 @@ func (j *JvmInjector) checkDebugFuncSymAfterChange() (uint64, error) {
 			targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
 			debugFuncSym.NET_Send.TargetAddr = targetAddress
 			debugFuncSym.NET_Send.SymName = "<NET_Send>(Debug)"
-			fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
+			klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
 
 			if targetAddress == j.ReleaseLibNetInfo.InnerSymbol.NET_Send.TargetAddr {
 				j.DebugLibNetInfo.InnerSymbol.NET_Send.TargetAddr = targetAddress
@@ -360,7 +362,7 @@ func (j *JvmInjector) checkReleaseFuncSymAfterChange() error {
 	if err != nil {
 		return fmt.Errorf("readMemory error in checkReleaseFuncSymAfterChange <%v>", err)
 	}
-	
+
 	// 原函数内容注释掉
 	// inst, err := x86asm.Decode(code[0:], 64)
 	// if err != nil {
@@ -378,35 +380,35 @@ func (j *JvmInjector) checkReleaseFuncSymAfterChange() error {
 	// if targetAddress != j.DebugLibNetInfo.FuncSymbol.SymAddr {
 	// 	return fmt.Errorf("Function entry jmp address does not match expectations.")
 	// }
-	
+
 	// 新的验证逻辑:验证指令序列:movabs $imm64,%rax 和 jmp *%rax
 	if len(code) < 13 { // movabs(10字节) + jmp(3字节) = 13字节
 		return fmt.Errorf("Instruction sequence too short, expected at least 13 bytes, got %d", len(code))
 	}
-	
+
 	// 验证第一个指令:movabs $imm64,%rax
 	// movabs 指令格式:48 B8 + 8字节立即数 (RAX寄存器)
 	// 48 B8 = movabs rax, imm64
 	if code[0] != 0x48 || code[1] != 0xB8 {
 		return fmt.Errorf("First instruction is not movabs rax, imm64. Got: 0x%02x 0x%02x", code[0], code[1])
 	}
-	
+
 	// 提取立即数值 (小端序)
 	imm64 := uint64(code[2]) | uint64(code[3])<<8 | uint64(code[4])<<16 | uint64(code[5])<<24 |
-		     uint64(code[6])<<32 | uint64(code[7])<<40 | uint64(code[8])<<48 | uint64(code[9])<<56
-	
+		uint64(code[6])<<32 | uint64(code[7])<<40 | uint64(code[8])<<48 | uint64(code[9])<<56
+
 	// 验证立即数是否与 Debug 函数地址一致
 	expectedAddr := j.DebugLibNetInfo.FuncSymbol.SymAddr
 	if imm64 != expectedAddr {
 		return fmt.Errorf("movabs immediate value mismatch. Expected: 0x%x (Debug function addr), Got: 0x%x", expectedAddr, imm64)
 	}
-	
+
 	// 验证第二个指令:jmp *%rax
 	// jmp *%rax 指令格式:FF E0
 	if code[10] != 0xFF || code[11] != 0xE0 {
 		return fmt.Errorf("Second instruction is not jmp *%%rax. Got: 0x%02x 0x%02x", code[10], code[11])
 	}
-	
+
 	klog.Infof("[checkReleaseFuncSymAfterChange] Successfully verified instruction sequence: movabs $0x%x,%%rax; jmp *%%rax", imm64)
 	return nil
 }
@@ -666,27 +668,27 @@ func (j *JvmInjector) findDebugFuncContextFromLibPath() error {
 	if err != nil {
 		return fmt.Errorf("Error finding first CALL instuction: %v", err)
 	}
-	fmt.Printf("First CALL instuction o1f %s at base 0x%x\n", functionName, baseAddress)
+	klog.Infof("First CALL instuction o1f %s at base 0x%x\n", functionName, baseAddress)
 	return nil
 }
 
 func printCodeData(data LibNetInfo) {
-	fmt.Printf("========FuncEnter <0x%x> \n", data.FuncSymbol.SymAddr)
-	fmt.Printf("Name %s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x> \nOrigin-Inst:<%s> | Inst:<%s> \n",
+	klog.Infof("========FuncEnter <0x%x> \n", data.FuncSymbol.SymAddr)
+	klog.Infof("Name %s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x> \nOrigin-Inst:<%s> | Inst:<%s> \n",
 		data.InnerSymbol.IO_fd_fdID.SymName,
 		data.InnerSymbol.IO_fd_fdID.SymAddr,
 		data.InnerSymbol.IO_fd_fdID.OriginTargetAddr,
 		data.InnerSymbol.IO_fd_fdID.TargetAddr,
 		x86asm.IntelSyntax(data.InnerSymbol.IO_fd_fdID.OriginInst, 0, nil),
 		x86asm.IntelSyntax(data.InnerSymbol.IO_fd_fdID.Inst, 0, nil))
-	fmt.Printf("\nName %s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x>\nOrigin-Inst:<%s> | Inst:<%s> \n",
+	klog.Infof("\nName %s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x>\nOrigin-Inst:<%s> | Inst:<%s> \n",
 		data.InnerSymbol.NET_Send.SymName,
 		data.InnerSymbol.NET_Send.SymAddr,
 		data.InnerSymbol.NET_Send.OriginTargetAddr,
 		data.InnerSymbol.NET_Send.TargetAddr,
 		x86asm.IntelSyntax(data.InnerSymbol.NET_Send.OriginInst, 0, nil),
 		x86asm.IntelSyntax(data.InnerSymbol.NET_Send.Inst, 0, nil))
-	fmt.Println("========")
+	klog.Infoln("========")
 }
 
 func (j *JvmInjector) jvmInjectLib() int {
@@ -694,7 +696,7 @@ func (j *JvmInjector) jvmInjectLib() int {
 	rootfs := C.CString(j.Rootfs)
 	defer C.free(unsafe.Pointer(dll))
 	result := C.cw_inject_library(C.int(j.Pid), C.int(1), dll, rootfs)
-	fmt.Printf("Result: %d\n", result)
+	klog.Infof("Result: %d\n", result)
 	return int(result)
 }
 
@@ -755,8 +757,7 @@ func modifyIoFdTargetAddr(pid int, insertAddr, distAddr, getTTLFunctionAddr uint
 
 	getTTLOffset := getTTLFunctionAddr - insertAddr - 5
 
-
-	// 读取原始数据 
+	// 读取原始数据
 	// alignedAddr := insertAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
 	originalData, err := readDataBytes(pid, insertAddr, 7)
 	if err != nil {
@@ -768,13 +769,13 @@ func modifyIoFdTargetAddr(pid int, insertAddr, distAddr, getTTLFunctionAddr uint
 
 	// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
 	var getTTLOffset32 uint32 = uint32(getTTLOffset)
-	originalData[offset] = 0xE8                   // call 
+	originalData[offset] = 0xE8 // call
 	originalData[offset+1] = byte(getTTLOffset32)
 	originalData[offset+2] = byte(getTTLOffset32 >> 8)
 	originalData[offset+3] = byte(getTTLOffset32 >> 16)
 	originalData[offset+4] = byte(getTTLOffset32 >> 24)
-	originalData[offset+5] = 0x90				//nop
-	originalData[offset+6] = 0x90				//nop
+	originalData[offset+5] = 0x90 //nop
+	originalData[offset+6] = 0x90 //nop
 
 	err = writeDataBytes(pid, insertAddr, originalData)
 	if err != nil {
@@ -803,8 +804,8 @@ func modifyIoFdTargetAddr(pid int, insertAddr, distAddr, getTTLFunctionAddr uint
 	TTLOriginalData[offset+11] = 0x48
 	TTLOriginalData[offset+12] = 0x8b
 	TTLOriginalData[offset+13] = 0x10
-	TTLOriginalData[offset+14] = 0x58				//pop rax
-	TTLOriginalData[offset+15] = 0xc3				//ret
+	TTLOriginalData[offset+14] = 0x58 //pop rax
+	TTLOriginalData[offset+15] = 0xc3 //ret
 
 	err = writeDataBytes(pid, getTTLFunctionAddr, TTLOriginalData)
 	if err != nil {
@@ -835,8 +836,7 @@ func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr, convert0Fun
 
 	convert0Offset := convert0FunctionAddr - sendDebugAddr - 5
 
-
-	// 读取原始数据 
+	// 读取原始数据
 	// alignedAddr := insertAddr & ^(uintptr(unsafe.Sizeof(uintptr(0))) - 1)
 	originalData, err := readDataBytes(pid, sendDebugAddr, 5)
 	if err != nil {
@@ -848,7 +848,7 @@ func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr, convert0Fun
 
 	// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
 	var convert0Offset32 uint32 = uint32(convert0Offset)
-	originalData[offset] = 0xE8                   // call 
+	originalData[offset] = 0xE8 // call
 	originalData[offset+1] = byte(convert0Offset32)
 	originalData[offset+2] = byte(convert0Offset32 >> 8)
 	originalData[offset+3] = byte(convert0Offset32 >> 16)
@@ -859,7 +859,6 @@ func modifyNetSetTargetAddr(pid int, sendDebugAddr, sendReleaseAddr, convert0Fun
 		return err
 	}
 
-
 	convert0OriginalData, err := readDataBytes(pid, convert0FunctionAddr, 13)
 	if err != nil {
 		return err
@@ -916,10 +915,10 @@ func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) er
 	}
 
 	offset := originEnterAddr % uintptr(unsafe.Sizeof(uintptr(0)))
-	
+
 	// 写入AMD64的绝对跳转指令: mov rax, addr; jmp rax
-	originalData[offset] = 0x48                    // REX.W prefix
-	originalData[offset+1] = 0xb8                  // mov rax, imm64
+	originalData[offset] = 0x48   // REX.W prefix
+	originalData[offset+1] = 0xb8 // mov rax, imm64
 	// 按小端序写入64位地址
 	originalData[offset+2] = byte(debugEnterAddr)
 	originalData[offset+3] = byte(debugEnterAddr >> 8)
@@ -929,7 +928,7 @@ func modifyReleaseFuncEnter(pid int, originEnterAddr, debugEnterAddr uintptr) er
 	originalData[offset+7] = byte(debugEnterAddr >> 40)
 	originalData[offset+8] = byte(debugEnterAddr >> 48)
 	originalData[offset+9] = byte(debugEnterAddr >> 56)
-	originalData[offset+10] = 0xff                 // jmp rax
+	originalData[offset+10] = 0xff // jmp rax
 	originalData[offset+11] = 0xe0
 
 	err = writeDataBytes(pid, alignedAddr, originalData)
@@ -1075,24 +1074,23 @@ func JvmInject(jvmInjector *JvmInjector) error {
 	ioFdReleaseTargetAddr := uintptr(jvmInjector.ReleaseLibNetInfo.InnerSymbol.IO_fd_fdID.TargetAddr)
 	netSendReleaseTargetAddr := uintptr(jvmInjector.ReleaseLibNetInfo.InnerSymbol.NET_Send.TargetAddr)
 
-	fmt.Printf("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
-	fmt.Printf("<0x%x> -> <0x%x>\n", debugIoFdAddr, ioFdReleaseTargetAddr)
-	fmt.Printf("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
-	fmt.Printf("conver0 -> <0x%x>\n", debugFuncConvert0EnterAddr)
-	fmt.Printf("getttl -> <0x%x>\n", debugFuncGetTTLEnterAddr)
-	
+	klog.Infof("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
+	klog.Infof("<0x%x> -> <0x%x>\n", debugIoFdAddr, ioFdReleaseTargetAddr)
+	klog.Infof("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
+	klog.Infof("conver0 -> <0x%x>\n", debugFuncConvert0EnterAddr)
+	klog.Infof("getttl -> <0x%x>\n", debugFuncGetTTLEnterAddr)
 
 	// 附加到目标进程
 	klog.Infof("attach")
 	err = syscall.PtraceAttach(pid)
 	if err != nil {
-		fmt.Printf("ptrace ATTACH: %v", err)
+		klog.Errorf("ptrace ATTACH: %v", err)
 	}
 
 	// 等待目标进程停止
 	klog.Infof("attach Wait")
 	if _, err := syscall.Wait4(pid, nil, 0, nil); err != nil {
-		fmt.Printf("wait4: %v", err)
+		klog.Errorf("wait4: %v", err)
 		return err
 	}
 	//time.Now().UnixNano()
@@ -1125,6 +1123,16 @@ func JvmInject(jvmInjector *JvmInjector) error {
 	}
 	// 更新函数入口
 	klog.Infof("modifyReleaseFuncEnter")
+	// 计算地址差
+	diff := originFuncEnterAddr - debugFuncEnterAddr
+	if diff < 0 {
+		diff = -diff
+	}
+	// 检查是否超过 2GB
+	if diff > (1 << 31) {
+		klog.Infof("[inject] originFuncEnterAddr(0x%x) and debugFuncEnterAddr(0x%x) distance > 2GB",
+			originFuncEnterAddr, debugFuncEnterAddr)
+	}
 	err = modifyReleaseFuncEnter(pid, originFuncEnterAddr, debugFuncEnterAddr)
 	if err != nil {
 		klog.WithError(err).Errorf("[inject] failed modifyReleaseFuncEnter")
@@ -1137,7 +1145,7 @@ func JvmInject(jvmInjector *JvmInjector) error {
 	if errReleaseFuncSymAfterChange != nil {
 		klog.WithError(errReleaseFuncSymAfterChange).Errorf("[inject] failed checkReleaseFuncSymAfterChange")
 		// 回滚
-		if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == 12 {
+		if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == ORIGIN_CODE_LEN {
 			err = restoreOriginalInstructions(pid, originFuncEnterAddr, jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode)
 			if err != nil {
 				klog.WithError(err).Errorf("[inject] failed restoreOriginalInstructions")

+ 46 - 46
ebpftracer/tracer/inject/inject_linux_arm64.go

@@ -308,7 +308,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 	//offset := sym.Value
 	size := j.DebugLibNetInfo.FuncSymbol.SymSize
 	code, err := j.readMemory(funcAbsAddress, size)
-	//fmt.Println(code, err)
+	//klog.Infoln(code, err)
 	if err != nil {
 		return 0, err
 	}
@@ -319,13 +319,13 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 	for pc < uint64(len(code)) {
 		inst, err := arm64asm.Decode(code[pc:])
 		if err != nil {
-			fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
+			klog.Infof("Decode error at offset 0x%x: %v\n", pc, err)
 			pc++ // Skip this byte and try to decode again
 			continue
 		}
-		//fmt.Printf("Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, Inst)
-		//fmt.Printf("Decoded x86 instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.IntelSyntax(inst, 0, nil))
-		//fmt.Printf("Decoded GNU instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.GNUSyntax(Inst, 0, nil))
+		//klog.Infof("Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, Inst)
+		//klog.Infof("Decoded x86 instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.IntelSyntax(inst, 0, nil))
+		//klog.Infof("Decoded GNU instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.GNUSyntax(Inst, 0, nil))
 		currentData := InstInfo{
 			PC:      pc,
 			SymAddr: funcAbsAddress + pc,
@@ -374,17 +374,17 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 		}
 		if pc == NET_SEND_SYM_OFFSET {
 			debugFuncSym.NET_Send = currentData
-			//fmt.Printf("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
+			//klog.Infof("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
 			//relOffset, ok := (inst.Args[0].(x86asm.Rel))
-			fmt.Println(inst)
-			fmt.Println(inst.Args)
+			klog.Infoln(inst)
+			klog.Infoln(inst.Args)
 			//if !ok {
 			//	return 0, fmt.Errorf("The decoded instruction is not a Rel.")
 			//}
 			//targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
 			//debugFuncSym.NET_Send.TargetAddr = targetAddress
 			debugFuncSym.NET_Send.SymName = "<NET_Send>(Debug)"
-			//fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
+			//klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
 			//
 			//// 保存原始数据
 			//debugFuncSym.NET_Send.OriginTargetAddr = targetAddress
@@ -418,20 +418,20 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 //	for pc < uint64(len(code)) {
 //		inst, err := x86asm.Decode(code[pc:], 64)
 //		if err != nil {
-//			fmt.Printf("Decode error at offset 0x%x: %v\n", pc, err)
+//			klog.Infof("Decode error at offset 0x%x: %v\n", pc, err)
 //			pc++ // Skip this byte and try to decode again
 //			continue
 //		}
-//		//fmt.Printf("Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, Inst)
-//		//fmt.Printf("Decoded x86 instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.IntelSyntax(inst, 0, nil))
-//		//fmt.Printf("Decoded GNU instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.GNUSyntax(Inst, 0, nil))
+//		//klog.Infof("Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, Inst)
+//		//klog.Infof("Decoded x86 instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.IntelSyntax(inst, 0, nil))
+//		//klog.Infof("Decoded GNU instuction at 0x%x: %v\n", funcAbsAddress+pc, x86asm.GNUSyntax(Inst, 0, nil))
 //		currentData := InstInfo{
 //			PC:      pc,
 //			SymAddr: funcAbsAddress + pc,
 //			Inst:    inst,
 //		}
 //		if pc == NET_SEND_SYM_OFFSET {
-//			fmt.Printf("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
+//			klog.Infof("Instuction at 0x%x: %v\n", preContext.PC, preContext.Inst)
 //			debugFuncSym.IO_fd_fdID = currentData
 //			debugFuncSym.IO_fd_fdID.SymName = "<IO_fd_fdID>(Debug)"
 //			// 计算目标地址
@@ -444,7 +444,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 //					// 直接从Mem结构体中读取偏移
 //					relOffset := mem.Disp
 //					targetAddress := currentData.SymAddr + uint64(currentData.Inst.Len) + uint64(relOffset)
-//					fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
+//					klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.IO_fd_fdID.SymName, targetAddress)
 //					debugFuncSym.IO_fd_fdID.TargetAddr = targetAddress
 //					//j.PreCheck.IoFdCheck = true
 //
@@ -452,7 +452,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 //						j.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.TargetAddr = targetAddress
 //						j.DebugLibNetInfo.InnerSymbol.IO_fd_fdID.Inst = currentData.Inst
 //						j.AfterCheck.IoFdCheck = true
-//						fmt.Println("ok")
+//						klog.Infoln("ok")
 //					}
 //				} else {
 //					return 0, fmt.Errorf("The instruction does not use RIP-relative addressing.")
@@ -463,8 +463,8 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 //		}
 //		if pc == NET_SEND_SYM_OFFSET {
 //			debugFuncSym.NET_Send = currentData
-//			//fmt.Println(currentData.IntelInst)
-//			//fmt.Printf("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
+//			//klog.Infoln(currentData.IntelInst)
+//			//klog.Infof("4 call Decoded instuction at 0x%x: %v\n", funcAbsAddress+pc, inst)
 //			relOffset, ok := (inst.Args[0].(x86asm.Rel))
 //			if !ok {
 //				return 0, fmt.Errorf("The decoded instruction is not a Rel.")
@@ -472,7 +472,7 @@ func (j *JvmInjector) findDebugAddressInfoFromMem() (uint64, error) {
 //			targetAddress := currentData.SymAddr + uint64(inst.Len) + uint64(relOffset)
 //			debugFuncSym.NET_Send.TargetAddr = targetAddress
 //			debugFuncSym.NET_Send.SymName = "<NET_Send>(Debug)"
-//			fmt.Printf("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
+//			klog.Infof("Find %s Target address: 0x%x\n", debugFuncSym.NET_Send.SymName, targetAddress)
 //
 //			if targetAddress == j.ReleaseLibNetInfo.InnerSymbol.NET_Send.TargetAddr {
 //				j.DebugLibNetInfo.InnerSymbol.NET_Send.TargetAddr = targetAddress
@@ -579,7 +579,7 @@ func (j *JvmInjector) findLibBaseFromProcMaps(libName string) (uint64, string, e
 			if len(fields) > 5 {
 				path := fields[5]
 				if strings.HasSuffix(path, ".so") {
-					fmt.Printf("Found library %s\n", path)
+					klog.Infof("Found library %s\n", path)
 					return start, path, nil
 				}
 			}
@@ -609,12 +609,12 @@ func (j *JvmInjector) findLibBaseFromProcMaps(libName string) (uint64, string, e
 //
 //	//textSection := elfFile.Section(".text")
 //	//if textSection == nil {
-//	//	fmt.Println("textSection is null")
+//	//	klog.Infoln("textSection is null")
 //	//	//return nil
 //	//}
 //	//textSectionData, err := textSection.Data()
 //	//if err != nil {
-//	//	fmt.Println("textSectionData error is", err)
+//	//	klog.Infoln("textSectionData error is", err)
 //	//	//return nil
 //	//}
 //	//textSectionLen := uint64(len(textSectionData) - 1)
@@ -633,7 +633,7 @@ func (j *JvmInjector) findLibBaseFromProcMaps(libName string) (uint64, string, e
 //	if err != nil {
 //		return fmt.Errorf("Error finding base addresses: %v", err)
 //	}
-//	fmt.Printf("Base address of (%s)%s: %x\n", "", libName, baseAddress)
+//	klog.Infof("Base address of (%s)%s: %x\n", "", libName, baseAddress)
 //
 //	// 获取函数的偏移量
 //	functionSym, err := j.getFunctionOffset(libPath, functionName)
@@ -644,7 +644,7 @@ func (j *JvmInjector) findLibBaseFromProcMaps(libName string) (uint64, string, e
 //	if err != nil {
 //		return fmt.Errorf("Error getting function offset: %v", err)
 //	}
-//	fmt.Printf("Actual memory address of %s at base 0x%x: 0x%x\n", functionName, baseAddress, j.ReleaseLibNetInfo.FuncSymbol.SymAddr)
+//	klog.Infof("Actual memory address of %s at base 0x%x: 0x%x\n", functionName, baseAddress, j.ReleaseLibNetInfo.FuncSymbol.SymAddr)
 //	err = j.findReleaseAddressInfoFromMem()
 //
 //	if err != nil {
@@ -773,8 +773,8 @@ func (j *JvmInjector) findDebugFuncContextFromLibPath() error {
 	if err != nil {
 		return fmt.Errorf("Error getting recode function:[%s] error: %v", j.RecodeInfo.FuncSymbol.SymName, err)
 	}
-	//fmt.Printf("DEBUG Actual memory address of %s at base 0x%x: 0x%x\n", functionName, baseAddress, j.DebugLibNetInfo.FuncSymbol.SymAddr)
-	//fmt.Printf("DEBUG Actual memory address of %s at base 0x%x: 0x%x\n", j.RecodeInfo.FuncSymbol.SymName, baseAddress, j.RecodeInfo.FuncSymbol.SymAddr)
+	//klog.Infof("DEBUG Actual memory address of %s at base 0x%x: 0x%x\n", functionName, baseAddress, j.DebugLibNetInfo.FuncSymbol.SymAddr)
+	//klog.Infof("DEBUG Actual memory address of %s at base 0x%x: 0x%x\n", j.RecodeInfo.FuncSymbol.SymName, baseAddress, j.RecodeInfo.FuncSymbol.SymAddr)
 
 	//_, err = j.findDebugAddressInfoFromMem()
 	//if err != nil {
@@ -784,29 +784,29 @@ func (j *JvmInjector) findDebugFuncContextFromLibPath() error {
 }
 
 func printCodeData(data LibNetInfo) {
-	fmt.Printf("========FuncEnter <0x%x> \n", data.FuncSymbol.SymAddr)
-	//fmt.Printf("%s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x> \nOrigin-Enc:<0x%x> | TargetEnc:<0x%x> \n",
+	klog.Infof("========FuncEnter <0x%x> \n", data.FuncSymbol.SymAddr)
+	//klog.Infof("%s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x> \nOrigin-Enc:<0x%x> | TargetEnc:<0x%x> \n",
 	//	data.InnerSymbol.IO_fd_fdID_ADRP.SymName,
 	//	data.InnerSymbol.IO_fd_fdID_ADRP.SymAddr,
 	//	data.InnerSymbol.IO_fd_fdID_ADRP.OriginTargetAddr,
 	//	data.InnerSymbol.IO_fd_fdID_ADRP.TargetAddr,
 	//	data.InnerSymbol.IO_fd_fdID_ADRP.OriginEnc,
 	//	data.InnerSymbol.IO_fd_fdID_ADRP.TargetEnc)
-	//fmt.Printf("\n%s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x> \nOrigin-Enc:<0x%x> | TargetEnc:<0x%x> \n",
+	//klog.Infof("\n%s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x> \nOrigin-Enc:<0x%x> | TargetEnc:<0x%x> \n",
 	//	data.InnerSymbol.IO_fd_fdID_ADD.SymName,
 	//	data.InnerSymbol.IO_fd_fdID_ADD.SymAddr,
 	//	data.InnerSymbol.IO_fd_fdID_ADD.OriginTargetAddr,
 	//	data.InnerSymbol.IO_fd_fdID_ADD.TargetAddr,
 	//	data.InnerSymbol.IO_fd_fdID_ADD.OriginEnc,
 	//	data.InnerSymbol.IO_fd_fdID_ADD.TargetEnc)
-	//fmt.Printf("\n%s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x>\nOrigin-Inst:<%s> | Inst:<%s> \n",
+	//klog.Infof("\n%s | CurrentAddr:<0x%x>\nOrigin-TargetAddr:<0x%x> | TargetAddr:<0x%x>\nOrigin-Inst:<%s> | Inst:<%s> \n",
 	//	data.InnerSymbol.NET_Send.SymName,
 	//	data.InnerSymbol.NET_Send.SymAddr,
 	//	data.InnerSymbol.NET_Send.OriginTargetAddr,
 	//	data.InnerSymbol.NET_Send.TargetAddr,
 	//	arm64asm.GNUSyntax(data.InnerSymbol.NET_Send.OriginInst),
 	//	arm64asm.GNUSyntax(data.InnerSymbol.NET_Send.Inst))
-	fmt.Println("========")
+	klog.Infoln("========")
 }
 
 func (j *JvmInjector) jvmInjectLib() int {
@@ -885,7 +885,7 @@ func buildCwNopEnc(pid int, nopAddr, originAddr uintptr) error {
 	if err != nil {
 		return err
 	}
-	fmt.Printf("0x%016x\n", originalData) // 16个字符宽度,左边补0
+	klog.Infof("0x%016x\n", originalData) // 16个字符宽度,左边补0
 
 	if originalData != 0xd503201f {
 		return fmt.Errorf("The cw enc not nop <0x%016x>\n", originAddr)
@@ -1129,7 +1129,7 @@ func modifyOriginEnc(pid int, trampolineAddr uint64, origin uintptr, recode uint
 	//	return err
 	//}
 
-	fmt.Printf("# blr x18 \nset *(unsigned int*)($origin+%d) = 0x%08x\n", PC_START+4*4, 0xD63F0240)
+	klog.Infof("# blr x18 \nset *(unsigned int*)($origin+%d) = 0x%08x\n", PC_START+4*4, 0xD63F0240)
 	return nil
 }
 
@@ -1138,7 +1138,7 @@ func buildArm64Enc(imm16, hw uint64) uint64 {
 	fixed := 0x1e5
 	// Combine all parts into a single 32-bit value
 	result := uint64(rd<<0) | (imm16 << 5) | (hw << 21) | uint64(fixed<<23)
-	fmt.Printf("set *(unsigned int*)($origin+%d) = 0x%08x\n", PC_START+hw*4, result)
+	klog.Infof("set *(unsigned int*)($origin+%d) = 0x%08x\n", PC_START+hw*4, result)
 	return result
 }
 
@@ -1236,7 +1236,7 @@ func restoreOriginalInstructions(pid int, addr uintptr, instructions []byte) err
 //	}
 //
 //	err = jvmInject(jvmInjector)
-//	fmt.Println(err)
+//	klog.Infoln(err)
 //}
 
 func JvmInject(jvmInjector *JvmInjector) error {
@@ -1248,7 +1248,7 @@ func JvmInject(jvmInjector *JvmInjector) error {
 
 	//err = jvmInjector.findReleaseFuncContextFromLibPath()
 
-	//fmt.Println(err)
+	//klog.Infoln(err)
 	// Debug版本无需修改寄存器  TODO 直接使用原函数 需要在ebpf层适配
 	// 已经加载so并指令修改正确的
 	if jvmInjector.PreCheck.EbpfCanInjection {
@@ -1314,16 +1314,16 @@ func JvmInject(jvmInjector *JvmInjector) error {
 	debugFuncEnterAddr := uintptr(jvmInjector.DebugLibNetInfo.FuncSymbol.SymAddr)
 	originFuncEnterAddr := uintptr(jvmInjector.ReleaseLibNetInfo.FuncSymbol.SymAddr)
 	recodeFuncEnterAddr := uintptr(jvmInjector.RecodeInfo.FuncSymbol.SymAddr)
-	//fmt.Printf("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
-	//fmt.Printf("<0x%x> -> <0x%x>\n", debugIoFdAddr, ioFdReleaseTargetAddr)
-	//fmt.Printf("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
+	//klog.Infof("<0x%x> -> <0x%x>\n", originFuncEnterAddr, debugFuncEnterAddr)
+	//klog.Infof("<0x%x> -> <0x%x>\n", debugIoFdAddr, ioFdReleaseTargetAddr)
+	//klog.Infof("<0x%x> -> <0x%x>\n", debugNetSendAddr, netSendReleaseTargetAddr)
 	//
 	// 附加到目标进程
 	klog.Infof("[inject] %d attach", pid)
 
 	err = syscall.PtraceAttach(pid)
 	if err != nil {
-		fmt.Printf("ptrace ATTACH: %v", err)
+		klog.Infof("ptrace ATTACH: %v", err)
 	}
 	//
 	// 等待目标进程停止
@@ -1336,15 +1336,15 @@ func JvmInject(jvmInjector *JvmInjector) error {
 	klog.Infof("[inject] %d build cw enc", pid)
 	err = buildCwNopEnc(pid, debugFuncEnterAddr, originFuncEnterAddr)
 	if err != nil {
-		fmt.Println(err)
+		klog.Errorln(err)
 		return err
 	}
 
 	//
 	//err = modifyNetSetTargetAddr(pid, debugNetSendAddr, netSendReleaseTargetAddr)
-	//fmt.Println(err)
+	//klog.Infoln(err)
 	//if err != nil {
-	//	fmt.Println(err)
+	//	klog.Infoln(err)
 	//	return err
 	//}
 	// todo 二次效验 读取并验证地址
@@ -1364,17 +1364,17 @@ func JvmInject(jvmInjector *JvmInjector) error {
 	//// 更新函数入口
 	//err = modifyReleaseFuncEnter(pid, originFuncEnterAddr, debugFuncEnterAddr)
 	//if err != nil {
-	//	fmt.Println(err)
+	//	klog.Infoln(err)
 	//	return err
 	//}
 	//// 校验jmp地址修改正确
 	//err = jvmInjector.checkReleaseFuncSymAfterChange()
 	//if err != nil {
-	//	fmt.Println(err)
+	//	klog.Infoln(err)
 	//	if len(jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode) == 5 {
 	//		err = restoreOriginalInstructions(pid, originFuncEnterAddr, jvmInjector.ReleaseLibNetInfo.FuncSymbol.OriginCode)
 	//		if err != nil {
-	//			fmt.Println(err)
+	//			klog.Infoln(err)
 	//			return err
 	//		}
 	//	}

+ 16 - 67
flags/flags.go

@@ -1,25 +1,23 @@
 package flags
 
 import (
-	"encoding/json"
 	"fmt"
-	"github.com/common-nighthawk/go-figure"
-	"github.com/coroot/coroot-node-agent/utils"
-	"github.com/coroot/coroot-node-agent/utils/modelse"
-	"github.com/jedib0t/go-pretty/v6/table"
-	"gopkg.in/alecthomas/kingpin.v2"
-	"gopkg.in/ini.v1"
 	"net/url"
 	"os"
-	"path"
 	"strings"
+
+	"github.com/common-nighthawk/go-figure"
+	"gopkg.in/alecthomas/kingpin.v2"
+	"gopkg.in/ini.v1"
 )
 
 var (
 	// apm
 	ConfigServer        = kingpin.Flag("config-server", "The URL of the endpoint to send traces to").Envar("CONFIG_SERVER").Default("http://10.0.16.250:18080").String()
 	DataServer          = kingpin.Flag("data-server", "The URL of the endpoint to send traces to").Envar("DATA_SERVER").Default("http://10.0.16.250:18080").String()
-	DumpApps            = kingpin.Flag("dump", "Dump app snap").Default("false").Bool()
+	DumpApps            = kingpin.Flag("dump", "Dump app snap").Short('d').Default("false").Bool()
+	DumpRules           = kingpin.Flag("dr", "Dump rule snap").Default("false").Bool()
+	PrintFormat         = kingpin.Flag("print", "Output format (table|json)").Default("table").String()
 	Version             = kingpin.Flag("version", "show app version").Short('v').Bool()
 	LogLevel            = kingpin.Flag("log-level", "Log level").Envar("LOG_LEVEL").Default("info").String()
 	ConsoleLog          = kingpin.Flag("console-log", "Console log").Envar("CONSOLE_LOG").Default("false").Bool()
@@ -36,15 +34,15 @@ var (
 
 	ListenAddress     = kingpin.Flag("listen", "Listen address - ip:port or :port").Default("0.0.0.0:8123").Envar("LISTEN").String()
 	CgroupRoot        = kingpin.Flag("cgroupfs-root", "The mount point of the host cgroupfs root").Default("/sys/fs/cgroup").Envar("CGROUPFS_ROOT").String()
-	DisableLogParsing = kingpin.Flag("disable-log-parsing", "Disable container log parsing").Default("false").Envar("DISABLE_LOG_PARSING").Bool()
+	DisableLogParsing = kingpin.Flag("disable-log-parsing", "Disable container log parsing").Default("true").Envar("DISABLE_LOG_PARSING").Bool()
 	DisablePinger     = kingpin.Flag("disable-pinger", "Don't ping upstreams").Default("false").Envar("DISABLE_PINGER").Bool()
 	DisableL7Tracing  = kingpin.Flag("disable-l7-tracing", "Disable L7 tracing").Default("false").Envar("DISABLE_L7_TRACING").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").
-					Default("0.0.0.0/0").
-					Strings()
+		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").
+		Default("0.0.0.0/0").
+		Strings()
 	EphemeralPortRange = kingpin.Flag("ephemeral-port-range", "Destination and Listen TCP ports from this range will be skipped").Default("").Envar("EPHEMERAL_PORT_RANGE").String()
 
 	Provider          = kingpin.Flag("provider", "`provider` label for `node_cloud_info` metric").Envar("PROVIDER").String()
@@ -102,7 +100,10 @@ func init() {
 		ShowVersion()
 	}
 	if *DumpApps {
-		DumpTableFeatures()
+		DumpTableFeatures(*PrintFormat)
+	}
+	if *DumpRules {
+		DumpRuleTableFeatures(*PrintFormat)
 	}
 	if *CollectorEndpoint != nil {
 		u := *CollectorEndpoint
@@ -172,58 +173,6 @@ func init() {
 	}
 }
 
-func DumpTableFeatures() {
-	dumpPath := path.Join(utils.GetDefaultRuntimePath(), "memdump")
-	fileName := path.Join(dumpPath, "app.snap")
-	content, err := os.ReadFile(fileName)
-	if err != nil {
-		fmt.Println(err.Error())
-	}
-
-	s := make(map[uint32]modelse.AppStatusInfo)
-	err = json.Unmarshal(content, &s)
-	if err != nil {
-		fmt.Println(err.Error())
-	}
-	t := table.NewWriter()
-	for pid, info := range s {
-		service := fmt.Sprintf("%s", info.Sn)
-		t.AppendRow(table.Row{
-			//info.AgentID,
-			//info.UpdateAt,
-			pid,
-			info.ProcName,
-			info.AppName,
-			info.Rule,
-			info.Language,
-			service,
-			info.AppID,
-			info.RegisterAt,
-			info.PreStatus.String(),
-			info.Status.String(),
-			info.StackStatus,
-		})
-	}
-	t.SetAutoIndex(true)
-	t.AppendHeader(table.Row{
-		//"agent id",
-		//"update at",
-		"pid",
-		"process",
-		"app name",
-		"app rule",
-		"code",
-		"service",
-		"app id",
-		"reg at",
-		"app pre status",
-		"app status",
-		"stack status",
-	})
-	fmt.Println(t.Render())
-	os.Exit(0)
-}
-
 func ShowVersion() {
 	fmt.Printf("%-20s %-8s\n", "Name:", AgentName)
 	fmt.Printf("%-20s %-8s\n", "Version:", AgentVersion)

+ 187 - 0
flags/snap.go

@@ -0,0 +1,187 @@
+package flags
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"os"
+	"path"
+	"time"
+
+	"github.com/coroot/coroot-node-agent/utils"
+	"github.com/coroot/coroot-node-agent/utils/modelse"
+	"github.com/jedib0t/go-pretty/v6/table"
+)
+
+func DumpTableFeatures(outputFormat string) {
+	dumpPath := path.Join(utils.GetDefaultRuntimePath(), "memdump")
+	fileName := path.Join(dumpPath, "app.snap")
+
+	// 打开文件并获取文件信息
+	file, err := os.Open(fileName)
+	if err != nil {
+		fmt.Println("no app.snap")
+		os.Exit(0)
+	}
+	defer file.Close()
+
+	// 获取文件修改时间
+	fileInfo, err := file.Stat()
+	if err != nil {
+		fmt.Println("Failed to get file information")
+		os.Exit(0)
+	}
+	fileModTime := fileInfo.ModTime().Format("2006/01/02 15:04:05")
+
+	// 读取文件内容
+	content, err := io.ReadAll(file)
+	if err != nil {
+		fmt.Println("Failed to read file content")
+		os.Exit(0)
+	}
+
+	s := make(map[uint32]modelse.AppStatusInfo)
+	err = json.Unmarshal(content, &s)
+	if err != nil {
+		fmt.Println(err.Error())
+		os.Exit(0)
+	}
+
+	// 根据输出格式选择显示方式
+	if outputFormat == "json" {
+		// JSON格式输出
+		output := map[string]interface{}{
+			"snap_updated": fileModTime,
+			"data":         s,
+		}
+		jsonData, err := json.MarshalIndent(output, "", "  ")
+		if err != nil {
+			fmt.Println("Failed to marshal JSON:", err.Error())
+			os.Exit(1)
+		}
+		fmt.Println(string(jsonData))
+	} else {
+		// 默认表格格式输出
+		t := table.NewWriter()
+		t.SetTitle(fmt.Sprintf("Application Status (Snap Updated: %s)", fileModTime))
+
+		for pid, info := range s {
+			service := fmt.Sprintf("%s", info.Sn)
+			t.AppendRow(table.Row{
+				//info.AgentID,
+				//info.UpdateAt,
+				pid,
+				info.ProcName,
+				info.AppName,
+				info.Container,
+				info.Rule,
+				info.Language,
+				service,
+				info.AppID,
+				info.RegisterAt,
+				info.PreStatus.String(),
+				info.Status.String(),
+				info.StackStatus,
+			})
+		}
+		t.SetAutoIndex(true)
+		t.AppendHeader(table.Row{
+			//"agent id",
+			//"update at",
+			"pid",
+			"process",
+			"app name",
+			"container",
+			"app rule",
+			"code",
+			"service",
+			"app id",
+			"reg at",
+			"app pre status",
+			"app status",
+			"stack status",
+		})
+		fmt.Println(t.Render())
+	}
+	os.Exit(0)
+}
+
+func DumpRuleTableFeatures(outputFormat string) {
+	dumpPath := path.Join(utils.GetDefaultRuntimePath(), "memdump")
+	fileName := path.Join(dumpPath, "rule.snap")
+
+	// 打开文件并获取文件信息
+	file, err := os.Open(fileName)
+	if err != nil {
+		fmt.Println("no rule.snap")
+		os.Exit(0)
+	}
+	defer file.Close()
+
+	// 获取文件修改时间
+	fileInfo, err := file.Stat()
+	if err != nil {
+		fmt.Println("Failed to get file information")
+		os.Exit(0)
+	}
+	fileModTime := fileInfo.ModTime().Format("2006/01/02 15:04:05")
+
+	// 读取文件内容
+	content, err := io.ReadAll(file)
+	if err != nil {
+		fmt.Println("Failed to read file content")
+		os.Exit(0)
+	}
+
+	var whiteData modelse.WhiteDataV2
+	err = json.Unmarshal(content, &whiteData)
+	if err != nil {
+		fmt.Println(err.Error())
+		os.Exit(0)
+	}
+
+	// 根据输出格式选择显示方式
+	if outputFormat == "json" {
+		// JSON格式输出
+		lastUpdatedTime := time.Unix(int64(whiteData.LastUpdatedTime), 0).Format("2006/01/02 15:04:05")
+		output := map[string]interface{}{
+			"rule_updated": lastUpdatedTime,
+			"snap_updated": fileModTime,
+			"data":         whiteData.SettingList,
+		}
+		jsonData, err := json.MarshalIndent(output, "", "  ")
+		if err != nil {
+			fmt.Println("Failed to marshal JSON:", err.Error())
+			os.Exit(1)
+		}
+		fmt.Println(string(jsonData))
+	} else {
+		// 默认表格格式输出
+		t := table.NewWriter()
+
+		// 设置表格标题,包含规则更新时间和文件更新时间
+		lastUpdatedTime := time.Unix(int64(whiteData.LastUpdatedTime), 0).Format("2006/01/02 15:04:05")
+		t.SetTitle(fmt.Sprintf("Rule Configuration (Rule Updated: %s, Snap Updated: %s)", lastUpdatedTime, fileModTime))
+		for _, setting := range whiteData.SettingList {
+			t.AppendRow(table.Row{
+				setting.AppName,
+				setting.ProcessKey,
+				setting.Filters,
+				setting.WhiteStackSettingInfo.OpenStack,
+				setting.WhiteStackSettingInfo.WhiteList,
+				setting.WhiteStackSettingInfo.BlackList,
+			})
+		}
+		t.SetAutoIndex(true)
+		t.AppendHeader(table.Row{
+			"App Name",
+			"Setting rule",
+			"Filters",
+			"Stack Switch",
+			"White List",
+			"Black List",
+		})
+		fmt.Println(t.Render())
+	}
+	os.Exit(0)
+}

+ 1 - 2
main.go

@@ -141,8 +141,7 @@ func main() {
 		MaxSize:    50, // 日志文件最大尺寸,单位MB
 		MaxBackups: 3,  // 最多保留的旧日志文件数
 		MaxAge:     3,  // 日志文件保留的最长时间,单位天
-		// Console:    *flags.ConsoleLog,
-		Console:    true,
+		Console:    *flags.ConsoleLog,
 	})
 
 	if err != nil {

+ 9 - 2
utils/modelse/stack_status.go

@@ -46,6 +46,13 @@ func (s *StackStatus) StackUprobesClose() {
 }
 
 func (s StackStatus) String() string {
-	return fmt.Sprintf("native:%v|uprobe:%v",
-		s.IsJattachSuccess(), s.IsStackUprobesSuccess())
+	n := 0
+	if s.IsJattachSuccess() {
+		n = 1
+	}
+	u := 0
+	if s.IsStackUprobesSuccess() {
+		u = 1
+	}
+	return fmt.Sprintf("N=%d U=%d ", n, u)
 }

+ 1 - 0
utils/modelse/status.go

@@ -18,6 +18,7 @@ type AppStatusInfo struct {
 	PreStatus   APP_TYPE `json:"pre_status"`
 	Rule        string   `json:"rule"`
 	StackStatus string   `json:"stack_status"`
+	Container   string   `json:"container"`
 }
 
 const (