使用Prometheus可视化监控物联网平台数据

物联网平台中设备相关的物模型属性时序数据时序存储规则流转数据自定义时序存储表数据,可以推送到Prometheus中存储和处理,实现对物联网设备的实时监控、预测和故障诊断,帮助提高设备的性能、可靠性和管理效率。

背景信息

  • Prometheus是一个开源系统监控和警报工具包,Prometheus UI内置可视化监控能力,您可在Prometheus官网查看Prometheus的详细介绍、帮助文档、工具下载链接、最新版本信息等。您可以参考帮助文档,了解如何使用Prometheus进行监控和告警,以及如何与其他工具和平台集成。

  • 物联网平台提供的实时监控功能,支持自定义监控的指标项进行实时展示。具体内容,请参见实时监控使用说明

本文介绍如何使用Prometheus快速接入物联网平台数据并进行可视化展示。

应用场景

使用Prometheus可视化监控物联网平台设备数据的应用场景如下:

  • 设备监控和故障检测

    监控物联网设备的状态和性能指标,例如设备的温度、湿度、电量等。通过实时监控这些指标,可以及时发现设备故障并进行诊断和修复。

  • 资源管理和优化

    帮助物联网平台进行资源管理和优化,例如监控和优化设备的能耗、网络带宽、存储空间等。通过对资源的实时监控和分析,可以有效地提高资源利用率和性能。

  • 数据分析和预测

    分析和预测物联网设备生成的海量数据。通过对数据的实时分析和挖掘,可以提取有价值的信息和洞察,并据此做出预测和决策。

  • 安全监控和威胁检测

    监控物联网设备的安全状态,例如检测设备是否存在漏洞、是否受到攻击等。通过实时监控安全指标并及时发出警报,可以提高物联网平台的安全性。

  • 自动化运维和管理

    结合自动化工具和流程,实现对物联网设备的自动化运维和管理。例如,可以根据监控数据自动触发故障修复、资源扩容等操作,提高物联网平台的可靠性和可扩展性。

Prometheus支持监控的物联网平台数据

您可以在Prometheus服务器中使用物联网平台云端的SDK以下API,获取物联网平台中的数据。

数据类型

API

相关文档

物模型属性时序数据

QueryDevicePropertyStatus

设备使用物模型通信

时序存储规则流转数据

QueryDevicesHotStorageDataStatus

时序数据存储说明

自定义时序存储表数据

QueryCustomTimelineTableStatus

自定义时序存储表说明

使用限制

仅企业版实例下对应数据可接入到Prometheus进行可视化监控管理。

使用流程

物联网平台数据源对接Prometheus实现可视化的流程如下:

image

步骤一:安装并启动Prometheus Server

Prometheus对接物联网平台数据前,需要先启动Prometheus Server。本文以下载Window操作系统的软件包:prometheus-2.49.0-rc.0.windows-amd64.zip为例,介绍启动Prometheus Server的操作步骤。

  1. 下载最新版本的prometheus软件包:prometheus-2.49.0-rc.0.windows-amd64.zip

  2. 解压软件包文件:prometheus-2.49.0-rc.0.windows-amd64

    image.png

  3. 打开CMD命令窗口,进入文件目录:prometheus-2.49.0-rc.0.windows-amd64

  4. 执行以下命令,启动Prometheus Server。

    prometheus.exe
  5. 在浏览器中输入http://localhost:9090,进入Prometheus内置的监控管理工作台。

    image.png

步骤二:调用物联网平台和Prometheus的SDK对接设备数据

阿里云提供Java、Python和Go三种开发语言的SDK供您选择,您可以在业务服务端使用SDK开发应用程序,对接Prometheus读取物联网平台数据,以实现Prometheus后续读取物联网平台的数据源进行可视化监控管理。

Step1:调用SDK对接设备数据

Java SDK

环境配置

Java 官方网站下载,并按说明安装Java开发环境。要求安装Java 8及以上版本。

Maven项目依赖

  • 阿里云物联网平台云端API所需Maven依赖为:

    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>iot20180120</artifactId>
        <version>5.0.0</version>
    </dependency>
  • Prometheus所需Maven依赖为:

    <dependency>
        <groupId>io.prometheus</groupId>
        <artifactId>simpleclient</artifactId>
        <version>0.9.0</version>
    </dependency>
    <dependency>
        <groupId>io.prometheus</groupId>
        <artifactId>simpleclient_httpserver</artifactId>
        <version>0.9.0</version>
    </dependency>

