单元 4: 监测 CPU 负载¶
通过指定的时间间隔采集 PC 系统数据,可以监控 PC的 CPU 负载,并在 CPU 负载超过设置的阈值(例如50%)时报告 CPU 负载事件。
在本单元中,更新 单元 3 中使用的程序,增加监控CPU负载的功能。
声明函数
monitor()
以监控 CPU 负载,参考以下代码示例:public static void main(String[] args) throws Exception { connect(); updateAttribute(); monitor(); }
编写
monitor()
函数,以指定的时间间隔(例如,每 10 秒)将 PC 系统数据上传到 EnOS Cloud 并监视 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); } }
编写
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(); } }
编译并运行程序以进行设备连接、数据采集、和 CPU 负载事件报告。参考以下程序代码示例:
import java.util.HashMap; import java.util.Map; import com.envisioniot.enos.iot_mqtt_sdk.core.IConnectCallback; 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 IConnectCallback() { @Override public void onConnectSuccess() { System.out.println("connect success"); } @Override public void onConnectLost() { System.out.println("onConnectLost"); } @Override public void onConnectFailed(int reasonCode) { System.out.println("onConnectFailed : " + reasonCode); } }); } catch (EnvisionException e) { e.printStackTrace(); } 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 Cloud 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(); } } }
检查程序的运行结果。如果 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}}}
检查 设备详情 页面上 事件 选项卡下,发布到 EnOS 管理控制台 的事件。