Browse Source

Fixed #TASK_QT-9810 堆栈开启逻辑重构

Carl 1 năm trước cách đây
mục cha
commit
e25a895634

+ 57 - 0
containers/apm_get_code_setting.go

@@ -0,0 +1,57 @@
+package containers
+
+import (
+	"fmt"
+	"github.com/coroot/coroot-node-agent/utils"
+	. "github.com/coroot/coroot-node-agent/utils/modelse"
+	klog "github.com/sirupsen/logrus"
+)
+
+func (c *Container) GetCodeSetting(r *Registry) (CodeSettingResp, error) {
+	nodeInfo := r.nodeInfo.GetNodeInfo()
+	if nodeInfo == nil {
+		return CodeSettingResp{}, fmt.Errorf("[GetCodeSetting] Unknown node info.")
+	}
+	req := CodeSettingReq{
+		AccountId: nodeInfo.AccountID,
+		HostId:    nodeInfo.HostID,
+		Appid:     c.AppInfo.AppIdHash.IntVal,
+		AgentId:   c.AppInfo.AgentId,
+	}
+	klog.Infof("[GetCodeSetting] req: %s.", utils.ToString(req))
+	resp, err := r.connServer.GetCodeSetting(req)
+	if err != nil {
+		klog.WithError(err).Errorf("[GetCodeSetting] Failed GetCodeSetting  %s.", utils.ToString(req))
+		return resp, err
+	}
+
+	//fmt.Println(resp)
+	//c.saveWhiteStackSettingInfo(resp)
+	return resp, err
+}
+
+func (c *Container) saveWhiteStackSettingInfo(resp CodeSettingResp) {
+	c.WhiteSettingInfo.WhiteStackSettingInfo.WhiteList = resp.BlackWhiteSettings.WhiteList
+	c.WhiteSettingInfo.WhiteStackSettingInfo.BlackList = resp.BlackWhiteSettings.BlackList
+	c.WhiteSettingInfo.WhiteStackSettingInfo.OpenStack = resp.BlackWhiteSettings.CollectStack
+}
+
+func (c *Container) stackRuleUpdate(resp CodeSettingResp) bool {
+	if c.noOrigRule() {
+		return false
+	}
+	return resp.BlackWhiteSettings.WhiteList != c.WhiteSettingInfo.WhiteStackSettingInfo.WhiteList ||
+		resp.BlackWhiteSettings.BlackList != c.WhiteSettingInfo.WhiteStackSettingInfo.BlackList
+}
+
+func (c *Container) noStackRule(resp CodeSettingResp) bool {
+	return resp.BlackWhiteSettings.WhiteList == "" && resp.BlackWhiteSettings.BlackList == ""
+}
+
+func (c *Container) hasStackRule(resp CodeSettingResp) bool {
+	return resp.BlackWhiteSettings.WhiteList != "" || resp.BlackWhiteSettings.BlackList != ""
+}
+
+func (c *Container) noOrigRule() bool {
+	return c.WhiteSettingInfo.WhiteStackSettingInfo.WhiteList == "" && c.WhiteSettingInfo.WhiteStackSettingInfo.BlackList == ""
+}

+ 22 - 2
containers/apm_stack_dispatch.go

