【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); } }
代码
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(); } } } }
如果忍耐算是坚强 我选择抵抗 如果妥协算是努力 我选择争取