SDK使用说明

  1. 使用物联网平台云端SDK通过查询数据的API获取物联网平台设备数据,使用说明,请参见Java SDK使用说明

  2. QueryDevicePropertyStatus

    接口的请求参数和返回参数说明,请参见QueryDevicePropertyStatus

    import com.aliyun.iot20180120.models.QueryDevicePropertyStatusResponse;
    import com.aliyun.tea.TeaException;
    
    public class ApiUtil {
    
        public static com.aliyun.iot20180120.Client createClient(String accessKeyId,
                                                                 String accessKeySecret,
                                                                 String endpoint) throws Exception {
            com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                    .setAccessKeyId(accessKeyId)
                    .setAccessKeySecret(accessKeySecret);
            config.endpoint = endpoint;
            return new com.aliyun.iot20180120.Client(config);
        }
    
        public static String getSnapshotApi(String accessKeyId,
                                            String accessKeySecret,
                                            String endpoint,
                                            String iotInstanceId,
                                            String productKey,
                                            String deviceName) throws Exception {
    
            com.aliyun.iot20180120.Client client = api.createClient(accessKeyId, accessKeySecret, endpoint);
            com.aliyun.iot20180120.models.QueryDevicePropertyStatusRequest queryDevicePropertyStatusRequest = new com.aliyun.iot20180120.models.QueryDevicePropertyStatusRequest();
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            try {
                queryDevicePropertyStatusRequest.setIotInstanceId(iotInstanceId);
                queryDevicePropertyStatusRequest.setProductKey(productKey);
                queryDevicePropertyStatusRequest.setDeviceName(deviceName);
    
                QueryDevicePropertyStatusResponse queryDevicePropertyStatusResponse =
                        client.queryDevicePropertyStatusWithOptions(queryDevicePropertyStatusRequest, runtime);
                return queryDevicePropertyStatusResponse.getBody().getData().getList().getPropertyStatusInfo().get(0).getValue();
            } catch (TeaException error) {
                System.out.println(error.getMessage());
                System.out.println(error.getData().get("Recommend"));
                com.aliyun.teautil.Common.assertAsString(error.message);
            } catch (Exception error_e) {
                TeaException error = new TeaException(_error.getMessage(), error_e);
                System.out.println(error.getMessage());
                System.out.println(error.getData().get("Recommend"));
                com.aliyun.teautil.Common.assertAsString(error.message);
            }
    
            return null;
        }
    }

    QueryDevicesHotStorageDataStatus

    接口的请求参数和返回参数说明,请参见QueryDevicesHotStorageDataStatus

    import com.aliyun.iot20180120.models.QueryDevicesHotStorageDataStatusResponse;
    import com.aliyun.tea.TeaException;
    
    public class ApiUtil {
    
        public static com.aliyun.iot20180120.Client createClient(String accessKeyId,
                                                                 String accessKeySecret,
                                                                 String endpoint) throws Exception {
            com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                    .setAccessKeyId(accessKeyId)
                    .setAccessKeySecret(accessKeySecret);
            config.endpoint = endpoint;
            return new com.aliyun.iot20180120.Client(config);
        }
    
        public static String getSnapshotTopicApi(String accessKeyId,
                                                 String accessKeySecret,
                                                 String endpoint,
                                                 String iotInstanceId,
                                                 String productKey,
                                                 String deviceName,
                                                 Integer asc,
                                                 Integer pageSize,
                                                 String userTopic) throws Exception {
    
            com.aliyun.iot20180120.Client client = api.createClient(accessKeyId, accessKeySecret, endpoint);
            com.aliyun.iot20180120.models.QueryDevicesHotStorageDataStatusRequest queryDevicesHotStorageDataStatusRequest = new com.aliyun.iot20180120.models.QueryDevicesHotStorageDataStatusRequest();
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            try {
                queryDevicesHotStorageDataStatusRequest.setIotInstanceId(iotInstanceId);
                queryDevicesHotStorageDataStatusRequest.setProductKey(productKey);
                queryDevicesHotStorageDataStatusRequest.setDeviceName(deviceName);
                queryDevicesHotStorageDataStatusRequest.setAsc(asc);
                queryDevicesHotStorageDataStatusRequest.setPageSize(pageSize);
                queryDevicesHotStorageDataStatusRequest.setUserTopic(userTopic);
    
                QueryDevicesHotStorageDataStatusResponse queryDevicesHotStorageDataStatusResponse =
                        client.queryDevicesHotStorageDataStatusWithOptions(queryDevicesHotStorageDataStatusRequest, runtime);
    
                return queryDevicesHotStorageDataStatusResponse.getBody().getData().getList().getPropertyStatusDataInfo().get(0).getValue();
            } catch (TeaException error) {
                System.out.println(error.getMessage());
                System.out.println(error.getData().get("Recommend"));
                com.aliyun.teautil.Common.assertAsString(error.message);
            } catch (Exception error_e) {
                TeaException error = new TeaException(_error.getMessage(), error_e);
                System.out.println(error.getMessage());
                System.out.println(error.getData().get("Recommend"));
                com.aliyun.teautil.Common.assertAsString(error.message);
            }
    
            return null;
        }
    }

    QueryCustomTimelineTableStatus

    接口的请求参数和返回参数说明,请参见QueryCustomTimelineTableStatus

    import com.aliyun.iot20180120.models.QueryCustomTimelineTableStatusRequest;
    import com.aliyun.iot20180120.models.QueryCustomTimelineTableStatusResponse;
    import com.aliyun.tea.TeaException;
    
    public class ApiUtil {
    
        public static com.aliyun.iot20180120.Client createClient(String accessKeyId,
                                                                 String accessKeySecret,
                                                                 String endpoint) throws Exception {
            com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                    .setAccessKeyId(accessKeyId)
                    .setAccessKeySecret(accessKeySecret);
            config.endpoint = endpoint;
            return new com.aliyun.iot20180120.Client(config);
        }
    
        public static String getCustomSnapshotApi(String accessKeyId,
                                                  String accessKeySecret,
                                                  String endpoint,
                                                  String iotInstanceId,
                                                  String tableName) throws Exception {
    
            com.aliyun.iot20180120.Client client = ApiUtil.createClient(accessKeyId, accessKeySecret, endpoint);
            com.aliyun.iot20180120.models.QueryCustomTimelineTableStatusRequest queryCustomTimelineTableStatusRequest = new QueryCustomTimelineTableStatusRequest();
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            try {
                queryCustomTimelineTableStatusRequest.setIotInstanceId(iotInstanceId);
                queryCustomTimelineTableStatusRequest.setTableName(tableName);
    
                QueryCustomTimelineTableStatusResponse queryCustomTimelineTableStatusResponse =
                        client.queryCustomTimelineTableStatusWithOptions(queryCustomTimelineTableStatusRequest, runtime);
    
                return queryCustomTimelineTableStatusResponse.getBody().getData().getResultJson();
            } catch (TeaException error) {
                System.out.println(error.getMessage());
                System.out.println(error.getData().get("Recommend"));
                com.aliyun.teautil.Common.assertAsString(error.message);
            } catch (Exception error_e) {
                TeaException error = new TeaException(error_e.getMessage(), error_e);
                System.out.println(error.getMessage());
                System.out.println(error.getData().get("Recommend"));
                com.aliyun.teautil.Common.assertAsString(error.message);
            }
    
            return null;
        }
    }
    
  3. 使用Prometheus SDK读取物联网平台数据源。

    1. 调用方法HTTPServer()配置启动访问Prometheus Server的端口。示例代码设置了8084

      new HTTPServer(8084);
    2. 调用方法Gauge.build("name","help").register()注册Gauge对象,定义存放数据的字段标识符。

      其中name是字段标识符,例如testJavaSnapshotRawtestJavaSnapshotTopichelp是描述的帮助信息,例如test num。后续通过参数1在Prometheus自带的监控管理工作台查看和分析对应字段的数据。

      您可以注册多个Gauge对象,分别接收存放多个字段的数据。

              Gauge gaugeRaw = Gauge.build("testJavaSnapshotRaw", "test num").register();
              Gauge gaugeTopic = Gauge.build("testJavaSnapshotTopic", "test num").register();
              Gauge gaugeCustom =  Gauge.build("testCustomTableSnapshot", "test num").register();
    3. 调用Gauge对象的set()方法,设置Gauge对象中对应字段的值为物联网平台云端API返回数据中的指定字段值。

              while (true) {
      
                  String resultRaw = ApiUtil.getSnapshotApi(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID_LP"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET_LP"),
                          "yourEndpoint", "yourIotInstanceId", "yourProductKey", "yourDeviceName");
                  gaugeRaw.set(Double.parseDouble(Objects.requireNonNull(resultRaw)));
      
                  String resultTopic = ApiUtil.getSnapshotTopicApi("yourAccessKey", "yourAccessSecret",
                          "yourEndpoint", "yourIotInstanceId", "yourProductKey", "yourDeviceName", 0, 1,"yourTopic");
                  gaugeTopic.set(Double.parseDouble(Objects.requireNonNull(resultTopic)));
      
                  String resultJson = ApiUtil.getCustomSnapshotApi("yourAccessKey", "yourAccessSecret",
                          "yourEndpoint", "yourIotInstanceId", "yourtableName");
                  List<Map<String, Object>> resultList = (List<Map<String, Object>>) JSONArray.parse(resultJson);
                  gaugeCustom.set(Double.parseDouble(Objects.requireNonNull(resultList).get(0).get("avg_humidity").toString()));
                
                  Thread.sleep(3000);
              }

      实际使用场景中需替换以下参数为真实值:

      参数

      说明

      yourAccessKey

      阿里云账号或对应RAM用户的AccessKey ID和AccessKey Secret。

      登录物联网平台控制台,将鼠标移至账号头像上,然后单击AccessKey管理,获取AccessKey ID和AccessKey Secret。

      重要

      为避免将AccessKey硬编码到业务代码中带来的安全风险,可采用配置环境变量的方法管理AccessKey。

      您需在本地操作系统中添加环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET,并分别写入已准备好的AccessKey ID和AccessKey Secret。

      在示例代码中可通过以下方法获取:

      • System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")

      • System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")

      yourAccessSecret

      yourEndpoint

      调用云服务的接入地址。物联网平台的接入地址格式:iot.${RegionId}.aliyuncs.com。其中,变量${RegionId}需替换为您的物联网平台服务的地域代码。阿里云地域代码,请参见支持的地域

      yourIotInstanceId

      实例ID。您可在物联网平台控制台的实例概览页面,查看当前实例的ID

      yourProductKey

      设备所属的产品ProductKey和设备名称,可在设备详情页面查看,具体操作,请参见查看设备信息

      yourDeviceName

      yourTopic

      调用接口QueryDevicesHotStorageDataStatus时,传入要查询数据所属自定义Topic。从user类目开始,输入自定义Topic的后续所有类目。

      例如:user/a***/b***。自定义Topic详细说明,请参见使用自定义Topic通信

      yourtableName

      调用接口QueryCustomTimelineTableStatus时,传入要查询数据所属自定义时序存储表的表标识符。

      查看表标识符方法,请参见查看自定义存储表信息

