java 获取服务器CPU、内存、磁盘等信息,并发送邮件告警

777人浏览 / 0人评论

参考

java获取当前服务器状态cpu、内存、存储等核心信息_java 获取cpu信息_Benjamin℡的博客-CSDN博客

oshi/FAQ.md at master · oshi/oshi · GitHub

java实现简单发送邮件功能_java_脚本之家 (jb51.net)

依赖

<!--发送邮件API-->
<!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>javax.mail-api</artifactId>
    <version>1.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
<!-- cpu info -->
<dependency>
    <groupId>com.github.oshi</groupId>
    <artifactId>oshi-core</artifactId>
    <version>6.3.2</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.12.1</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>5.12.1</version>
</dependency>

DiskUsage.java

@Setter
@Getter
public class DiskUsage {
    /**
     * 总空间
     */
    private Double total;
    /**
     * 可用空间
     */
    private Double free;
    /**
     * 空闲空间
     */
    private Double un;
    /**
     * 磁盘
     */
    private String path;
}

CpuAndMemoryUsage.java

@Getter
@Setter
@ToString
public class CpuAndMemoryUsage {
    /**
     * 初始的总内存(JVM)
     */
    private Long initTotalMemorySize;
    /**
     * 最大可用内存(JVM)
     */
    private Long maxMemorySize;
    /**
     * 已使用的内存(JVM)
     */
    private Long usedMemorySize;
    /**
     * 操作系统
     */
    private String osName;
    /**
     * 总的物理内存
     */
    private Long totalPhysicalMemorySize;
    /**
     * 剩余的物理内存
     */
    private Long freePhysicalMemorySize;
    /**
     * 已使用的物理内存
     */
    private Long usedPhysicalMemorySize;
    /**
     * 线程总数
     */
    private Integer totalThread;
    /**
     * 程序启动时间
     */
    private String programStartTime;
    private String pid;
    /**
     * cpu核数
     */
    private Integer logicalProcessorCount;
    /**
     * cpu系统使用率
     */
    private Double cpuSystem;
    /**
     * cpu用户使用率
     */
    private Double cpuUser;
    /**
     * cpu当前等待率
     */
    private Double cpuWait;
    /**
     * cpu当前空闲率
     */
    private Double cpuIdle;
    /**
     * cpu利用率
     */
    private Double cpuUtilization;
    private String cpuLoadBetweenTicks;
    private String cpuLoad;
    private String javaHome;
    private String javaVersion;
    private String userHome;
    private String userName;
    /**
     * 处理器信息
     */
    private CentralProcessor.ProcessorIdentifier processorIdentifier;
}

EmailException.java

public class EmailException extends Exception {
    public EmailException(String message) {
        super(message);
    }
    public EmailException() {
        super();
    }
    private static final long serialVersionUID = 115631651651651651L;
}

CPUInfo.java

