分享

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

 三十的狼 2020-08-06
复制代码
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();
            }
        }
    }
}
复制代码

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多