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

 依赖

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

 

ZgxFileUtil工具

package com.file;

import com.ZgxLoggerUtil;
import com.csvreader.CsvReader;
import com.csvreader.CsvWriter;
import org.apache.log4j.Logger;

import javax.swing.*;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Jarvis
 * @version 1.0
 * @time 2019/12/20 9:35
 */
public class ZgxFileUtil {
    private static Logger log = ZgxLoggerUtil.getLogger(ZgxFileUtil.class);

    /**
     * 功能:将数据写入csv文件中
     *
     * @param filePath 文件路径
     * @param header   文件头
     * @param contents 文件内容
     * @return
     */
    static public boolean writeCsv(String filePath, String[] header, List<String[]> contents) {
        CsvWriter csvWriter = new CsvWriter(filePath, ',', Charset.forName("GBK"));

        // 写入文件头
        if (header != null) {
            try {
                csvWriter.writeRecord(header);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 写入文件行
        for (int i = 0; i < contents.size(); i++) {
            try {
                csvWriter.writeRecord(contents.get(i));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        csvWriter.close();

        return true;
    }

    static public boolean writeCsv(String filePath, String[] header, List<String[]> contents, JProgressBar jProgressBar, List<String> fileType) {
        List<CsvWriter> csvWriterList = new ArrayList<>();
        for (int i = 0; i < fileType.size(); i++) {
            csvWriterList.add(new CsvWriter(String.format("%s.%s", filePath, fileType.get(i)), ',', Charset.forName("GBK")));
        }

        // 写入文件头
        if (header != null) {
            try {
                for (int i = 0; i < csvWriterList.size(); i++) {
                    csvWriterList.get(i).writeRecord(header);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 写入文件行
        try {
            for (int i = 0; i < contents.size(); i++) {
                for (int j = 0; j < csvWriterList.size(); j++) {
                    csvWriterList.get(j).writeRecord(contents.get(i));
                    System.out.println(String.format("写入“%s”文件 第%s行", csvWriterList.get(j), i + 1));
                }
                jProgressBar.setValue(i + 1);
                System.out.println(String.format("总:%s 最小:%s 最大:%s 当前:%s", contents.size(), jProgressBar.getMinimum(), jProgressBar.getMaximum(), i));
            }

            for (int i = 0; i < csvWriterList.size(); i++) {
                csvWriterList.get(i).close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 功能:读取CSV文件
     *
     * @param readHeaders 是否要读文件头
     * @param filePath    文件路径
     * @return 返回读取的数据
     */
    static public List<String[]> readCsv(boolean readHeaders, String filePath) {
        List<String[]> contentHangs = new ArrayList<>();
        try {
            CsvReader csvReader = new CsvReader(filePath, ',', Charset.forName("GBK"));
            if (!readHeaders) {
                csvReader.readHeaders();
            }

            while (csvReader.readRecord()) {
                contentHangs.add(csvReader.getValues());
            }

            csvReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        int hang = 0;
        int lie = 0;
        log.info(String.format("第%s行第%s列的数据=%s", hang, lie, contentHangs.get(hang)[lie]));
        return contentHangs;
    }

    /**
     * 功能:数据清洗(读取一个旧文件的数据 清洗预期的数据后 再写入到一个新的文件中)
     * 备注:清洗逻辑需变更
     *
     * @param oldFilePath 原文件路径
     * @param newFilePath 清洗后的新文件路径
     */
    static public void readAndWriteCsv(String oldFilePath, String newFilePath) {
        /** 【清洗原理】从idb上导出的数据 有双引号引起来的 所以要清洗下数据 取双引号中间的数据*/
        // step1 读取文件 清洗数据
        List<String[]> read = readCsv(false, oldFilePath);
        List<String[]> newData = new ArrayList<>();
        for (int i = 0; i < read.size(); i++) {
            String[] substring = {read.get(i)[0].substring(0, read.get(i)[0].length())};
            newData.add(substring);
        }

        // step2 将清洗后的数据写入文件
        writeCsv(newFilePath, null, newData);
    }

}
View Code

 

代码 

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();
            }
        }
    }
}
posted @ 2020-01-21 16:26  淡怀  阅读(4870)  评论(5编辑  收藏  举报