import com.sun.management.OperatingSystemMXBean;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.util.GlobalConfig;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class CPUInfo {
    /***
     * 获取系统详细参数信息
     */
    public static String getSystemInfo(List<DiskUsage> diskUsages, CpuAndMemoryUsage usage) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            if (diskUsages != null && !diskUsages.isEmpty()) {
                // 磁盘使用情况
                stringBuilder.append(":::::::::::::::::磁盘使用情况:::::::::::::::::\n");
                for (DiskUsage diskUsage : diskUsages) {
                    String total = new DecimalFormat("#.#").format(diskUsage.getTotal()) + "G";
                    String free = new DecimalFormat("#.#").format(diskUsage.getFree()) + "G";
                    String un = new DecimalFormat("#.#").format(diskUsage.getUn()) + "G";
                    String path = diskUsage.getPath();
                    stringBuilder.append(path).append(" 总:").append(total).append(",可用空间:").append(un).append(",空闲空间:").append(free).append("\n");
                }
                stringBuilder.append("\n");
            }
            if (usage == null) return stringBuilder.toString();
            stringBuilder.append(":::::::::::::::::操作系统详情:::::::::::::::::\n");
            stringBuilder.append("操作系统:").append(usage.getOsName()).append("\n");
            stringBuilder.append("程序启动时间:").append(usage.getProgramStartTime()).append("\n");
            stringBuilder.append("pid:").append(getPID()).append("\n");
            stringBuilder.append("cpu核数:").append(usage.getLogicalProcessorCount()).append("\n");
            stringBuilder.append("cpu系统使用率:").append(new DecimalFormat("#.##%").format(usage.getCpuSystem())).append("\n");
            stringBuilder.append("cpu用户使用率:").append(new DecimalFormat("#.##%").format(usage.getCpuUser())).append("\n");
            stringBuilder.append("cpu当前等待率:").append(new DecimalFormat("#.##%").format(usage.getCpuWait())).append("\n");
            stringBuilder.append("cpu当前空闲率:").append(new DecimalFormat("#.##%").format(usage.getCpuIdle())).append("\n");
            stringBuilder.append("cpu利用率:").append(new DecimalFormat("#.##%").format(usage.getCpuUtilization())).append("\n");
            stringBuilder.append("CPU load: ").append(usage.getCpuLoadBetweenTicks());
            stringBuilder.append("CPU load: ").append(usage.getCpuLoad()).append("\n");
            stringBuilder.append("\n");

            stringBuilder.append(":::::::::::::::::堆栈内存信息:::::::::::::::::\n");
            stringBuilder.append("JAVA_HOME:").append(usage.getJavaHome()).append("\n");
            stringBuilder.append("JAVA_VERSION:").append(usage.getJavaVersion()).append("\n");
            stringBuilder.append("USER_HOME:").append(usage.getUserHome()).append("\n");
            stringBuilder.append("USER_NAME:").append(usage.getUserName()).append("\n");
            stringBuilder.append("初始的总内存(JVM):").append(new DecimalFormat("#.#").format(usage.getInitTotalMemorySize() * 1.0 / 1024 / 1024)).append("M\n");
            stringBuilder.append("最大可用内存(JVM):").append(new DecimalFormat("#.#").format(usage.getMaxMemorySize() * 1.0 / 1024 / 1024)).append("M\n");
            stringBuilder.append("已使用的内存(JVM):").append(new DecimalFormat("#.#").format(usage.getUsedMemorySize() * 1.0 / 1024 / 1024)).append("M\n");
            stringBuilder.append("总的物理内存:").append(new DecimalFormat("#.##").format(usage.getTotalPhysicalMemorySize() / 1024.0 / 1024 / 1024)).append("G\n");
            stringBuilder.append("剩余的物理内存:").append(new DecimalFormat("#.##").format(usage.getFreePhysicalMemorySize() / 1024.0 / 1024 / 1024)).append("G\n");
            stringBuilder.append("已使用的物理内存:").append(new DecimalFormat("#.##").format(usage.getUsedPhysicalMemorySize() / 1024.0 / 1024 / 1024)).append("G\n");
            stringBuilder.append("总线程数:").append(usage.getTotalThread()).append("\n");
            stringBuilder.append("\n");

            stringBuilder.append(":::::::::::::::::处理器信息:::::::::::::::::\n");
            CentralProcessor.ProcessorIdentifier processorIdentifier = usage.getProcessorIdentifier();
            stringBuilder.append("vendor: ").append(processorIdentifier.getVendor()).append("\n");
            stringBuilder.append("name: ").append(processorIdentifier.getName()).append("\n");
            stringBuilder.append("family: ").append(processorIdentifier.getFamily()).append("\n");
            stringBuilder.append("model: ").append(processorIdentifier.getModel()).append("\n");
            stringBuilder.append("stepping: ").append(processorIdentifier.getStepping()).append("\n");
            stringBuilder.append("processorID: ").append(processorIdentifier.getProcessorID()).append("\n");
            stringBuilder.append("identifier: ").append(processorIdentifier.getIdentifier()).append("\n");
            stringBuilder.append("vendorFreq: ").append(processorIdentifier.getVendorFreq()).append("\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }

    /**
     * 获取磁盘使用情况
     */
    public static List<DiskUsage> getDiskUsage() {
        List<DiskUsage> data = new ArrayList<>();
        File[] files = File.listRoots();
        for (File file : files) {
            DiskUsage diskUsage = new DiskUsage();
            diskUsage.setTotal(file.getTotalSpace() * 1.0 / 1024 / 1024 / 1024);
            diskUsage.setFree(file.getFreeSpace() * 1.0 / 1024 / 1024 / 1024);
            diskUsage.setUn(file.getUsableSpace() * 1.0 / 1024 / 1024 / 1024);
            diskUsage.setPath(file.getPath());
            data.add(diskUsage);
        }
        return data;
    }

    /**
     * 获取CPU、内存信息
     */
    public static CpuAndMemoryUsage getCpuAndMemoryUsage() throws InterruptedException {
        CpuAndMemoryUsage usage = new CpuAndMemoryUsage();
        SystemInfo systemInfo = new SystemInfo();
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        // 椎内存使用情况
        MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();
        // 初始的总内存
        usage.setInitTotalMemorySize(memoryUsage.getInit());
        // 最大可用内存
        usage.setMaxMemorySize(memoryUsage.getMax());
        // 已使用的内存
        usage.setUsedMemorySize(memoryUsage.getUsed());
        // 操作系统
        usage.setOsName(System.getProperty("os.name"));
        // 总的物理内存
        //usage.setTotalPhysicalMemorySize(systemInfo.getHardware().getMemory().getTotal() * 1.0 / 1024 / 1024 / 1024);
        usage.setTotalPhysicalMemorySize(osmxb.getTotalPhysicalMemorySize());
        // 剩余的物理内存
        //usage.setFreePhysicalMemorySize(systemInfo.getHardware().getMemory().getAvailable() * 1.0 / 1024 / 1024 / 1024);
        usage.setFreePhysicalMemorySize(osmxb.getFreePhysicalMemorySize());
        // 已使用的物理内存
        //usage.setUsedPhysicalMemorySize((systemInfo.getHardware().getMemory().getTotal() - systemInfo.getHardware().getMemory().getAvailable()) * 1.0 / 1024 / 1024 / 1024);
        usage.setUsedPhysicalMemorySize(osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize());
        // 获得线程总数
        ThreadGroup parentThread = Thread.currentThread().getThreadGroup();
        while (parentThread.getParent() != null) {
            parentThread = parentThread.getParent();
        }
        usage.setTotalThread(parentThread.activeCount());
        usage.setProgramStartTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(ManagementFactory.getRuntimeMXBean().getStartTime())));
        usage.setPid(getPID());
        GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true);
        CentralProcessor processor = systemInfo.getHardware().getProcessor();
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        // 睡眠1s
        TimeUnit.SECONDS.sleep(1);
        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
        long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
        long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
        // cpu核数
        usage.setLogicalProcessorCount(processor.getLogicalProcessorCount());
        // cpu系统使用率
        usage.setCpuSystem(cSys * 1.0 / totalCpu);
        // cpu用户使用率
        usage.setCpuUser(user * 1.0 / totalCpu);
        // cpu当前等待率
        usage.setCpuWait(iowait * 1.0 / totalCpu);
        // cpu当前空闲率
        usage.setCpuIdle(idle * 1.0 / totalCpu);
        long cpuUtilization = user + nice + cSys + iowait + irq + softirq + steal;
        // cpu利用率
        usage.setCpuUtilization(cpuUtilization * 1.0 / totalCpu);
        long[] ticksArray = {1, 2, 3, 4, 5, 6, 7, 8};
        usage.setCpuLoadBetweenTicks(String.format("%.1f%% (counting ticks)%n", processor.getSystemCpuLoadBetweenTicks(ticksArray) * 100));
        usage.setCpuLoad(String.format("%.1f%% (OS MXBean)%n", processor.getSystemCpuLoad(1L) * 100));
        usage.setJavaHome(System.getProperty("java.home"));
        usage.setJavaVersion(System.getProperty("java.version"));
        usage.setUserHome(System.getProperty("user.home"));
        usage.setUserName(System.getProperty("user.name"));
        usage.setProcessorIdentifier(processor.getProcessorIdentifier());
        return usage;
    }


    public static void initSystemInfo() {
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            try {
                SystemInfo systemInfo = new SystemInfo();
                OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
                MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
                // 椎内存使用情况
                MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();

                // 初始的总内存
                long initTotalMemorySize = memoryUsage.getInit();
                // 最大可用内存
                long maxMemorySize = memoryUsage.getMax();
                // 已使用的内存
                long usedMemorySize = memoryUsage.getUsed();

                // 操作系统
                String osName = System.getProperty("os.name");
                // 总的物理内存
                String totalMemorySize = new DecimalFormat("#.##").format(osmxb.getTotalPhysicalMemorySize() / 1024.0 / 1024 / 1024) + "G";
                // 剩余的物理内存
                String freePhysicalMemorySize = new DecimalFormat("#.##").format(osmxb.getFreePhysicalMemorySize() / 1024.0 / 1024 / 1024) + "G";
                // 已使用的物理内存
                String usedMemory = new DecimalFormat("#.##").format((osmxb.getTotalPhysicalMemorySize() - osmxb.getFreePhysicalMemorySize()) / 1024.0 / 1024 / 1024) + "G";
                // 获得线程总数
                ThreadGroup parentThread;
                for (parentThread = Thread.currentThread().getThreadGroup(); parentThread
                        .getParent() != null; parentThread = parentThread.getParent()) {

                }

                int totalThread = parentThread.activeCount();

                // 磁盘使用情况
                File[] files = File.listRoots();
                for (File file : files) {
                    String total = new DecimalFormat("#.#").format(file.getTotalSpace() * 1.0 / 1024 / 1024 / 1024) + "G";
                    String free = new DecimalFormat("#.#").format(file.getFreeSpace() * 1.0 / 1024 / 1024 / 1024) + "G";
                    String un = new DecimalFormat("#.#").format(file.getUsableSpace() * 1.0 / 1024 / 1024 / 1024) + "G";
                    String path = file.getPath();
                    System.err.println(path + "总:" + total + ",可用空间:" + un + ",空闲空间:" + free);
                    System.err.println("=============================================");
                }

                System.err.println("操作系统:" + osName);
                System.err.println("程序启动时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(ManagementFactory.getRuntimeMXBean().getStartTime())));
                /// System.err.println("pid:" + System.getProperty("PID"));
                System.err.println("pid:" + getPID());
                System.err.println("cpu核数:" + Runtime.getRuntime().availableProcessors());
                printlnCpuInfo(systemInfo);
                System.err.println("JAVA_HOME:" + System.getProperty("java.home"));
                System.err.println("JAVA_VERSION:" + System.getProperty("java.version"));
                System.err.println("USER_HOME:" + System.getProperty("user.home"));
                System.err.println("USER_NAME:" + System.getProperty("user.name"));
                System.err.println("初始的总内存(JVM):" + new DecimalFormat("#.#").format(initTotalMemorySize * 1.0 / 1024 / 1024) + "M");
                System.err.println("最大可用内存(JVM):" + new DecimalFormat("#.#").format(maxMemorySize * 1.0 / 1024 / 1024) + "M");
                System.err.println("已使用的内存(JVM):" + new DecimalFormat("#.#").format(usedMemorySize * 1.0 / 1024 / 1024) + "M");
                System.err.println("总的物理内存:" + totalMemorySize);
                System.err.println("总的物理内存:" + new DecimalFormat("#.##").format(systemInfo.getHardware().getMemory().getTotal() * 1.0 / 1024 / 1024 / 1024) + "M");
                System.err.println("剩余的物理内存:" + freePhysicalMemorySize);
                System.err.println("剩余的物理内存:" + new DecimalFormat("#.##").format(systemInfo.getHardware().getMemory().getAvailable() * 1.0 / 1024 / 1024 / 1024) + "M");
                System.err.println("已使用的物理内存:" + usedMemory);
                System.err.println("已使用的物理内存:" + new DecimalFormat("#.##").format((systemInfo.getHardware().getMemory().getTotal() - systemInfo.getHardware().getMemory().getAvailable()) * 1.0 / 1024 / 1024 / 1024) + "M");
                System.err.println("总线程数:" + totalThread);
                System.err.println("===========================");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, 0, 60, TimeUnit.SECONDS);


    }

    /**
     * 打印 CPU 信息
     */
    private static void printlnCpuInfo(SystemInfo systemInfo) throws InterruptedException {

        // todo 解决 Why does OSHI's System and Processor CPU usage differ from the Windows Task Manager?
        GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true);

        CentralProcessor processor = systemInfo.getHardware().getProcessor();
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        // 睡眠1s
        TimeUnit.SECONDS.sleep(1);
        long[] ticks = processor.getSystemCpuLoadTicks();
        long nice = ticks[CentralProcessor.TickType.NICE.getIndex()] - prevTicks[CentralProcessor.TickType.NICE.getIndex()];
        long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()] - prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
        long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()] - prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
        long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()] - prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
        long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()] - prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
        long user = ticks[CentralProcessor.TickType.USER.getIndex()] - prevTicks[CentralProcessor.TickType.USER.getIndex()];
        long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()] - prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
        long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()] - prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
        System.err.println("cpu核数:" + processor.getLogicalProcessorCount());
        System.err.println("cpu系统使用率:" + new DecimalFormat("#.##%").format(cSys * 1.0 / totalCpu));
        System.err.println("cpu用户使用率:" + new DecimalFormat("#.##%").format(user * 1.0 / totalCpu));
        System.err.println("cpu当前等待率:" + new DecimalFormat("#.##%").format(iowait * 1.0 / totalCpu));
        System.err.println("cpu当前空闲率:" + new DecimalFormat("#.##%").format(idle * 1.0 / totalCpu));

        // todo cup利用
        //  user + system + nice + iowait + irq + softirq + steal
        long cpuUtilization = user + nice + cSys + iowait + irq + softirq + steal;
        System.err.println("cpu利用率:" + new DecimalFormat("#.##%").format(cpuUtilization * 1.0 / totalCpu));

        // hutool工具,底层用的也是oshi
		/*
		GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true);
		cn.hutool.system.oshi.CpuInfo cpuInfo = OshiUtil.getCpuInfo();
		double free = cpuInfo.getFree();
		DecimalFormat format = new DecimalFormat("#.00");
		System.out.println("cpu利用率:" + Double.parseDouble(format.format(100.0D - free)));
		*/

        /// 低版本这两个方法是无参方法,高版本中是需要有参数的
        //System.err.format("CPU load: %.1f%% (counting ticks)%n", processor.getSystemCpuLoadBetweenTicks(ticksArray) * 100);
        //System.err.format("CPU load: %.1f%% (OS MXBean)%n", processor.getSystemCpuLoad(1L) * 100);
        long[] ticksArray = {1, 2, 3, 4, 5, 6, 7, 8};
        System.err.format("CPU load: %.1f%% (counting ticks)%n", processor.getSystemCpuLoadBetweenTicks(ticksArray) * 100);
        System.err.format("CPU load: %.1f%% (OS MXBean)%n", processor.getSystemCpuLoad(1L) * 100);

        ProcessorIdentifierInfo(processor);
    }


    /**
     * 获取进程id
     */
    public static String getPID() {
        String name = ManagementFactory.getRuntimeMXBean().getName();
        return name.split("@")[0];
    }

    public static void ProcessorIdentifierInfo(CentralProcessor processor) {
        CentralProcessor.ProcessorIdentifier processorIdentifier = processor.getProcessorIdentifier();
        String vendor = processorIdentifier.getVendor();
        String name = processorIdentifier.getName();
        String family = processorIdentifier.getFamily();
        String model = processorIdentifier.getModel();
        String stepping = processorIdentifier.getStepping();
        String processorID = processorIdentifier.getProcessorID();
        // cpu64bit ? "Intel64" : "x86"
        // Intel64 Family 6 Model 142 Stepping 12
        String identifier = processorIdentifier.getIdentifier();
        long vendorFreq = processorIdentifier.getVendorFreq();
        System.out.println("vendor: " + vendor);
        // 处理器名字
        System.out.println("name: " + name);
        System.out.println("family: " + family);
        System.out.println("model: " + model);
        System.out.println("stepping: " + stepping);
        System.out.println("processorID: " + processorID);
        System.out.println("identifier: " + identifier);
        System.out.println("vendorFreq: " + vendorFreq);
    }
}

