当前位置: 首页 > news >正文

go语言获取机器的进程和进程运行参数 获取当前进程的jmx端口 go调用/jstat获取当前Java进程gc情况

这里主要分享go中获取机器进程和进程参数的一些代码

获取当前机器所有的pid:

import "github.com/shirou/gopsutil/process"
pids, err := process.Pids()
for _, pid := range pids {
		proc, err := process.NewProcess(pid)
		if err != nil {
			log.Errorf("get pid %d info error: %s", pid, err.Error())
			continue
		}

		// 获取进程命令行参数
		cmdLine, err := proc.Cmdline()
		if err != nil {
			log.Errorf("get cmdLine of pid %d error: %s", pid, err.Error())
			continue
		}

		log.Infof("cmdline of pid %d is: %s", pid, cmdLine)

		if !strings.Contains(cmdLine, "java") {
			continue
		}
//获取jmx端口:
	// 检查命令行参数是否包含"java"和"Dcom.sun.management.jmxremote.port"
			var jmxPort string
			if strings.Contains(cmdLine, "Dcom.sun.management.jmxremote.port") {
				// 提取JMX端口
				re := regexp.MustCompile(`Dcom.sun.management.jmxremote.port=(\d+)`)
				match := re.FindStringSubmatch(cmdLine)
				if len(match) > 1 {
					jmxPort = match[1]
					log.Infof("PID: %v, JMX Port: %v , %s, cmdLine: %s\n", pid, match[1], jmxPort, cmdLine)
				} else {
					log.Infof("not found jmxremote.port or jmxremote.rmi.port")
					log.Infof("PID: %v, of cmdLine: %s, has no Dcom.sun.management.jmxremote.port \n", pid, cmdLine)
				}
			}

Process.CmdlineWithContext 方法的实现依赖于 callPsWithContext 函数来获取进程的命令行参数。这个方法的实现如下:

func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
    r, err := callPsWithContext(ctx, "command", p.Pid, false)
    if err != nil {
        return "", err
    }
    return strings.Join(r[0], " "), err
}

调用jstat

JSTAT:JSTAT用于监视和收集Java虚拟机(JVM)的各种统计数据,例如垃圾回收情况、类加载情况、线程数量等。它可以实时显示这些统计数据,帮助开发人员了解应用程序的性能状况。
在这里插入图片描述

根据pid获取当前java程序的gc情况:


		Command := "jstat"
		if e.NewJSTAT {
			Command = "/usr/local/jdk/bin/jstat"
		}
		Data, DataErr, Err = util.RunCommandWithTimeout(&util.CommandArgs{
			Cmd:       Command,
			Username:  "root",
			Groupname: "root",
			Args:      []string{"-gcutil", strconv.FormatInt(pid, 10)},
		}, 2*time.Second)


func RunCommandWithTimeout(command *CommandArgs, timeout time.Duration) (stdout, stderr string, err error) {
	userinfo, err := user.Lookup(command.Username)
	if err != nil {
		return "", fmt.Sprintf("lookup user err:%s", err.Error()), err
	}
	uid, _ := strconv.Atoi(userinfo.Uid)
	gid, _ := strconv.Atoi(userinfo.Gid)
	var outb, errb bytes.Buffer
	ctxt, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()
	getBashCommand(command)
	cmd := exec.CommandContext(ctxt, command.Cmd, command.Args...)
	cmd.Stdout = &outb
	cmd.Stderr = &errb
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Credential: &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)},
		Setsid:     true,
	}
	cmd.Env = append(os.Environ(), makeEnv(command.Username)...)
	if command.Env != nil && len(command.Env) != 0 {
		for k, v := range command.Env {
			cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
		}
	}
	if err := cmd.Start(); err != nil {
		return outb.String(), errb.String(), err
	}
	if err := cmd.Wait(); err != nil {
		return outb.String(), errb.String(), err
	}
	return outb.String(), errb.String(), err
}

调用jcmd命令:

log.Debugf("process jcmd data")
			JCMD := "jcmd"
			if e.NewJSTAT {
				Command = "/usr/local/jdk/bin/jcmd"
			}
			JcmdData, JcmdDataErr, JcmdErr = util.RunCommandWithTimeout(&util.CommandArgs{
				Cmd:       JCMD,
				Username:  "root",
				Groupname: "root",
				Args:      []string{strconv.FormatInt(pid, 10), "VM.flags"},
			}, 2*time.Second)
			if JcmdErr != nil {
				log.Errorf("RunCommandWithTimeout Jcmd JcmdDataErr %s JcmdErr %v", JcmdDataErr, JcmdErr)
			}

