• 【Java】+获取Linux服务器的CPU、内存使用率


     依赖

            <dependency>
                <groupId>ch.ethz.ganymed</groupId>
                <artifactId>ganymed-ssh2</artifactId>
                <version>262</version>
            </dependency>

    代码 

    package com.alipay.ipay.gn.commontool;
    
    import ch.ethz.ssh2.Connection;
    import ch.ethz.ssh2.Session;
    import ch.ethz.ssh2.StreamGobbler;
    import com.alipay.ipay.gn.commontool.file.ZgxFileUtil;
    import org.apache.commons.lang3.tuple.Pair;
    import org.apache.log4j.Logger;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.List;
    
    
    /**
     * @author 
     * @version 1.0
     * @time 2019/7/15 20:28
     * <p>
     * 类功能说明:
     * 1、连接服务器
     * 2、执行Linux日志查询命令,返回查询后的日志字符串(以行为单位)
     */
    public class LogAuto {
        private static Logger log;
        private Session ssh;
        private String hostName;
        private String userName;
        private String password;
        private int port;
    
        /**
         * 连接服务器
         *
         * @param hostname 服务器IP
         * @param port     端口
         * @param username 账号
         * @param password 密码
         */
        public LogAuto(String hostname, int port, String username, String password) {
            this.hostName = hostname;
            this.port = port;
            this.userName = username;
            this.password = password;
            this.log = ZgxLoggerUtil.getLoger(LogAuto.class);
        }
    
        /**
         * 通过Linux命令查询日志内容
         *
         * @param command Linux日志查询命令
         * @return 返回根据命令查出的日志内容
         */
        public List<String> execCom(String command) {
            Connection conn = new Connection(this.hostName, this.port);
            createConnection(conn);
            List<String> logContent = new ArrayList<String>();
            try {
                ssh.execCommand(command);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            //将Terminal屏幕上的文字全部打印出来
            InputStream is = new StreamGobbler(ssh.getStdout());
            BufferedReader brs = new BufferedReader(new InputStreamReader(is));
            while (true) {
                String line = null;
                try {
                    line = brs.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (line == null) {
                    break;
                }
    //            System.out.println(line);
                logContent.add(line);
            }
    
            return logContent;
        }
    
        private void createConnection(Connection connection) {
            //创建连接
            try {
                connection.connect();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                connection.authenticateWithPassword(this.userName, this.password);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            //创建与服务器的会话节点
            try {
                setSsh(connection.openSession());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private void setSsh(Session ssh) {
            this.ssh = ssh;
        }
    
        private Session getSsh() {
            return ssh;
        }
    
        /**
         * 功能:获取指定服务器在当前时间的内存使用率
         *
         * @param logAuto
         * @return 返回使用率(百分比)
         */
        public static double getMemoryRate(LogAuto logAuto) {
            String shell = String.format("%s", "free"); // 多个命令用“;”隔开
            List<String> listResult = logAuto.execCom(shell);
            // 打印shell命令执行后的结果
            for (int i = 0; i < listResult.size(); i++) {
                System.out.println(listResult.get(i));
            }
    
            // 提取内存数据(第二行)
            List<String> mem = ZgxStringUtil.splitString(listResult.get(1), " ");
            Integer usedMemory = Integer.valueOf(mem.get(2));
            Integer allMemory = Integer.valueOf(mem.get(1));
            log.info(String.format("usedMemory=%s;allMemory=%s", usedMemory, allMemory));
    
            // 计算内存使用率(已使用内存/总内存)
            double f1 = new BigDecimal((float) usedMemory / allMemory).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
            log.info(String.format("内存使用率=%s%s", f1, "%"));
            return f1;
        }
    
        private static Pair getCpuData(LogAuto logAuto) {
            String shell = String.format("%s", "cat /proc/stat"); // 多个命令用“;”隔开
            List<String> listResult = logAuto.execCom(shell);
            // 打印shell命令执行后的结果
            for (int i = 0; i < listResult.size(); i++) {
                System.out.println(listResult.get(i));
            }
    
            // 提取CPU数据(第一行)
            List<String> mem = ZgxStringUtil.splitString(listResult.get(0), " ");
            mem.remove(0);
            Long allTime1 = 0L;
            for (int i = 0; i < mem.size(); i++) {
                allTime1 += Long.valueOf(mem.get(i));
            }
            System.out.println(String.format("CPU使用总时间=%s;idle=%s", allTime1, mem.get(3)));
    
            return Pair.of(allTime1, mem.get(3));
        }
    
        /**
         * 功能:获取指定服务器在当前时间的CPU使用率
         *
         * @param logAuto
         * @return 返回使用率(百分比)
         */
        public static double getCpuRate(LogAuto logAuto) {
            Pair cpuData1 = getCpuData(logAuto);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Pair cpuData2 = getCpuData(logAuto);
    
            // step1 计算两次的cpu总时间
            Long allTime = Long.valueOf(cpuData2.getLeft().toString()) - Long.valueOf(cpuData1.getLeft().toString());
            // step2 计算两次的cpu剩余时间
            Long idle = Long.valueOf(cpuData2.getRight().toString()) - Long.valueOf(cpuData1.getRight().toString());
            // step3 计算两次的cpu使用时间
            Long used = allTime - idle;
            // step4 计算cpu使用率(cpu使用率 = 使用时间 / 总时间 * 100%)
            double f1 = new BigDecimal((float) used / allTime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
            log.info(String.format("CPU使用率=%s%s", f1, "%"));
    
            return f1;
        }
    
        public static void main(String[] args) {
            LogAuto logAuto = new LogAuto("服务器IP", 端口号, "账号", "密码");
            getMemoryRate(logAuto);
            getCpuRate(logAuto);
    
            String[] header = {"时间,CPU使用率,内存使用率"};
            List<String[]> content = new ArrayList<>();
            // 每分钟获取一次服务器CPU、内存使用率(获取30次)
            for (int i = 0; i < 30; i++) {
                String[] data = {ZgxDateUtil.getNowDate("yyyy-MM-dd HH:mm:ss")
                        , String.valueOf(getCpuRate(logAuto))
                        , String.valueOf(getMemoryRate(logAuto))};
                content.add(data);
                ZgxFileUtil.writeCsv("服务器性能数据.csv", header, content);
                try {
                    Thread.sleep(1000 * 60);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • 相关阅读:
    段间跳转之陷阱门
    段间跳转之中断门
    段间跳转之调用门
    代码段段间跳转流程
    Window内核学习之保护模式基础
    回顾2020,展望2021
    内存管理之堆
    Windows进程间通讯(IPC)----信号量
    线程本地存储(动态TLS和静态TLS)
    Windows进程间通讯(IPC)----套接字
  • 原文地址:https://www.cnblogs.com/danhuai/p/12222208.html
Copyright © 2020-2023  润新知