SendMailUtil.java

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.Date;
import java.util.Properties;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import com.sun.mail.util.MailSSLSocketFactory;

public class SendMailUtil {
    // smtp服务器
    private String HOST = "";
    // 用户名
    private String USER = "";
    // 授权码
    private String PWD = "";
    // 发件人地址
    private String FROM = "";
    // 收件人地址
    private String[] TOS = null;
    // 附件地址
    private String[] AFFIX = null;
    private Properties props = null;

    /**
     * @param USER 账户名
     * @param PWD  密码
     * @param FROM 发件人地址
     */
    public SendMailUtil(String USER, String PWD, String FROM) throws EmailException, GeneralSecurityException {
        this.USER = USER;
        this.PWD = PWD;
        this.FROM = FROM;
        initProperties();
    }

    private void initProperties() throws EmailException, GeneralSecurityException {
        props = new Properties();
        if (FROM == null || FROM.length() == 0) {
            throw new EmailException("邮箱账号不能为空");
        } else {
            if (FROM.contains("@qq")) {
                HOST = "smtp.qq.com";
            } else if (FROM.contains("@163")) {
                HOST = "smtp.163.com";
            } else if (FROM.contains("@sina")) {
                HOST = "smtp.sina.com.cn";
            } else if (FROM.contains("@jbritian")) {
                HOST = "mail.jbritian.com";
            } else {
                throw new EmailException("不支持该协议");
            }
            // 设置邮件服务器主机名
            props.setProperty("mail.host", HOST);
        }
        if (PWD == null || PWD.length() == 0) throw new EmailException("邮箱密码不能为空");
        // 发送邮件协议名称
        props.setProperty("mail.transport.protocol", "smtp");
        // 需要经过授权,也就是有户名和密码的校验,这样才能通过验证(一定要有这一条)
        props.setProperty("mail.smtp.auth", "true");
        // 设置debug模式 后台输出邮件发送的过程
        // props.put("mail.debug", "true");

        //ssl加密
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.smtp.ssl.socketFactory", sf);
    }