@@ -10,6 +10,7 @@ import (
 	"github.com/coroot/coroot-node-agent/ebpftracer/tracer"
 	tracerelf "github.com/coroot/coroot-node-agent/ebpftracer/tracer"
 	"github.com/coroot/coroot-node-agent/proc"
+	"github.com/coroot/coroot-node-agent/utils"
 	. "github.com/coroot/coroot-node-agent/utils/modelse"
 	klog "github.com/sirupsen/logrus"
 	"golang.org/x/arch/arm64/arm64asm"
@@ -123,10 +124,29 @@ func (c *Container) stackTrace(tracer *ebpftracer.Tracer, pid uint32) error {
 }
 
 func (c *Container) jvmStackTrace(tracer *ebpftracer.Tracer, pid uint32) error {
-
 	p := c.processes[pid]
+	// check version
+	libjavaso, err := utils.GetSoPath(pid, "libjava.so", c.getRootfs())
+	if err != nil {
+		p.versionFailed = true
+		klog.WithError(err).Errorf("[jvmStackTrace] Failed get so path")
+		return err
+	}
+	v, err := ebpftracer.GetJvmVersion(libjavaso)
+	if err != nil {
+		p.versionFailed = true
+		klog.WithError(err).Errorf("[jvmStackTrace] Failed get Java version")
+		return err
+	}
+	c.AppInfo.Version = v
+	major, minor, patch, err := ebpftracer.ParseVersion(v)
+	klog.Infof("[jvmStackTrace] version: %s (Major: %d, Minor: %d, Patch: %d)", v, major, minor, patch)
+	if major != 1 || minor != 8 {
+		p.versionFailed = true
+		return fmt.Errorf("[jvmStackTrace] Unsupported Java version")
+	}
 
-	err := tracer.JattachJvm(pid, c.AppInfo)
+	err = tracer.JattachJvm(pid, c.AppInfo, c.WhiteSettingInfo.WhiteStackSettingInfo.WhiteList, c.WhiteSettingInfo.WhiteStackSettingInfo.BlackList)
 	if err != nil {
 		p.stackStatus.JattachFailure()
 		return err

+ 5 - 5
containers/apm_white_list.go

@@ -17,15 +17,15 @@ func (r *Registry) getWhiteListByCodeType(codeType CodeType) []WhiteSettingInfo
 }
 
 func (r *Registry) setWhiteList(whiteData WhiteData) {
-	var openStack int
-	if !r.tracer.DisableStackTracing() {
-		openStack = 1
-	}
+	//var openStack int
+	//if !r.tracer.DisableStackTracing() {
+	//	openStack = 1
+	//}
 	whiteListMap := make(WhiteListMap)
 	for _, scop := range whiteData.Appscope {
 		code := scop.Code
 		for _, setting := range scop.Settings {
-			setting.OpenStack = openStack
+			//setting.OpenStack = openStack
 			whiteListMap[code] = append(whiteListMap[code], setting)
 		}
 	}

+ 70 - 25
containers/container_apm.go

@@ -568,6 +568,57 @@ func (c *Container) l7AttachSuccess() {
 	c.l7Attach = true
 }
 
+func (c *Container) ctrlStack(r *Registry, pid uint32) {
+	resp, err := c.GetCodeSetting(r)
+	if err != nil {
+		klog.WithField("pid", pid).WithError(err).Error("[ctrlStack] GetCodeSetting failed.")
+		return
+	}
+
+	if resp.BlackWhiteSettings.CollectStack == OPEN_STACK {
+		// 有黑白名单规则 &&
+		// 之前有注入 先卸载再注入
+		// 之前没注入 直接注入
+		// 没有有黑白名单 直接卸载
+		if c.hasStackRule(resp) {
+			if c.stackRuleUpdate(resp) {
+				// 重新注入
+				err = c.DetachStack(pid, APP_UNINSTALL)
+				if err != nil {
+					klog.WithError(err).Errorf("[ctrlStack][end] Failed detach stack trace!")
+				}
+			}
+			klog.WithField("pid", pid).Infoln("[ctrlStack] Attach app stack.")
+			c.saveWhiteStackSettingInfo(resp)
+			err = c.AttachStack(r.tracer, pid)
+			if err != nil {
+				c.AppInfo.SetAppStackError()
+				klog.WithField("pid", pid).WithError(err).Errorf("[ctrlStack][end] Failed attach stack trace!")
+			}
+		} else {
+			if c.noOrigRule() {
+				return
+			}
+			c.saveWhiteStackSettingInfo(resp)
+			// 关闭堆栈
+			err = c.DetachStack(pid, APP_UNINSTALL)
+			if err != nil {
+				klog.WithError(err).Errorf("[ctrlStack][end] Failed detach stack trace!")
+			}
+		}
+	} else {
+		if c.noOrigRule() {
+			return
+		}
+		c.saveWhiteStackSettingInfo(resp)
+		// 关闭堆栈
+		err = c.DetachStack(pid, APP_UNINSTALL)
+		if err != nil {
+			klog.WithError(err).Errorf("[ctrlStack][end] Failed detach stack trace!")
+		}
+	}
+}
+
 func (c *Container) verifyAttachConditions(r *Registry, pid uint32) (bool, int) {
 	p := c.processes[pid]
 	if p != nil && c.checkEventReady() {
@@ -592,15 +643,16 @@ func (c *Container) verifyAttachConditions(r *Registry, pid uint32) (bool, int)
 			}
 			// 判断规则
 			if strings.Contains(cmdline, ruleVal) {
-				c.WhiteSettingInfo = setting
+				c.WhiteSettingInfo.AppName = setting.AppName
+				c.WhiteSettingInfo.Filters = setting.Filters
 				klog.WithField("pid", pid).
 					WithField("codeType", codeType.String()).
 					WithField("ruleVal", ruleVal).
 					WithField("cmdline", cmdline).
-					WithField("stack", setting.OpenStack).
+					//WithField("stack", setting.OpenStack).
 					WithField("white list", utils.ToString(whiteListByCode)).
 					Infoln("[verify] check successful.")
-				return true, setting.OpenStack
+				return true, 0
 			}
 		}
 	}
@@ -690,16 +742,21 @@ func (c *Container) DetachStack(pid uint32, detachType APP_TYPE) error {
 // 1.2.1 卸载 jvm堆栈
 func (c *Container) detachJvmStack(pid uint32) error {
 	if p := c.processes[pid]; p != nil {
-		var err error
-		// 卸载堆栈probes
-		err = p.closeStackUprobes()
-		klog.WithError(err).Infof("[detachJvmStack] closeStackUprobes")
+
 		//if p.stackStatus.IsStackUprobesSuccess() || len(p.stackUprobes) > 0 {
 		//}
 		// 卸载 JavaAgent
+		var err error
 		if p.stackStatus.IsJattachSuccess() {
+			// 卸载堆栈probes
+			err = p.closeStackUprobes()
+			if err != nil {
+				klog.WithError(err).Errorf("[detachJvmStack] closeStackUprobes")
+			}
 			err = p.uninstallJavaAgent()
-			klog.WithError(err).Infof("[detachJvmStack] uninstallJavaAgent")
+			if err != nil {
+				klog.WithError(err).Errorf("[detachJvmStack] uninstallJavaAgent")
+			}
 		}
 		return err
 	}
@@ -730,13 +787,14 @@ func (c *Container) BuildActiveApps(runtimeApps map[uint32]AppStatusInfo, pid ui
 			Status:     c.AppInfo.Status,
 			Rule:       c.WhiteSettingInfo.Filters,
 		}
-		detail.Rule = fmt.Sprintf("%s|%d", c.WhiteSettingInfo.Filters, c.WhiteSettingInfo.OpenStack)
+		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
 	}
@@ -745,7 +803,7 @@ func (c *Container) BuildActiveApps(runtimeApps map[uint32]AppStatusInfo, pid ui
 
 func (c *Container) AgentCtrl(r *Registry, pid uint32) {
 	var err error
-	verifyAttachConditions, openStack := c.verifyAttachConditions(r, pid)
+	verifyAttachConditions, _ := c.verifyAttachConditions(r, pid)
 
 	// UNINSTALL
 	if r.isFusing && c.Isl7AttachSuccess() {
@@ -773,20 +831,7 @@ func (c *Container) AgentCtrl(r *Registry, pid uint32) {
 		} else {
 			klog.WithField("pid", pid).Infoln("[AgentCtrl] Attach uprobes success!")
 		}
-		if openStack == OPEN_STACK {
-			klog.WithField("pid", pid).Infoln("[AgentCtrl] Attach app stack.")
-			err = c.AttachStack(r.tracer, pid)
-			if err != nil {
-				c.AppInfo.SetAppStackError()
-				klog.WithField("pid", pid).WithError(err).Errorf("[AgentCtrl][end] Failed attach stack trace!")
-				return
-			}
-		} else {
-			// 关闭堆栈
-			err = c.DetachStack(pid, APP_UNINSTALL)
-			if err != nil {
-				klog.WithError(err).Errorf("[AgentCtrl][end] Failed detach stack trace!")
-			}
-		}
+		// 堆栈控制
+		c.ctrlStack(r, pid)
 	}
 }

+ 1 - 0
containers/process.go

@@ -39,6 +39,7 @@ type Process struct {
 	jvmAttachOnce    bool
 	stackAttachOnce  bool
 	stackStatus      StackStatus
+	versionFailed    bool
 	codeType         CodeType
 	cmdline          string
 	pythonGilChecked bool

+ 0 - 7
dist/package_dir/agents/NativeAgent/conf/agent.properties

@@ -1,7 +0,0 @@
-# APM Server url.
-ConfigDomain    = http://10.0.7.115:18080
-SendDomain      = http://10.0.7.115:18080
-# License Key.
-# Logging level.
-# Optional: DEBUG, INFO, WARN, ERROR
-agent.log.level = ERROR

+ 0 - 15
dist/package_dir/agents/NativeAgent/conf/interceptors.xml

@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<interceptors>
-    <interceptor id="define-interceptor_id">
-        <definition>
-            <class_name>define-class</class_name>
-            <method_name>define-method</method_name>
-            <paramters>
-            </paramters>
-        </definition>
-        <info>
-            <uri>$this.name</uri>
-        </info>
-    </interceptor>
-
-</interceptors>

BIN
dist/package_dir/agents/NativeAgent/lib/apmAgent.jar


BIN
dist/package_dir/agents/NativeAgent/lib/apmCore.jar


BIN
dist/package_dir/agents/NativeAgent/lib/apmSpy.jar


BIN
dist/package_dir/agents/NativeAgent/plugins/cloudwise-javacode-plugin-apiurl.jar


BIN
dist/package_dir/agents/NativeAgent/plugins/cloudwise-javacode-plugin-autotracebusinesspkg.jar


+ 15 - 2
ebpftracer/stack.go

@@ -49,13 +49,25 @@ func (t *Tracer) AttachStackUprobes(path string, uprobes []tracer.Uprobe) []link
 }
 
 // JVM process stack
-func (t *Tracer) JattachJvm(pid uint32, appInfo AppInfo) error {
+func (t *Tracer) JattachJvm(pid uint32, appInfo AppInfo, whiteList, blackList string) error {
 	klog.Infoln("[Jvm stack uprobe] Attach Start AttachJVMStackUprobes", pid)
 	// TODO tiny Agent 注入
 	// TODO copy agent到 jre conf/lib/plugins
 
 	//argkv := "/opt/github/euspace/dist/package_dir/agents/NativeAgent/lib/apmAgent.jar=/opt/github/euspace/dist/package_dir/agents/NativeAgent"
-
+	if whiteList == "" && blackList == "" {
+		return nil
+	}
+	whiteList = strings.ReplaceAll(whiteList, ",", "")
+	blackList = strings.ReplaceAll(blackList, ",", "")
+	var stackRule string
+	if whiteList == "" {
+		stackRule = fmt.Sprintf("blackStack=%s", blackList) // 仅保留黑名单
+	} else if blackList == "" {
+		stackRule = fmt.Sprintf("whiteStack=%s", whiteList) // 仅保留白名单
+	} else {
+		stackRule = fmt.Sprintf("whiteStack=%s,blackStack=%s", whiteList, blackList)
+	}
 	nativeBasePath := utils.GetDefaultAgentsPath("NativeAgent")
 	kvPairs := []string{
 		fmt.Sprintf("%s=%s", filepath.Join(nativeBasePath, "lib", "apmAgent.jar"), nativeBasePath),
@@ -63,6 +75,7 @@ func (t *Tracer) JattachJvm(pid uint32, appInfo AppInfo) error {
 		fmt.Sprintf("%s=%d", "agentId", appInfo.AgentId),
 		fmt.Sprintf("%s=%d", "hostId", utils.GetHostID()),
 		fmt.Sprintf("%s=%d", "accountId", utils.GetAccountID()),
+		stackRule,
 	}
 	argkv := strings.Join(kvPairs, ",")
 	klog.Infof("[Jvm stack uprobe] params:[%s]", argkv)

+ 14 - 15
flags/flags.go

@@ -6,7 +6,6 @@ import (
 	"github.com/coroot/coroot-node-agent/utils"
 	"github.com/coroot/coroot-node-agent/utils/modelse"
 	"github.com/jedib0t/go-pretty/v6/table"
-	klog "github.com/sirupsen/logrus"
 	"gopkg.in/alecthomas/kingpin.v2"
 	"gopkg.in/ini.v1"
 	"net/url"
@@ -139,20 +138,20 @@ func init() {
 	}
 
 	// set tiny-agent config
-	nativeConf := utils.GetDefaultAgentsPath("NativeAgent", "conf", "agent.properties")
-	confData, err := ini.Load(nativeConf)
-	if err == nil {
-		configServer := *ConfigServer
-		if !strings.HasPrefix(*ConfigServer, "http") {
-			configServer = fmt.Sprintf("http://%s", *ConfigServer)
-		}
-		confData.Section(ini.DEFAULT_SECTION).Key("ConfigDomain").SetValue(configServer + *ServerPrefix)
-		confData.Section(ini.DEFAULT_SECTION).Key("SendDomain").SetValue(*DataServer + *ServerPrefix)
-		err = confData.SaveTo(nativeConf)
-		if err != nil {
-			klog.Error(err)
-		}
-	}
+	//nativeConf := utils.GetDefaultAgentsPath("NativeAgent", "conf", "agent.properties")
+	//confData, err := ini.Load(nativeConf)
+	//if err == nil {
+	//	configServer := *ConfigServer
+	//	if !strings.HasPrefix(*ConfigServer, "http") {
+	//		configServer = fmt.Sprintf("http://%s", *ConfigServer)
+	//	}
+	//	confData.Section(ini.DEFAULT_SECTION).Key("ConfigDomain").SetValue(configServer + *ServerPrefix)
+	//	confData.Section(ini.DEFAULT_SECTION).Key("SendDomain").SetValue(*DataServer + *ServerPrefix)
+	//	err = confData.SaveTo(nativeConf)
+	//	if err != nil {
+	//		klog.Error(err)
+	//	}
+	//}
 
 	if *RunInContainer {
 		if *HostDirPathPrefix == "" {

+ 34 - 9
utils/modelse/models.go

@@ -162,15 +162,24 @@ type WhiteListResp struct {
 }
 
 type WhiteSettingInfo struct {
-	AppName         string `json:"app_name"`
-	K8SNamespace    string `json:"k8s_namespace"`
-	K8SWorkLoadName string `json:"k8s_workLoadName"`
-	Filters         string `json:"filters"`
-	Type            string `json:"type"`
-	PodName         string `json:"pod_name"`
-	ProcessKey      string `json:"process_key"`
-	OpenStack       int    `json:"collect_stack"`
-	UpdateTime      int64  `json:"update_time"`
+	AppName string `json:"app_name"`
+	//K8SNamespace    string `json:"k8s_namespace"`
+	//K8SWorkLoadName string `json:"k8s_workLoadName"`
+	Filters string `json:"filters"`
+	//Type            string `json:"type"`
+	//PodName         string `json:"pod_name"`
+	ProcessKey string `json:"process_key"`
+	//OpenStack       int    `json:"collect_stack"`
+	//UpdateTime      int64  `json:"update_time"`
+
+	WhiteStackSettingInfo WhiteStackSettingT
+}
+
+type WhiteStackSettingT struct {
+	// from getCodeSetting
+	OpenStack int
+	WhiteList string
+	BlackList string
 }
 
 type Appscope struct {
@@ -281,6 +290,22 @@ type AgentInfo struct {
 	ProxyLocalIp string `json:"proxy_local_ip"`
 }
 
+type CodeSettingReq struct {
+	AccountId int   `json:"accountId"`
+	AgentId   int64 `json:"agentId"`
+	Appid     int64 `json:"appId"`
+	HostId    int64 `json:"hostId"`
+}
+
+type CodeSettingResp struct {
+	BlackWhiteSettings struct {
+		WhiteList      string `json:"white_list"`
+		BlackList      string `json:"black_list"`
+		BlackWhiteList int    `json:"black_white_list"`
+		CollectStack   int    `json:"collect_stack"`
+	} `json:"black_white_settings"`
+}
+
 type EbpfAppReq struct {
 	AccountId int `json:"account_id"`
 }

+ 20 - 2
utils/worker/serverWorker.go

@@ -38,6 +38,8 @@ type ServerWorker interface {
 	WhiteListV2(WhiteListReq) (WhiteDataV2, error)
 
 	PullAllAppInfo(EbpfAppReq) (EbpfAppResp, error)
+
+	GetCodeSetting(CodeSettingReq) (CodeSettingResp, error)
 	//SyncAgentInfo(RegistRequest) ([]AgentList, error)
 
 	//Heart(DaemonHeartBeatInfo) (map[string]HeartConfContent, error)
@@ -51,11 +53,27 @@ type ServerWorker interface {
 	//GetInfo() (string, string)
 }
 
+func (w *ServerHTTPWorker) GetCodeSetting(request CodeSettingReq) (CodeSettingResp, error) {
+	//log.Infof("[get GetCodeSetting] request:%v.", utils.ToString(request))
+	response := CodeSettingResp{}
+	result, err := w.requestServer("/api/v70/agent/getCodeSetting", request)
+	//log.Infof("[get GetCodeSetting] resp data:%v.", string(result))
+	if err != nil {
+		return response, err
+	}
+	err = json.Unmarshal(result, &response)
+	if err != nil {
+		log.WithError(err).Errorf("[get GetCodeSetting] Failed get request:%v.", utils.ToString(request))
+		return response, err
+	}
+	return response, nil
+}
+
 func (w *ServerHTTPWorker) PullAllAppInfo(request EbpfAppReq) (EbpfAppResp, error) {
-	log.Infof("[get all appinfo] request:%v.", utils.ToString(request))
+	//log.Infof("[get all appinfo] request:%v.", utils.ToString(request))
 	response := EbpfAppResp{}
 	result, err := w.requestServer("/api/v70/ebpfAppInfo", request)
-	log.Infof("[get all appinfo] resp data:%v.", string(result))
+	//log.Infof("[get all appinfo] resp data:%v.", string(result))
 	if err != nil {
 		return response, err
 	}