完整示例代码

物联网平台云端SDK和Prometheus SDK的示例代码,请参见Prometheus Java SDK demo

Python SDK

环境配置

  1. 访问Python官网下载Python安装包,并完成安装。目前Python SDK支持Python的3.7及以上版本。

  2. 访问pip 官网下载pip安装包,并完成安装。(如果您已安装pip,请忽略此步骤。)

项目依赖

  • 阿里云物联网平台云端API所需依赖包为:

    pip install alibabacloud_iot20180120
  • Prometheus所需依赖包为:

    pip install prometheus_client

SDK使用说明

  1. 使用物联网平台云端SDK通过查询数据的API获取物联网平台设备数据,使用说明,请参见Python SDK使用说明

  2. QueryDevicePropertyStatus

    接口的请求参数和返回参数说明,请参见QueryDevicePropertyStatus

    from alibabacloud_iot20180120.client import Client as Iot20180120Client
    from alibabacloud_tea_openapi import models as open_api_models
    from alibabacloud_iot20180120 import models as iot_20180120_models
    from alibabacloud_tea_util import models as util_models
    from alibabacloud_tea_util.client import Client as UtilClient
    
    def create_client(access_key_id, access_key_secret, endpoint):
        config = open_api_models.Config(access_key_id=access_key_id, access_key_secret=access_key_secret)
        config.endpoint = endpoint
        return Iot20180120Client(config)
    
    def get_snapshot_api(access_key_id, access_key_secret, endpoint, iot_instance_id, product_key, device_name):
        client = create_client(access_key_id=access_key_id, access_key_secret=access_key_secret, endpoint=endpoint)
        query_device_property_status_request = iot_20180120_models.QueryDevicePropertyStatusRequest()
        query_device_property_status_request.iot_instance_id = iot_instance_id
        query_device_property_status_request.product_key = product_key
        query_device_property_status_request.device_name = device_name
    
        runtime = util_models.RuntimeOptions()
    
        try:
            return client.query_device_property_status_with_options(query_device_property_status_request, runtime)
        except Exception as error:
            UtilClient.assert_as_string(error.message)

    QueryDevicesHotStorageDataStatus

    接口的请求参数和返回参数说明,请参见QueryDevicesHotStorageDataStatus

    from alibabacloud_iot20180120.client import Client as Iot20180120Client
    from alibabacloud_tea_openapi import models as open_api_models
    from alibabacloud_iot20180120 import models as iot_20180120_models
    from alibabacloud_tea_util import models as util_models
    from alibabacloud_tea_util.client import Client as UtilClient
    
    def create_client(access_key_id, access_key_secret, endpoint):
        config = open_api_models.Config(access_key_id=access_key_id, access_key_secret=access_key_secret)
        config.endpoint = endpoint
        return Iot20180120Client(config)
        
    
    def get_snapshot_topic_api(access_key_id, access_key_secret, endpoint, iot_instance_id, product_key, device_name, asc, page_size, user_topic):
        client = create_client(access_key_id=access_key_id, access_key_secret=access_key_secret, endpoint=endpoint)
        query_devices_hot_storage_data_status_request = iot_20180120_models.QueryDevicesHotStorageDataStatusRequest()
        query_devices_hot_storage_data_status_request.iot_instance_id = iot_instance_id
        query_devices_hot_storage_data_status_request.product_key = product_key
        query_devices_hot_storage_data_status_request.device_name = device_name
        query_devices_hot_storage_data_status_request.asc = asc
        query_devices_hot_storage_data_status_request.page_size = page_size
        query_devices_hot_storage_data_status_request.user_topic = user_topic
    
        runtime = util_models.RuntimeOptions()
    
        try:
            return client.query_devices_hot_storage_data_status_with_options(query_devices_hot_storage_data_status_request, runtime)
        except Exception as error:
            UtilClient.assert_as_string(error.message)

    QueryCustomTimelineTableStatus

    接口的请求参数和返回参数说明,请参见QueryCustomTimelineTableStatus

    from alibabacloud_iot20180120.client import Client as Iot20180120Client
    from alibabacloud_tea_openapi import models as open_api_models
    from alibabacloud_iot20180120 import models as iot_20180120_models
    from alibabacloud_tea_util import models as util_models
    from alibabacloud_tea_util.client import Client as UtilClient
    
    def create_client(access_key_id, access_key_secret, endpoint):
        config = open_api_models.Config(access_key_id=access_key_id, access_key_secret=access_key_secret)
        config.endpoint = endpoint
        return Iot20180120Client(config)
    
    def get_custom_snapshot_api(access_key_id, access_key_secret, endpoint, iot_instance_id, table_name):
        client = create_client(access_key_id=access_key_id, access_key_secret=access_key_secret, endpoint=endpoint)
        query_custom_timeline_table_status_request = iot_20180120_models.QueryCustomTimelineTableStatusRequest()
        query_custom_timeline_table_status_request.iot_instance_id = iot_instance_id
        query_custom_timeline_table_status_request.table_name = table_name
    
        runtime = util_models.RuntimeOptions()
    
        try:
            return client.query_custom_timeline_table_status_with_options(query_custom_timeline_table_status_request, runtime)
        except Exception as error:
            UtilClient.assert_as_string(error.message)
    
  3. 使用Prometheus SDK读取物联网平台数据源。

    1. 调用方法start_http_server()配置启动访问Prometheus Server的端口。示例代码设置了8083

      start_http_server(8083)
    2. 调用方法Gauge("name","help")注册Gauge指标对象,定义存放数据的字段标识符。

      其中name是字段标识符,例如testPythonSnapshotRawtestPythonSnapshotTopichelp是描述的帮助信息,例如test sample。后续通过name在Prometheus自带的监控管理工作台查看和分析对应字段的数据。

      您可以注册多个Gauge对象,分别接收存放多个字段的数据。

      g_raw = Gauge('testPythonSnapshotRaw', 'test sample')
      g_topic = Gauge('testPythonSnapshotTopic', 'test sample')
      g_custom = Gauge('testPythonCustomSnapshot', 'test sample')
    3. 调用Gauge指标对象的set()方法,设置Gauge指标对象中对应字段的值为物联网平台云端API返回数据中的指定字段值。

      while True:
          result_raw = api.get_snapshot_api(access_key_id="", access_key_secret="",
                                            endpoint="", iot_instance_id="",
                                            product_key="", device_name="")
          g_raw.set(result_raw.body.data.list.property_status_info[0].value)
          
          result_topic = api.get_snapshot_topic_api(access_key_id="", access_key_secret="",
                                                    endpoint="", iot_instance_id="",
                                                    product_key="", device_name="", asc="0",
                                                    page_size="1", user_topic="")
          g_topic.set(result_topic.body.data.list.property_status_data_info[0].value)
          
          result_json = api.get_custom_snapshot_api(access_key_id="", access_key_secret="",
                                                endpoint="", iot_instance_id="",
                                                table_name="")
          result_custom = json.loads(result_json.body.data.result_json)  
          for row in result_custom:
              g_custom.set(row["avg_humidity"])
              
          time.sleep(3)

      实际使用场景中以下参数需填入真实值:

      参数

      说明

      access_key_id

      阿里云账号或对应RAM用户的AccessKey ID和AccessKey Secret。

      登录物联网平台控制台,将鼠标移至账号头像上,然后单击AccessKey管理,获取AccessKey ID和AccessKey Secret。

      重要

      为避免将AccessKey硬编码到业务代码中带来的安全风险,可采用配置环境变量的方法管理AccessKey。

      您需在本地操作系统中添加环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET,并分别写入已准备好的AccessKey ID和AccessKey Secret。

      在示例代码中可通过以下方法获取:

      • os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_ID")

      • os.environ.get("ALIBABA_CLOUD_ACCESS_KEY_SECRET")

      access_key_secret

      endpoint

      调用云服务的接入地址。物联网平台的接入地址格式:iot.${RegionId}.aliyuncs.com。其中,变量${RegionId}需替换为您的物联网平台服务的地域代码。阿里云地域代码,请参见支持的地域

      iot_instance_id

      实例ID。您可在物联网平台控制台的实例概览页面,查看当前实例的ID

      product_key

      设备所属的产品ProductKey和设备名称,可在设备详情页面查看,具体操作,请参见查看设备信息

      device_name

      user_topic

      调用接口QueryDevicesHotStorageDataStatus时,传入要查询数据所属自定义Topic。从user类目开始,输入自定义Topic的后续所有类目。

      例如:user/a***/b***。自定义Topic详细说明,请参见使用自定义Topic通信

      table_name

      调用接口QueryCustomTimelineTableStatus时,传入要查询数据所属自定义时序存储表的表标识符。

      查看表标识符方法,请参见查看自定义存储表信息