    /**
     * 添加附件
     * @param path 需要添加附件的文件路径
     */
    public void addFile(String... path) throws EmailException {
        if (path == null || path.length == 0) throw new EmailException("附件路径不能为空");
        this.AFFIX = path;
    }

    /**
     * 设置收件人
     * @param to address1,address2...
     */
    public void setTo(String... to) throws EmailException {
        if (toString().length() > 0) {
            for (String t : to) {
                boolean emailFormat = emailFormat(t);
                if (!emailFormat) {
                    throw new EmailException(t + "邮箱格式不正确");
                }
            }
            TOS = to;
        } else {
            throw new EmailException("收件人不能为空");
        }
    }

    /**
     * * 验证输入的邮箱格式是否符合
     *
     * @return 是否合法
     */
    private boolean emailFormat(String email) {
        boolean tag = true;
        final String pattern1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        final Pattern pattern = Pattern.compile(pattern1);
        final Matcher mat = pattern.matcher(email);
        if (!mat.find()) {
            tag = false;
        }
        return tag;
    }

    /**
     * 发送邮件
     * @param subject 标题
     * @param context 文本信息
     */
    public void send(String subject, String context) throws EmailException, MessagingException, GeneralSecurityException, UnsupportedEncodingException {
        if (subject == null || subject.length() == 0) subject = UUID.randomUUID().toString();
        if (TOS.length == 0) throw new EmailException("收件人不能为空");
        // 用props对象构建一个session
        Session session = Session.getInstance(props);
        // session.setDebug(true);//关闭控制台输出

        //用session为参数定义消息对象
        MimeMessage message = new MimeMessage(session);
        // 加载发件人地址
        message.setFrom(new InternetAddress(FROM, USER));
        // 加载收件人地址
        InternetAddress[] sendTo = new InternetAddress[TOS.length];
        for (int i = 0; i < TOS.length; i++) {
            sendTo[i] = new InternetAddress(TOS[i]);
        }
        message.addRecipients(Message.RecipientType.TO, sendTo);
        //设置在发送给收信人之前给自己(发送方)抄送一份,不然会被当成垃圾邮件,报554错
        message.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(FROM));
        //加载标题
        message.setSubject(subject);
        //向 multipart 对象中添加邮件的各个部分内容,包括文本内容和附件
        Multipart multipart = new MimeMultipart();
        //设置邮件的文本内容
        BodyPart contentPart = new MimeBodyPart();
        contentPart.setText(context);
        multipart.addBodyPart(contentPart);
        if (AFFIX != null && AFFIX.length > 0) {//添加附件
            for (String affix : AFFIX) {
                File file = new File(affix);
                if (file.exists()) {
                    BodyPart messageBodyPart = new MimeBodyPart();
                    FileDataSource source = new FileDataSource(file);
                    //添加附件的内容
                    messageBodyPart.setDataHandler(new DataHandler(source));
                    messageBodyPart.setFileName(MimeUtility.encodeWord(file.getName(), "GBK", null));
                    multipart.addBodyPart(messageBodyPart);
                } else {
                    throw new EmailException("文件" + affix + "不存在");
                }
            }
        }
        //将multipart对象放到message中
        message.setContent(multipart);
        //保存邮件
        message.saveChanges();
        //发送邮件
        Transport transport = session.getTransport();
        //连接服务器的邮箱
        transport.connect(HOST, FROM, PWD);
        //把邮件发送出去
        transport.sendMessage(message, message.getAllRecipients());
        //关闭连接
        transport.close();
    }

    /**
     * 转发邮件
     * @param message 接收的邮件
     */
    public void forwardMail(Message message) throws MessagingException, EmailException, IOException {
        if (TOS.length == 0) throw new EmailException("收件人不能为空");
        //用props对象构建一个session
        Session session = Session.getInstance(props);
        // 关闭控制台输出
        // session.setDebug(true);

        //用session为参数定义消息对象
        MimeMessage newMessage = new MimeMessage(session);
        newMessage.setSubject(message.getSubject());
        newMessage.setFrom(new InternetAddress(FROM, USER));
        newMessage.setSentDate(new Date());
        newMessage.setContent(message.getContent(), message.getContentType());
        // 加载收件人地址
        InternetAddress[] sendTo = new InternetAddress[TOS.length];
        for (int i = 0; i < TOS.length; i++) {
            sendTo[i] = new InternetAddress(TOS[i]);
        }
        newMessage.addRecipients(Message.RecipientType.TO, sendTo);
        //设置在发送给收信人之前给自己(发送方)抄送一份,不然会被当成垃圾邮件,报554错
        newMessage.addRecipients(MimeMessage.RecipientType.CC, InternetAddress.parse(FROM));
        Transport smtp = session.getTransport("smtp");
        smtp.connect(HOST, FROM, PWD);
        smtp.sendMessage(newMessage, newMessage.getAllRecipients());
        smtp.close();
    }
}

