java代碼實現liunx服務器(cpu、mem(內存)、jvm、堆/非堆、磁盤、服務器、java虛擬機)監控

廢話不多說 直接貼代碼。。。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ServerStateUtils {

    private static final Log logger = LogFactory.getLog(ServerStateUtils.class);
    // cpu、mem(物理內存)、swap(交換分區)命令
    public static final String CPU_MEM_SWAP_SHELL = "top -b -n 1";
    // 系統磁盤命令
    public static final String FILES_SHELL = "df -hl";
    public static final String[] COMMANDS = { CPU_MEM_SWAP_SHELL, FILES_SHELL };
    // liunx 行分隔符
    public static final String LINE_SEPARATOR = System.getProperty("line.separator");

    /**
     * 獲取服務器相關信息 cpu、內存、服務器信息、java虛擬機信息、堆/非堆
     * 
     * @return
     */
    public static Map<String, Map<String, String>> getServerStateInfo() {
        String osName = System.getProperty("os.name");
        if (osName.toLowerCase().startsWith("linux")) {
            return disposeResultMessage();
        }
        return null;
    }

    /**
     * 直接在本地執行 shell
     * 
     * @param commands
     *            執行的腳本
     * @return 執行結果信息
     */
    private static Map<String, String> runLocalShell(String[] commands) {
        Runtime runtime = Runtime.getRuntime();
        Map<String, String> map = new HashMap<>();
        StringBuilder stringBuffer;
        BufferedReader reader = null;
        Process process;
        try {
            for (String command : commands) {
                stringBuffer = new StringBuilder();
                process = runtime.exec(command);
                InputStream inputStream = process.getInputStream();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                String buf;
                while ((buf = reader.readLine()) != null) {
                    // 捨棄PID 進程信息
                    if (buf.contains("PID")) {
                        break;
                    }
                    stringBuffer.append(buf.trim()).append(LINE_SEPARATOR);
                }
                // 每個命令存儲自己返回數據-用於後續對返回數據進行處理
                map.put(command, stringBuffer.toString());
            }
        } catch (IOException e) {
            logger.error("獲取liunx服務器基本信息異常:" + e.getMessage());
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                logger.error("獲取liunx服務器基本信息過程中讀取流關閉異常:" + e.getMessage());
            }
        }
        return map;
    }

    /**
     * 處理 shell 返回的信息
     * 
     * 具體處理過程以服務器返回數據格式爲準 不同的Linux 版本返回信息格式不同
     *
     * @param result
     *            shell 返回的信息
     * @return 最終處理後的信息
     */
    private static Map<String, Map<String, String>> disposeResultMessage() {
        Map<String, String> result = runLocalShell(COMMANDS);
        if (result == null || result.size() < 1) {
            return null;
        }
        Map<String, Map<String, String>> resultMap = new HashMap<>();
        for (String command : COMMANDS) {
            String commandResult = result.get(command);
            if (null == commandResult) {
                continue;
            }
            if (CPU_MEM_SWAP_SHELL.equals(command)) {
                String[] strings = commandResult.split(LINE_SEPARATOR);
                for (String line : strings) {
                    Map<String, String> map = new HashMap<>();
                    // 轉大寫處理
                    line = line.toUpperCase();
                    line = line.replaceAll("\\s+", "");
                    if (line.contains("CPU(S):")) {
                        logger.info("cpu:"+line);
                        // cpu數據結果格式化:Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si,0.0%st
                        //用戶空間佔用CPU百分比,內核空間佔用CPU百分比,戶進程空間內改變過優先級的進程佔用CPU百分比,空閒CPU百分比
                        //等待輸入輸出的CPU時間百分比,等待輸入輸出的CPU時間百分比,硬件中斷,軟件中斷,實時
                        List<String> keysList = new ArrayList<>();
                        keysList.add("US");
                        keysList.add("SY");
                        keysList.add("NI");
                        keysList.add("ID");
                        keysList.add("WA");
                        keysList.add("HI");
                        keysList.add("SI");
                        keysList.add("ST");
                        String[] cpus = line.split(":")[1].split(",");
                        for (String value : cpus) {
                            for (int i = 0; i < keysList.size(); i++) {
                                String itemKey = keysList.get(i);
                                if(!value.contains(itemKey))continue;
                                String new_value = value.replace(itemKey, "").trim();
                                String keyLower = itemKey.toLowerCase();
                                map.put(keyLower, new_value);
                            }
                        }
                        map.put("count", Integer.toString(Runtime.getRuntime().availableProcessors()));
                        resultMap.put("cpu", map);
                    } else if (line.contains("MEM:")) {
                        logger.info("mem/swap:" + line);
                        // mem數據結果格式化:Mem: 32826948k total, 1360332k used, 31466616k free, 135952k
                        // 內存總計
                        String mem = line.split(":")[1].replaceAll("\\.", ",");
                        String[] mems = mem.split(",");
                        List<String> keysList = new ArrayList<>();
                        keysList.add("TOTAL");
                        keysList.add("USED");
                        keysList.add("FREE");
                        keysList.add("BUFFERS");
                        keysList.add("BUFF/CACHE");
                        for (String value : mems) {
                            for (int i = 0; i < keysList.size(); i++) {
                                String itemKey = keysList.get(i);
                                if(!value.contains(itemKey))continue;
                                String new_value = value.replace(itemKey, "").trim();
                                if (!new_value.contains("k")) new_value = new_value + "k";
                                String keyLower = itemKey.toLowerCase();
                                String new_value_unit = disposeUnit(new_value);
                                if(keyLower.contains("buffers") || keyLower.contains("buff/cache")) {
                                    map.put("buffers", new_value_unit);
                                }else {
                                    map.put(keyLower, new_value_unit);
                                }
                            }
                        }
                        resultMap.put("mem", map);
                    }
                }
            } else if (FILES_SHELL.equals(command)) {
                logger.info("disk:" + commandResult);
                String[] strings = commandResult.split(LINE_SEPARATOR);
                BigDecimal size = new BigDecimal(0);
                BigDecimal used = new BigDecimal(0);
                for (int i = 0; i < strings.length - 1; i++) {
                    if (i == 0)
                        continue;
                    String ss = strings[i].replaceAll("\\s+", ",");
                    String[] strs = ss.split(",");
                    if (strs.length == 1)
                        continue;
                    size = size.add(disposeUnitConvertG(strs[1]));
                    used = used.add(disposeUnitConvertG(strs[2]));
                }
                Map<String, String> map = new HashMap<>();
                // 磁盤總大小
                map.put("total", disposeUnit(size + "g"));
                // 磁盤已使用
                map.put("used", disposeUnit(used + "g"));
                // 磁盤空閒
                map.put("free", disposeUnit((size.subtract(used)) + "g"));
                resultMap.put("disk", map);
            }
        }
        // ===================jvm================

        Runtime jvm = Runtime.getRuntime();
        Map<String, String> map = new HashMap<>();
        // jvm 可以使用的總內存 以字節(B)爲單位
        String total = String.valueOf(jvm.totalMemory()/1024);
        if (!total.contains("k"))
            total = total + "k";
        map.put("total", disposeUnit(total));
        // jvm 空閒的內存
        String free = String.valueOf(jvm.freeMemory()/1024);
        if (!free.contains("k"))
            free = free + "k";
        map.put("free", disposeUnit(free));
        // jvm 已使用的內存
        String used = String.valueOf((jvm.totalMemory() - jvm.freeMemory())/1024);
        if (!used.contains("k"))
            used = used + "k";
        map.put("used", disposeUnit(used));
        logger.info("jvm:" + map.toString());
        resultMap.put("jvm", map);

        // ===================system================
        map = new HashMap<>();
        OperatingSystemMXBean system = ManagementFactory.getOperatingSystemMXBean();
        // 操作系統類型
        map.put("type", system.getName());
        // 操作系統架構
        map.put("arch", system.getArch());
        // 操作系統版本
        map.put("version", system.getVersion());
        // 服務器名稱
        String hostname = "localhost.unknow";
        try {
            hostname = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            logger.error("獲取服務器名稱異常:"+e.getMessage());
        }
        map.put("name", hostname);
        map.put("ip", getLinuxLocalIp());
        resultMap.put("system", map);

        // ===================java================
        map = new HashMap<>();
        RuntimeMXBean mxBean = ManagementFactory.getRuntimeMXBean();
        // java 的名稱
        map.put("name", System.getProperty("java.vm.name"));
        map.put("vendor",System.getProperty("java.vendor"));
        // java 的安裝路徑
        map.put("home", System.getProperty("java.home"));
        // java 的版本
        map.put("version",System.getProperty("java.version"));
        // java 啓動時間
        map.put("startTime", DateUtils.getDateString(new Date(mxBean.getStartTime())));
        // java 運行時間
        map.put("runTime", DateUtils.secToTime(Integer.valueOf(mxBean.getUptime() + "")));
        resultMap.put("java", map);
        // 堆與非堆
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        // 堆
        map = new HashMap<>();
        MemoryUsage heap = memoryMXBean.getHeapMemoryUsage();
        logger.info("Heap Memory Usage:"+heap);
        // 初始大小
        Long heapInit = heap.getInit();
        if(heapInit<0) {
            heapInit = 0L;
        }else {
            heapInit = heapInit / 1024;
        }
        map.put("heapInit", disposeUnit(heapInit + "k"));
        // 已用內存
        Long heapUsed = heap.getUsed();
        if(heapUsed<0) {
            heapUsed = 0L;
        }else {
            heapUsed = heapUsed / 1024;
        }
        map.put("heapUsed", disposeUnit(heapUsed + "k"));
        // 最大內存
        Long heapMax = heap.getMax();
        if(heapMax<0) {
            heapMax = 0L;
        }else {
            heapMax = heapMax / 1024;
        }
        map.put("heapMax", disposeUnit(heapMax + "k"));
        // 可用內存
        Long heapFree = heapMax - heapUsed;
        if(heapFree<0) {
            heapFree = 0L;
        }
        map.put("heapFree", disposeUnit(heapFree + "k"));
        resultMap.put("heap", map);
        
        // 非堆
        map = new HashMap<>();
        MemoryUsage nonHeap = memoryMXBean.getNonHeapMemoryUsage();
        logger.info("Non-Heap Memory Usage:"+nonHeap);
        // 初始大小
        Long noHeapInit = nonHeap.getInit();
        if(noHeapInit<0) {
            noHeapInit = 0L;
        }else {
            noHeapInit = noHeapInit / 1024;
        }
        map.put("noHeapInit", disposeUnit(noHeapInit + "k"));
        // 已用內存
        Long noHeapUsed = nonHeap.getUsed();
        if(noHeapUsed<0) {
            noHeapUsed = 0L;
        }else {
            noHeapUsed = noHeapUsed / 1024;
        }
        map.put("noHeapUsed", disposeUnit(noHeapUsed + "k"));
        // 最大內存
        Long noHeapMax = nonHeap.getMax();
        if(noHeapMax<0) {
            noHeapMax = 0L;
        }else {
            noHeapMax = noHeapMax / 1024;
        }
        map.put("noHeapMax", disposeUnit(noHeapMax + "k"));
        // 可用內存
        Long notheapfree = noHeapMax - noHeapUsed;
        if(notheapfree<0) {
            notheapfree = 0L;
        }
        map.put("noHeapFree", disposeUnit(notheapfree + "k"));
        resultMap.put("noheap", map);
        return resultMap;
    }

    /**
     * 處理單位轉換
     * 
     * @param s
     *            帶單位的數據字符串
     * 
     * @return 以K/KB/M/G/T爲單位處理後的數值
     */
    private static String disposeUnit(String s) {
        BigDecimal bg = new BigDecimal(0);
        try {
            s = s.toUpperCase();
            String lastIndex = s.substring(s.length() - 1);
            String num = s.substring(0, s.length() - 1);
            BigDecimal size = new BigDecimal(1024);
            bg = new BigDecimal(num);
            if ("K".equals(lastIndex) || "KB".equals(lastIndex)) {
                if (bg.compareTo(size) == 1 || bg.compareTo(size) == 0) {
                    s = (bg.divide(size)) + "m";
                    return disposeUnit(s);
                }
                s = bg.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue() + "KB";
                return s;
            } else if ("M".equals(lastIndex)) {
                if (bg.compareTo(size) == 1 || bg.compareTo(size) == 0) {
                    s = (bg.divide(size)) + "g";
                    return disposeUnit(s);
                }
                s = bg.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue() + "M";
                return s;
            } else if ("G".equals(lastIndex)) {
                if (bg.compareTo(size) == 1 || bg.compareTo(size) == 0) {
                    s = (bg.divide(size).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue()) + "T";
                    return s;
                }
                return bg.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue() + "G";
            }
        } catch (NumberFormatException e) {
            logger.error("獲取服務器內存大小單位轉換異常:" + e.getMessage());
            return bg + "k";
        }
        return bg + "k";
    }

    /**
     * 處理單位轉換 K/KB/M/T 最終轉換爲G 處理
     *
     * @param s
     *            帶單位的數據字符串
     * @return 以G 爲單位處理後的數值
     */
    private static BigDecimal disposeUnitConvertG(String s) {
        BigDecimal bg = new BigDecimal(0);
        try {
            s = s.toUpperCase();
            String lastIndex = s.substring(s.length() - 1);
            String num = s.substring(0, s.length() - 1);
            if (num.length() == 0)
                return bg;
            bg = new BigDecimal(num);
            BigDecimal size = new BigDecimal(1024);
            if (lastIndex.equals("G")) {
                return bg.setScale(3, BigDecimal.ROUND_HALF_UP);
            } else if (lastIndex.equals("T")) {
                return bg.multiply(size).setScale(3, BigDecimal.ROUND_HALF_UP);
            } else if (lastIndex.equals("M")) {
                return bg.divide(size).setScale(3, BigDecimal.ROUND_HALF_UP);
            } else if (lastIndex.equals("K") || lastIndex.equals("KB")) {
                size = size.multiply(size).setScale(3, BigDecimal.ROUND_HALF_UP);
                return bg.divide(size).setScale(3, BigDecimal.ROUND_HALF_UP);
            }
        } catch (NumberFormatException e) {
            logger.error("獲取服務器磁盤大小統一轉換成G異常:" + e.getMessage());
            return bg;
        }
        return bg;
    }
    
    /**
     * 獲取Linux下的IP地址
     *
     * @return IP地址
     * @throws SocketException
     */
    private static String getLinuxLocalIp(){
        String ip = "";
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                String name = intf.getName();
                if (!name.contains("docker") && !name.contains("lo")) {
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress()) {
                            String ipaddress = inetAddress.getHostAddress().toString();
                            if (!ipaddress.contains("::") && !ipaddress.contains("0:0:") && !ipaddress.contains("fe80")) {
                                ip = ipaddress;
                                System.out.println(ipaddress);
                            }
                        }
                    }
                }
            }
        } catch (SocketException ex) {
            logger.error("獲取服務器ip異常:"+ex.getMessage());
            ip = "127.0.0.1";
        }
        return ip;
    }
}

以上就是相關java代碼,有需要的拿去。。。我只是代碼的搬運工

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章