关于jcmd:
jcmd 是一个用于与 Java 虚拟机 (JVM) 进行交互的命令行工具。它是 JDK(Java Development Kit)的一部分,提供了一系列命令来诊断和监控运行中的 Java 应用程序。jcmd 工具可以用于执行各种操作,例如获取线程堆栈、生成堆转储、执行垃圾回收等。

jcmd 的基本用法
jcmd 的基本用法如下:

jcmd <pid | main class> <command> [options]
<pid | main class>:指定目标 JVM 的进程 ID 或主类名。
<command>:要执行的命令。
[options]:命令的可选参数。

常用命令
以下是一些常用的 jcmd 命令:

列出所有可用的命令:

jcmd help
例如:
jcmd 12345 help
列出所有正在运行的 Java 进程:

jcmd

在这里插入图片描述

获取 JVM 版本信息:
jcmd VM.version
例如:
jcmd 12345 VM.version
获取系统属性:
jcmd VM.system_properties
获取 JVM 配置:
jcmd VM.command_line

在docker中执行/jstat

在docker中想执行jstat如下:

func RunDockerPsEfWithTimeout(dockerName string) (stdout, stderr string, err error) {

	// docker exec sr-broker ps -ef | grep broker
	cmd := exec.Command("/usr/bin/docker", "exec", dockerName, "ps", "-ef")
	var outb, errb bytes.Buffer
	cmd.Stdout = &outb
	cmd.Stderr = &errb
	err = cmd.Run()

	return outb.String(), errb.String(), err
}

func RunDockerJstatWithTimeout(dockerName string, dockerPid string) (stdout, stderr string, err error) {
stdout, stderr, err := RunDockerPsEfWithTimeout(dockerName)
		if err != nil {
			log.Errorf("RunDockerCMDWithTimeout dockerPsCmd err %v stderr %s", err, stderr)
			return "", "", "", err
		}
		//获取docker中的pid
		dockerPid := ""
		lines := strings.Split(stdout, "\n")
		for _, line := range lines {
			fields := strings.Fields(line)
			if len(fields) >= 8 {
				if strings.Contains(line, dockerPName) {
					dockerPid = fields[1]
					break
				}
			}
		}
	defer func() {
		if e := recover(); e != nil {
			log.Errorf("RunDockerJstatWithTimeout error %v", e)
		}
	}()

	dockerCmd := []string{"bash", "-c", fmt.Sprintf("source /etc/profile && jstat -gcutil %s", dockerPid)}

	cmd := exec.Command("/usr/bin/docker", "exec", dockerName)
	cmd.Args = append(cmd.Args, dockerCmd...)
	var outb, errb bytes.Buffer
	cmd.Stdout = &outb
	cmd.Stderr = &errb
	err = cmd.Run()

	return outb.String(), errb.String(), err
}

相关文章:

  • 【前端】几种常见的跨域解决方案代理的概念
  • SQLMesh系列教程-2:SQLMesh入门项目实战(上篇)
  • SQL布尔盲注、时间盲注
  • [SQL Server]从数据类型 varchar 转换为 numeric 时出错
  • 排序--四种算法
  • STM32、GD32驱动TM1640原理图、源码分享
  • HCIA项目实践--RIP相关原理知识面试问题总结回答
  • 服务器,交换机和路由器的一些笔记
  • 机器学习(李宏毅)——self-Attention
  • 常见的排序算法:插入排序、选择排序、冒泡排序、快速排序
  • 利用Java爬虫按图搜索1688商品(拍立淘):实战案例指南
  • 集成学习(一):从理论到实战(附代码)
  • sqli-lab靶场学习(六)——Less18-22(User-Agent、Referer、Cookie注入)
  • 网络工程师 (35)以太网通道
  • iptables网络安全服务详细使用
  • ES节点配置的最佳实践
  • 开发指南098-logback-spring.xml说明
  • 六西格玛设计培训如何破解风电设备制造质量与成本困局
  • 错误报告:WebSocket 设备连接断开处理问题
  • qt的QSizePolicy的使用
  • 西甲上海足球学院揭幕,用“足球方法论”试水中国青训
  • 习近平会见古共中央第一书记、古巴国家主席迪亚斯-卡内尔
  • 三星“七天机”质保期内屏幕漏液被要求自费维修,商家:系人为损坏
  • 上海“世行对标改革”的税务样本:设立全国首个税务审判庭、制定首个税务行政复议简易程序
  • 河南省平顶山市副市长许红兵主动投案,接受审查调查
  • 七大交响乐团“神仙斗法”,时代交响在上海奏出时代新声