单元 4: 监测 CPU 负载


通过指定的时间间隔采集 PC 系统数据,可以监控 PC的 CPU 负载,并在 CPU 负载超过设置的阈值(例如50%)时报告 CPU 负载事件。


在本单元中,更新 单元 3 中使用的程序,增加监控CPU负载的功能。

  1. 声明函数 monitor() 以监控 CPU 负载,参考以下代码示例:

    public static void main(String[] args) throws Exception {
        connect();
        updateAttribute();
        monitor();
    }
    


  2. 编写 monitor() 函数,以指定的时间间隔(例如,每 10 秒)将 PC 系统数据上传到 EnOS 云端并监视 CPU 负载(例如,cpu_load>0.2)。参考以下代码示例:

    public static void monitor() throws Exception {
        long lastReportTs=0;
        while (true) {
            Map<String, Object> systemInfo= collectDeviceInfo();
            postMeasurepoint(systemInfo);
    
            double cpu_load= (double) systemInfo.get("cpu_used");
            if (cpu_load>0.2) {
                long ts = System.currentTimeMillis();
    
                if ((ts-lastReportTs)>(60*1000)) {
                    lastReportTs=ts;
                    reportCPULoadEvent(cpu_load, "[Warning] CPU load: "+ cpu_load);
                }else{
                    System.out.println("[Warning] No reporting required, CPULoadEvent: " + cpu_load);
                }
            }
    
            Thread.sleep(interval*1000);
        }
    }
    


  3. 编写 reportCPULoadEvent() 函数,以在 CPU 负载超过阈值时报告 CPU 负载事件。参考以下代码示例:

    public static void reportCPULoadEvent(double value, String describe) {
        EventPostRequest request=EventPostRequest.builder()
                .setQos(0)
                .setEventIdentifier("cpu_event")
                .addValue("value", value)
                .addValue("message", describe)
                .build();
        System.out.println(">>> Post Event: "+request);
    
        try {
            EventPostResponse resp = client.publish(request);
            System.out.println("<-- " + resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    


  4. 编译并运行程序以进行设备连接、数据采集、和 CPU 负载事件报告。参考以下程序代码示例:

    import java.util.HashMap;
    import java.util.Map;
    
    import com.envisioniot.enos.iot_mqtt_sdk.core.ConnCallback;
    import com.envisioniot.enos.iot_mqtt_sdk.core.MqttClient;
    import com.envisioniot.enos.iot_mqtt_sdk.core.exception.EnvisionException;
    import com.envisioniot.enos.iot_mqtt_sdk.message.upstream.tsl.*;
    import oshi.hardware.HardwareAbstractionLayer;
    import oshi.software.os.OperatingSystem;
    
    public class Sample {
    
        private static final String uri = "tcp://{host}:{port}";
        private static final String productKey = "product_key";
        private static final String deviceKey = "device_key";
        private static final String deviceSecret = "device_secret";
    
        private static MqttClient client;
        private static int interval=5; // 10s
    
        public static void main(String[] args) throws Exception {
            connect();
            updateAttribute();
            monitor();
    
        }
    
        // Device connection initialization
        public static void connect() {
            System.out.println("start connect with callback ... ");
            try {
                client = new MqttClient(uri, productKey, deviceKey, deviceSecret);
                client.getProfile().setConnectionTimeout(60).setAutoReconnect(true);
                client.connect(new ConnCallback() {
                    @Override
                    public void connectComplete(boolean reconnect) {
                        System.out.println("connect success");
                    }
    
                    @Override
                    public void connectLost(Throwable cause) {
                        System.out.println("onConnectLost");
                    }
    
                    @Override
                    public void connectFailed(Throwable cause) {
                        System.out.println("onConnectFailed : " + cause);
                    }
    
                });
            } catch (Throwable var1) {
            }
            System.out.println("connect result :" + client.isConnected());
        }
    
        // Ingesting PC system and hardware data
        public static Map<String, Object> collectDeviceInfo() {
            oshi.SystemInfo si = new oshi.SystemInfo();
            HardwareAbstractionLayer hal = si.getHardware();
            OperatingSystem os = si.getOperatingSystem();
    
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("system", os.toString());
            data.put("model", hal.getComputerSystem().getManufacturer() + " " + hal.getComputerSystem().getModel());
            data.put("cpu_core", hal.getProcessor().getLogicalProcessorCount());
            data.put("cpu_used", hal.getProcessor().getSystemCpuLoad());
            data.put("mem_total", hal.getMemory().getTotal());
            data.put("mem_used", hal.getMemory().getAvailable());
            data.put("cpu_used_average", hal.getProcessor().getSystemLoadAverage());
            data.put("cpu_temperature", hal.getSensors().getCpuTemperature());
    
            return data;
        }
    
        // Updating PC attributes with the ingested system and hardware data
        public static void updateAttribute(){
            Map<String, Object> deviceInfo= collectDeviceInfo();
            System.out.println("Computer info: "+deviceInfo);
            AttributeUpdateRequest request = AttributeUpdateRequest.builder()
                    .setQos(1)
                    .addAttribute("system", deviceInfo.get("system"))
                    .addAttribute("model", deviceInfo.get("model"))
                    .addAttribute("cpu_core", deviceInfo.get("cpu_core"))
                    .addAttribute("mem_total", deviceInfo.get("mem_total"))
                    .build();
            System.out.println(">>> Update Attribute: "+request);
    
            try {
                AttributeUpdateResponse resp = client.publish(request);
                System.out.println("<-- " + resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        // Uploading PC system data into EnOS 云端
        public static void postMeasurepoint(Map<String, Object> systemInfo) {
            MeasurepointPostRequest request = MeasurepointPostRequest.builder()
                    .setQos(0)
                    .addMeasurePoint("cpu_used", Double.parseDouble(systemInfo.get("cpu_used").toString())+0.0)
                    .addMeasurePoint("mem_used", systemInfo.get("mem_used"))
                    .build();
            System.out.println(">>> Post Measurepoint: "+request);
    
            try {
                MeasurepointPostResponse resp = client.publish(request);
                System.out.println("<-- " + resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        // Monitoring the CPU load
        public static void monitor() throws Exception {
            long lastReportTs=0;
            while (true) {
                Map<String, Object> systemInfo= collectDeviceInfo();
                postMeasurepoint(systemInfo);
    
                double cpu_load= (double) systemInfo.get("cpu_used");
                if (cpu_load>0.2) {
                    long ts = System.currentTimeMillis();
    
                    if ((ts-lastReportTs)>(60*1000)) {
                        lastReportTs=ts;
                        reportCPULoadEvent(cpu_load, "[Warning] CPU load: "+ cpu_load);
                    }else{
                        System.out.println("[Warning] No reporting required, CPULoadEvent: " + cpu_load);
                    }
                }
    
                Thread.sleep(interval*1000);
            }
        }
    
        // Reporting CPU load events
        public static void reportCPULoadEvent(double value, String describe) {
            EventPostRequest request=EventPostRequest.builder()
                    .setQos(0)
                    .setEventIdentifier("cpu_event")
                    .addValue("value", value)
                    .addValue("message", describe)
                    .build();
            System.out.println(">>> Post Event: "+request);
    
            try {
                EventPostResponse resp = client.publish(request);
                System.out.println("<-- " + resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    


  5. 检查程序的运行结果。如果 CPU 负载超过阈值,程序将返回以下结果:

    >>> Post Event: AnswerableMessageBody{id='null', method='thing.event.cpu_event.post', version='null', params={time=1565852207454, events={message=[Warning] CPU load: 1.0, value=1.0}}}
    


  6. 检查 设备详情 页面上 事件 选项卡下,发布到 EnOS 管理控制台的事件。


    ../../_images/uploaded_events.png