Main.java

import javax.mail.MessagingException;
import java.io.*;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @Author FengHao
 * @Date 2023/3/24
 * @Description:
 **/
public class Main {
    public static void main(String[] args) {
        String user = "用户名";
        String pwd = "密码";
        String from = "发送方邮件地址";
        String to = "接收方邮件地址";
        // 磁盘监控
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            try {
                List<String> paths = new ArrayList<>();
                for (DiskUsage diskUsage : CPUInfo.getDiskUsage()) {
                    double value = diskUsage.getFree() / diskUsage.getTotal();
                    if (value < 0.01) {
                        paths.add(diskUsage.getPath());
                    }
                }
                if (!paths.isEmpty()) {
                    SendMailUtil mail = new SendMailUtil(user, pwd, from);
                    mail.setTo(to);
                    mail.send("磁盘" + paths + "容量不足", CPUInfo.getSystemInfo(CPUInfo.getDiskUsage(), CPUInfo.getCpuAndMemoryUsage()));
                    paths.clear();
                }
            } catch (MessagingException | UnsupportedEncodingException | EmailException | GeneralSecurityException |
                     InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, 0, 5, TimeUnit.HOURS);

        // 内存监控
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            int count = 0;
            try {
                CpuAndMemoryUsage usage = CPUInfo.getCpuAndMemoryUsage();
                double value = usage.getFreePhysicalMemorySize() * 1.0 / usage.getTotalPhysicalMemorySize();
                while (value < 0.01 && count < 10) {
                    count++;
                    Thread.sleep(1000 * 60);
                    usage = CPUInfo.getCpuAndMemoryUsage();
                    value = usage.getFreePhysicalMemorySize() * 1.0 / usage.getTotalPhysicalMemorySize();
                }
                if (value < 0.01) {
                    SendMailUtil mail = new SendMailUtil(user, pwd, from);
                    mail.setTo(to);
                    mail.send("服务器内存不足", CPUInfo.getSystemInfo(CPUInfo.getDiskUsage(), usage));
                }
            } catch (MessagingException | UnsupportedEncodingException | EmailException | GeneralSecurityException |
                     InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                count = 0;
            }
        }, 0, 1, TimeUnit.HOURS);

        // JVM监控
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            int count = 0;
            try {
                CpuAndMemoryUsage usage = CPUInfo.getCpuAndMemoryUsage();
                double value = 1 - usage.getUsedMemorySize() * 1.0 / usage.getMaxMemorySize();
                while (value < 0.01 && count < 10) {
                    count++;
                    Thread.sleep(1000 * 60);
                    usage = CPUInfo.getCpuAndMemoryUsage();
                    value = usage.getUsedMemorySize() * 1.0 / usage.getMaxMemorySize();
                }
                if (value < 0.01) {
                    SendMailUtil mail = new SendMailUtil(user, pwd, from);
                    mail.setTo(to);
                    mail.send("JVM堆栈溢出", CPUInfo.getSystemInfo(CPUInfo.getDiskUsage(), usage));
                }
            } catch (MessagingException | UnsupportedEncodingException | EmailException | GeneralSecurityException |
                     InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                count = 0;
            }
        }, 0, 1, TimeUnit.HOURS);

        // CPU监控
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            int count = 0;
            try {
                Double cpuUtilization = CPUInfo.getCpuAndMemoryUsage().getCpuUtilization();
                while (cpuUtilization >= 0.98 && count < 10) {
                    count++;
                    Thread.sleep(1000 * 60);
                    cpuUtilization = CPUInfo.getCpuAndMemoryUsage().getCpuUtilization();
                    if (cpuUtilization < 0.9) {
                        break;
                    }
                }
                if (CPUInfo.getCpuAndMemoryUsage().getCpuUtilization() >= 0.98) {
                    SendMailUtil mail = new SendMailUtil(user, pwd, from);
                    mail.setTo(to);
                    mail.send("CPU满载", CPUInfo.getSystemInfo(CPUInfo.getDiskUsage(), CPUInfo.getCpuAndMemoryUsage()));
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                count = 0;
            }
        }, 0, 1, TimeUnit.HOURS);

        // java CPU监控
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
            int count = 0;
            try {
                Double cpuJava = javaCpuUsage();
                while (cpuJava > 90 && count < 10) {
                    count++;
                    Thread.sleep(1000 * 10);
                    cpuJava = javaCpuUsage();
                }
                if (count >= 10) {
                    SendMailUtil mail = new SendMailUtil(user, pwd, from);
                    mail.setTo(to);
                    mail.send("jpress CPU满载",  "使用率:"+ cpuJava + "\n"+ CPUInfo.getSystemInfo(CPUInfo.getDiskUsage(), CPUInfo.getCpuAndMemoryUsage()));
                    // 摆烂做法,杀掉进程然后重启
                    killAndStart();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                count = 0;
            }
        }, 0, 10, TimeUnit.MINUTES);
    }

    private static void killAndStart() throws Exception {
        String[] ks = {"kill -9 `jps | grep 'Starter' | awk '{print $1}'`", "/root/jpress/jpress.sh start"};
        for (String str : ks) {
            String[] cmd = {"/bin/sh", "-c", str};
            Process pro = Runtime.getRuntime().exec(cmd);
            pro.waitFor();
            try (InputStream in = pro.getInputStream();
                 InputStreamReader reader = new InputStreamReader(in);
                 BufferedReader read = new BufferedReader(reader);) {
                String line;
                while ((line = read.readLine()) != null) {
                    System.out.println(line);
                }
            }
        }
    }

    private static Double javaCpuUsage() throws Exception {
        String[] cmd = {"/bin/sh", "-c", "top -p `jps | grep 'Starter' | awk '{print $1}'` -b -n 1 -d 5 > info.txt | sed -n '8,8p' info.txt | awk '{print $9}'"};
        Process pro = Runtime.getRuntime().exec(cmd);
        pro.waitFor();
        double cpuUsage = 0;
        try (InputStream in = pro.getInputStream();
            InputStreamReader reader = new InputStreamReader(in);
            BufferedReader read = new BufferedReader(reader);) {
            String line;
            while ((line = read.readLine()) != null) {
                cpuUsage = Double.parseDouble(line);
            }
        }
        return cpuUsage;
    }

}

全部评论