完整示例代码

物联网平台云端SDK和Prometheus SDK的使用示例,请参见Prometheus Python SDK demo

Go SDK

环境配置

  1. 访问Go官网,安装Go开发环境。目前支持Go 1.13.0及以上版本。

  2. Go安装完毕后,新建系统变量GOPATH,并将其指向您的代码目录。

    了解更多GOPATH相关信息,请执行命令go help gopath

项目依赖

  • 阿里云物联网平台云端API所需依赖包为:

    go get github.com/alibabacloud-go/tea/tea
    go get github.com/alibabacloud-go/darabonba-openapi/v2/client
    go get github.com/alibabacloud-go/iot-20180120/v6/client
    go get github.com/alibabacloud-go/tea-utils/v2/service
  • Prometheus所需依赖包为:

    go get github.com/prometheus/client_golang/prometheus
    go get github.com/prometheus/client_golang/prometheus/promhttp

SDK使用说明

  1. 使用物联网平台云端SDK通过查询数据的API获取物联网平台设备数据,使用说明,请参见Go SDK使用说明

  2. QueryDevicePropertyStatus

    接口的请求参数和返回参数说明,请参见QueryDevicePropertyStatus

    import (
    	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
    	iot20180120 "github.com/alibabacloud-go/iot-20180120/v6/client"
    	util "github.com/alibabacloud-go/tea-utils/v2/service"
    	"github.com/alibabacloud-go/tea/tea"
    )
    
    func CreateClient(accessKeyId *string, accessKeySecret *string, endpoint *string) (_result *iot20180120.Client, _err error) {
    	config := &openapi.Config{
    		// 必填,您的 AccessKey ID
    		AccessKeyId: accessKeyId,
    		// 必填,您的 AccessKey Secret
    		AccessKeySecret: accessKeySecret,
    	}
    	// Endpoint 请参考 https://api.aliyun.com/product/Iot
    	// config.Endpoint = tea.String("iot.cn-shanghai.aliyuncs.com")
    	config.Endpoint = endpoint
    	_result = &iot20180120.Client{}
    	_result, _err = iot20180120.NewClient(config)
    	return _result, _err
    }
    
    func getSnapshotApi(accessKeyId *string, accessKeySecret *string, endpoint *string, iotInstanceId *string, productKey *string,
    	deviceName *string) (queryDevicePropertyStatusResponse *iot20180120.QueryDevicePropertyStatusResponse, _err error) {
    	client, _err := CreateClient(accessKeyId, accessKeySecret, endpoint)
    	if _err != nil {
    		return nil, _err
    	}
    
    	queryDevicePropertyStatusRequest := &iot20180120.QueryDevicePropertyStatusRequest{}
    	queryDevicePropertyStatusRequest.IotInstanceId = iotInstanceId
    	queryDevicePropertyStatusRequest.ProductKey = productKey
    	queryDevicePropertyStatusRequest.DeviceName = deviceName
    
    	queryDevicePropertyStatusResponse = &iot20180120.QueryDevicePropertyStatusResponse{}
    
    	runtime := &util.RuntimeOptions{}
    	tryErr := func() (_e error) {
    		defer func() {
    			if r := tea.Recover(recover()); r != nil {
    				_e = r
    			}
    		}()
    		queryDevicePropertyStatusResponse, _err = client.QueryDevicePropertyStatusWithOptions(queryDevicePropertyStatusRequest, runtime)
    
    		if _err != nil {
    			return _err
    		}
    
    		return nil
    	}()
    
    	if tryErr != nil {
    		var error = &tea.SDKError{}
    		if _t, ok := tryErr.(*tea.SDKError); ok {
    			error = _t
    		} else {
    			error.Message = tea.String(tryErr.Error())
    		}
    		// 如有需要,请打印 error
    		_, _err = util.AssertAsString(error.Message)
    		if _err != nil {
    			return queryDevicePropertyStatusResponse, _err
    		}
    	}
    	return queryDevicePropertyStatusResponse, _err
    }

    QueryDevicesHotStorageDataStatus

    接口的请求参数和返回参数说明,请参见QueryDevicesHotStorageDataStatus

    import (
    	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
    	iot20180120 "github.com/alibabacloud-go/iot-20180120/v6/client"
    	util "github.com/alibabacloud-go/tea-utils/v2/service"
    	"github.com/alibabacloud-go/tea/tea"
    )
    
    func CreateClient(accessKeyId *string, accessKeySecret *string, endpoint *string) (_result *iot20180120.Client, _err error) {
    	config := &openapi.Config{
    		// 必填,您的 AccessKey ID
    		AccessKeyId: accessKeyId,
    		// 必填,您的 AccessKey Secret
    		AccessKeySecret: accessKeySecret,
    	}
    	// Endpoint 请参考 https://api.aliyun.com/product/Iot
    	// config.Endpoint = tea.String("iot.cn-shanghai.aliyuncs.com")
    	config.Endpoint = endpoint
    	_result = &iot20180120.Client{}
    	_result, _err = iot20180120.NewClient(config)
    	return _result, _err
    }
    
    func getSnapshotTopicApi(accessKeyId *string, accessKeySecret *string, endpoint *string, iotInstanceId *string, productKey *string,
    	deviceName *string, asc *int32, pageSize *int32, userTopic *string) (queryDevicesHotStorageDataStatusResponse *iot20180120.QueryDevicesHotStorageDataStatusResponse, _err error) {
    
    	client, _err := CreateClient(accessKeyId, accessKeySecret, endpoint)
    	if _err != nil {
    		return nil, _err
    	}
    
    	queryDevicesHotStorageDataStatusRequest := &iot20180120.QueryDevicesHotStorageDataStatusRequest{}
    	queryDevicesHotStorageDataStatusRequest.IotInstanceId = iotInstanceId
    	queryDevicesHotStorageDataStatusRequest.ProductKey = productKey
    	queryDevicesHotStorageDataStatusRequest.DeviceName = deviceName
    	queryDevicesHotStorageDataStatusRequest.Asc = asc
    	queryDevicesHotStorageDataStatusRequest.PageSize = pageSize
    	queryDevicesHotStorageDataStatusRequest.UserTopic = userTopic
    
    	queryDevicesHotStorageDataStatusResponse = &iot20180120.QueryDevicesHotStorageDataStatusResponse{}
    
    	runtime := &util.RuntimeOptions{}
    	tryErr := func() (_e error) {
    		defer func() {
    			if r := tea.Recover(recover()); r != nil {
    				_e = r
    			}
    		}()
    		queryDevicesHotStorageDataStatusResponse, _err = client.QueryDevicesHotStorageDataStatusWithOptions(queryDevicesHotStorageDataStatusRequest, runtime)
    
    		if _err != nil {
    			return _err
    		}
    
    		return nil
    	}()
    
    	if tryErr != nil {
    		var error = &tea.SDKError{}
    		if _t, ok := tryErr.(*tea.SDKError); ok {
    			error = _t
    		} else {
    			error.Message = tea.String(tryErr.Error())
    		}
    		// 如有需要,请打印 error
    		_, _err = util.AssertAsString(error.Message)
    		if _err != nil {
    			return queryDevicesHotStorageDataStatusResponse, _err
    		}
    	}
    	return queryDevicesHotStorageDataStatusResponse, _err
    }
    

    QueryCustomTimelineTableStatus

    接口的请求参数和返回参数说明,请参见QueryCustomTimelineTableStatus

    import (
    	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
    	iot20180120 "github.com/alibabacloud-go/iot-20180120/v6/client"
    	util "github.com/alibabacloud-go/tea-utils/v2/service"
    	"github.com/alibabacloud-go/tea/tea"
    )
    
    func CreateClient(accessKeyId *string, accessKeySecret *string, endpoint *string) (_result *iot20180120.Client, _err error) {
    	config := &openapi.Config{
    		// 必填,您的 AccessKey ID
    		AccessKeyId: accessKeyId,
    		// 必填,您的 AccessKey Secret
    		AccessKeySecret: accessKeySecret,
    	}
    	// Endpoint 请参考 https://api.aliyun.com/product/Iot
    	// config.Endpoint = tea.String("iot.cn-shanghai.aliyuncs.com")
    	config.Endpoint = endpoint
    	_result = &iot20180120.Client{}
    	_result, _err = iot20180120.NewClient(config)
    	return _result, _err
    }
    
    func getCustomSnapshotApi(accessKeyId *string, accessKeySecret *string, endpoint *string, iotInstanceId *string,
    	tableName *string) (queryCustomTimelineTableStatusResponse *iot20180120.QueryCustomTimelineTableStatusResponse, _err error) {
    
    	client, _err := CreateClient(accessKeyId, accessKeySecret, endpoint)
    	if _err != nil {
    		return nil, _err
    	}
    
    	queryCustomTimelineTableStatusRequest := &iot20180120.QueryCustomTimelineTableStatusRequest{}
    	queryCustomTimelineTableStatusRequest.IotInstanceId = iotInstanceId
    	queryCustomTimelineTableStatusRequest.TableName = tableName
    
    	queryCustomTimelineTableStatusResponse = &iot20180120.QueryCustomTimelineTableStatusResponse{}
    
    	runtime := &util.RuntimeOptions{}
    	tryErr := func() (_e error) {
    		defer func() {
    			if r := tea.Recover(recover()); r != nil {
    				_e = r
    			}
    		}()
    		queryCustomTimelineTableStatusResponse, _err = client.QueryCustomTimelineTableStatusWithOptions(queryCustomTimelineTableStatusRequest, runtime)
    
    		if _err != nil {
    			return _err
    		}
    
    		return nil
    	}()
    
    	if tryErr != nil {
    		var error = &tea.SDKError{}
    		if _t, ok := tryErr.(*tea.SDKError); ok {
    			error = _t
    		} else {
    			error.Message = tea.String(tryErr.Error())
    		}
    		// 如有需要,请打印 error
    		_, _err = util.AssertAsString(error.Message)
    		if _err != nil {
    			return queryCustomTimelineTableStatusResponse, _err
    		}
    	}
    
    	return queryCustomTimelineTableStatusResponse, _err
    }
  3. 使用Prometheus SDK读取物联网平台数据源。

    1. 调用方法http.ListenAndServe()配置启动访问Prometheus Server的端口。

      	// 创建一个HTTP处理器来暴露指标
      	http.Handle("/metrics", promhttp.Handler())
      
      	// 启动Web服务器
      	http.ListenAndServe(":8082", nil)
    2. 调用方法prometheus.NewGauge()创建Gauge指标对象,定义存放数据的字段标识符。

      其中name是字段标识符,例如GolangRawGolangTopichelp是描述的帮助信息,例如test value。后续通过name在Prometheus自带的监控管理工作台查看和分析对应字段的数据。

      var (
      	// 创建一个Gauge指标
      	guageRaw = prometheus.NewGauge(prometheus.GaugeOpts{
      		Name: "GolangRaw", // 指标名称
      		Help: "test value", // 指标帮助信息
      	})
      )
      
      var (
      	guageTopic = prometheus.NewGauge(prometheus.GaugeOpts{
      		Name: "GolangTopic", // 指标名称
      		Help: "test value", // 指标帮助信息
      	})
      )
      
      var (
      	guageCustom = prometheus.NewGauge(prometheus.GaugeOpts{
      		Name: "GolangCustom", // 指标名称
      		Help: "test value",   // 指标帮助信息
      	})
      )
    3. 调用prometheus.MustRegister()方法注册创建的Gauge指标对象。

      	// 注册指标
      	prometheus.MustRegister(guageRaw)
      	prometheus.MustRegister(guageTopic)
      prometheus.MustRegister(guageCustom)

      您可以创建并注册多个Gauge指标对象,分别接收存放多个字段的数据。

    4. 调用Gauge指标对象的set()方法,设置Gauge指标对象中对应字段的值为物联网平台云端API返回数据中的指定字段值。

      QueryDevicePropertyStatus

      func testRaw() {
      	go func() {
      		for {
      			queryDevicePropertyStatusResponse, _err := getSnapshotApi(tea.String("accessKeyId"), tea.String("accessKeySecret"),
      				tea.String("endpoint"), tea.String("iotInstanceId"), tea.String("productKey"), tea.String("deviceName"))
      			queryDevicePropertyStatusResponseBodyDataListPropertyStatusInfo := queryDevicePropertyStatusResponse.Body.Data.List.PropertyStatusInfo
      			var value *string = queryDevicePropertyStatusResponseBodyDataListPropertyStatusInfo[0].Value
      			var floatValue float64
      			floatValue, _ = strconv.ParseFloat(*value, 64)
      
      			if _err != nil {
      				panic(_err)
      			}
      
      			guageRaw.Set(floatValue)
      			time.Sleep(3 * time.Second)
      		}
      	}()
      }

      QueryDevicesHotStorageDataStatus

      func testTopic() {
      	go func() {
      		var asc int32 = 0
      		var pageSize int32 = 1
      		for {
            queryDevicesHotStorageDataStatusResponse, _err := getSnapshotTopicApi(tea.String("accessKeyId"), tea.String("accessKeySecret"),
      				tea.String("endpoint"), tea.String("iotInstanceId"), tea.String("productKey"), tea.String("deviceName"),
                                                                                  &asc, &pageSize, tea.String("userTopic"))
      			queryDevicesHotStorageDataStatusResponseBodyDataListPropertyStatusDataInfo := queryDevicesHotStorageDataStatusResponse.Body.Data.List.PropertyStatusDataInfo
      			var value *string = queryDevicesHotStorageDataStatusResponseBodyDataListPropertyStatusDataInfo[0].Value
      			var floatValue float64
      			floatValue, _ = strconv.ParseFloat(*value, 64)
      
      			if _err != nil {
      				panic(_err)
      			}
      
      			guageTopic.Set(floatValue)
      			time.Sleep(3 * time.Second)
      		}
      	}()
      }

      QueryCustomTimelineTableStatus

      func testCustom() {
      	go func() {
      		for {
      			queryCustomTimelineTableStatusResponse, _err := getCustomSnapshotApi(tea.String("accessKeyId"), tea.String("accessKeySecret"),
      				tea.String("endpoint"), tea.String("iotInstanceId"), tea.String("tableName"))
      
      			var config []map[string]interface{}
      			err := json.Unmarshal([]byte(*queryCustomTimelineTableStatusResponse.Body.Data.ResultJson), &config)
      
      			if err != nil {
      				panic(err)
      			}
      
      			if _err != nil {
      				panic(_err)
      			}
      
      			guageCustom.Set(config[0]["avg_humidity"].(float64))
      			time.Sleep(3 * time.Second)
      		}
      	}()
      }

      实际使用场景中需替换以下参数为真实值:

      参数

      说明

      accessKeyId

      阿里云账号或对应RAM用户的AccessKey ID和AccessKey Secret。

      登录物联网平台控制台,将鼠标移至账号头像上,然后单击AccessKey管理,获取AccessKey ID和AccessKey Secret。

      重要

      为避免将AccessKey硬编码到业务代码中带来的安全风险,可采用配置环境变量的方法管理AccessKey。

      您需在本地操作系统中添加环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET,并分别写入已准备好的AccessKey ID和AccessKey Secret。

      在示例代码中可通过以下方法获取:

      • os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")

      • os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")

      accessKeySecret

      endpoint

      调用云服务的接入地址。物联网平台的接入地址格式:iot.${RegionId}.aliyuncs.com。其中,变量${RegionId}需替换为您的物联网平台服务的地域代码。阿里云地域代码,请参见支持的地域

      iotInstanceId

      实例ID。您可在物联网平台控制台的实例概览页面,查看当前实例的ID

      productKey

      设备所属的产品ProductKey和设备名称,可在设备详情页面查看,具体操作,请参见查看设备信息

      deviceName

      userTopic

      调用接口QueryDevicesHotStorageDataStatus时,传入要查询数据所属自定义Topic。从user类目开始,输入自定义Topic的后续所有类目。

      例如:user/a***/b***。自定义Topic详细说明,请参见使用自定义Topic通信

      tableName

      调用接口QueryCustomTimelineTableStatus时,传入要查询数据所属自定义时序存储表的表标识符。

      查看表标识符方法,请参见查看自定义存储表信息

完整示例代码

物联网平台云端SDK和Prometheus SDK的使用示例,请参见Prometheus Go SDK demo

Step2:运行SDK Demo

重要

运行Demo前,请确保相关参数已替换为真实值。

运行Demo后,可在浏览器中输入http://localhost:8084/metrics,查看Prometheus SDK读取的数据,后续Prometheus Server可从http://localhost:8084/metrics中读取物联网平台数据源。

说明

8084为示例值,是调用Prometheus SDK获取物联网平台数据时配置的访问端口。

例如设备上报了如下物模型属性数据:

{
	"id": 1703*****418,
	"params": {
		"cpu_temperature": 60,
		"cpu_usage": 1.3
	},
	"version": "1.0",
	"method": "thing.event.property.post"
}

Prometheus SDK读取一个属性数据的信息如下:

# HELP testJavaSnapshotRaw test num
# TYPE testJavaSnapshotRaw gauge
testJavaSnapshotRaw 60.0

步骤三:配置并启动Prometheus读取数据源

启动Prometheus服务器和运行SDK Demo程序后,Prometheus还获取不到任何数据,还需要配置prometheus.yml文件,让Prometheus服务器定时拉取调用Prometheus SDK读取的物联网平台数据源。

  1. 打开文件目录prometheus-2.49.0-rc.0.windows-amd64下的prometheus.yml文件。

  2. globalscrape_configs节点下配置定时的时间和添加读取数据的任务,然后保存文件。

    • prometheus(默认任务):从http://localhost:9090/读取数据。

    • testjava:添加的任务,任务名称可自定义,从http://localhost:8084/metrics(8084为示例值,是上文步骤二中配置的访问端口)读取数据。

    • global:
        scrape_interval: 5s
      ........
      scrape_configs:
        - job_name: "prometheus"
          static_configs:
          - targets: ["localhost:9090"]
        - job_name: 'testjava'
          static_configs:
          - targets: ['localhost:8084']
  3. 重新启动Prometheus Server。具体操作,请参见上文的步骤一

  4. 在Prometheus内置的监控管理工作台输入up指令后单击Execute,启动数据访问端口。

    状态为1,表示端口已启动。

    image.png

步骤四:在Prometheus的Graph中查看数据

Prometheus拉取数据后,您可在内置的监控管理工作台查看对应数据。

  1. 在Prometheus内置的监控管理工作台,单击Graph页签。

  2. 输入Gauge对象设置的字段标识符,例如testJavaSnapshotRaw,然后单击Execute

    默认可查看到最近1小时内属性的时序数据。

    image.png

Prometheus监控管理数据的更多方法,请参见Prometheus官网文档