zoukankan      html  css  js  c++  java
  • 基于腾讯云监控 API 的 Grafana App 插件开发

    Tencent Cloud Monitor App

    Grafana 是一个开源的时序性统计和监控平台,支持例如 elasticsearch、graphite、influxdb 等众多的数据源,并以功能强大的界面编辑器著称,允许您对指标进行查询、可视化展示、设置告警等操作,以及自定义配置仪表盘。

    Grafana 已经拥有一个强大的贡献者和插件开发者社区。开发者社区提供了三种类型的插件:

    • Panel Plugin: 针对图形展示的面板插件;
    • Datasource Plugin: 针对数据源的插件;
    • App Plugin: 针对完整应用的插件,通常由 Panel Plugin,Datasource Plugin 以及 Dashboards 模板组成;

    Tencent Cloud Monitor App 的目录结构

    本文主要介绍的是 App Plugin 的开发过程以及相关的代码组织。基于腾讯云云监控 API 的 Tencent Cloud Monitor App 插件(TencentCloud/tencentcloud-monitor-grafana-app),主要由两部分组成: Datasource Plugin 和 Dashboards 模板组成,代码的目录结构如下:


    .
    ├── CHANGELOG.md
    ├── LICENSE
    ├── README.md
    ├── dist // 文件夹,文件夹 src 打包后的代码
    ├── package.json
    ├── src
    │ ├── components
    │ │ ├── config.html
    │ │ └── config.ts
    │ ├── dashboards // Dashboards 典型模板存放
    │ │ ├── example_cdb_dashboard.json
    │ │ └── example_cvm_dashboard.json
    │ ├── datasource // Datasource Plguin 代码
    │ │ ├── __mocks__
    │ │ │ └── core_module.ts
    │ │ ├── common
    │ │ │ ├── constants.ts
    │ │ │ └── sign.ts
    │ │ ├── components // 自定义的 Angular 组件
    │ │ │ ├── custom_select_dropdown.ts
    │ │ │ └── multi_condition.ts
    │ │ ├── css
    │ │ │ └── query_editor.css
    │ │ ├── config.ctrl.ts // ConfigCtrl 模块
    │ │ ├── datasource.ts // Datasource 模块
    │ │ ├── query.ctrl.ts // QueryCtrl 模块
    │ │ ├── img
    │ │ │ └── tencent-cloud.svg
    │ │ ├── partials // Datasource Plugin 中的 html 页面
    │ │ │ ├── config.html // config.ctrl.ts 对应的 html
    │ │ │ ├── query.editor.html // query.ctrl.ts 对应的 html
    │ │ ├── module.ts // Datasource Plguin 的 module.ts
    │ │ ├── plugin.json // Datasource Plguin 的 module.ts
    │ │ ├── specs // 测试用例文件夹
    │ │ │ ├── tc_monitor_cdb_datasource.test.ts
    │ │ │ └── tc_monitor_cvm_datasource.test.ts
    │ │ └── tc_monitor // 云监控相关的产品
    │ │ ├── cdb
    │ │ │ ├── datasource.ts
    │ │ │ ├── query.ts
    │ │ │ └── query_def.ts
    │ │ ├── cvm
    │ │ │ ├── datasource.ts
    │ │ │ ├── query.ts
    │ │ │ └── query_def.ts
    │ │ └── index.ts
    │ ├── image // 文件夹,存放README.md 中图片
    │ ├── img
    │ │ └── tencent-cloud.svg
    │ ├── module.ts // App Plguin 的 module.ts
    │ └── plugin.json // App Plugin 的 plugion.json
    ├── jest.config.js // jest 框架的配置信息
    ├── tsconfig.jest.json
    ├── tsconfig.json
    ├── tslint.json
    ├── webpack.config.analyze.js
    ├── webpack.config.js
    └── webpack.config.prod.js

    在每个 Plugin 开发中存在两个重要的配置文件: plugin.jsonmodule.ts

    plugin.json

    plugin.json(Required): 用于描述插件的相关信息。在 Grafana 服务启动时会扫描所有的插件文件夹并挂载每个插件的 dist 目录,并查找 plugin.json 文件,根据文件的内容完成插件的自动注册。

    在 Tencent Cloud Monitor App 中存在两种类型的 Plugin, 其配置文件如下: App Plugin 中配置 plugin.json


    {
    "type": "app", // 插件的类型: panel | app | datasource
    "name": "Tencent Cloud Monitor", // 插件名称
    "id": "tencentcloud-monitor-app", // 插件ID, 必须唯一
    "info": {
    "description": "Tencent Cloud Monitor App for Grafana",
    "author": {
    "name": "Tencent Cloud"
    },
    "keywords": [
    "tencentcloud",
    "tencentcloudmonitor",
    "grafana",
    "plugins"
    ],
    "logos": {
    "small": "img/tencent-cloud.svg",
    "large": "img/tencent-cloud.svg"
    },
    "version": "1.0.0",
    "updated": "2019-04-10"
    },
    "includes": [ // App Plugin 中包含的 Datasource Plugin 和 Dashboards 模板信息
    {
    "type": "dashboard",
    "name": "【实例】CDB 单机监控",
    "path": "dashboards/example_cdb_dashboard.json"
    },
    {
    "type": "dashboard",
    "name": "【实例】CVM 单机监控",
    "path": "dashboards/example_cvm_dashboard.json"
    },
    {
    "type": "datasource",
    "name": "Tencent Cloud Monitor Datasource"
    }
    ],
    "dependencies": {
    "grafanaVersion": "6.0",
    "plugins": []
    }
    }

    Datasource Plugin 中配置 plugin.json

    {
    "type": "datasource",
    "name": "Tencent Cloud Monitor Datasource",
    "id": "tencentcloud-monitor-datasource",
    "metrics": true, // Datasource plugin 特有的属性,是否在 panel 中支持 metrics
    "annotations": true, // Datasource plugin 特有的属性,是否在 dashboard 中支持 annotations 查询
    "queryOptions": {
    "maxDataPoints": true
    },
    "routes": [],
    "info": {
    "author": {
    "name": "Tencent Cloud"
    },
    "logos": {
    "small": "img/tencent-cloud.svg",
    "large": "img/tencent-cloud.svg"
    }
    }
    }

    特别注意 Datasource Plugin 的 plugin.json 配置中必须存在 metricannotations,且其中至少有一个属性的值为 true

    module.ts

    module.ts(Required): Plugin 入口文件,决定了 Plugin 的具体实现的。根据插件的类型不同其内容也有所差异。


    /* App Plugin 的 module.ts 需要导出1个模块 */
    export {
    ConfigCtrl,
    };

    /* Datasource Plugin 的 module.ts 通常需要导出5个模块 */
    export {
    Datasource, // Required
    ConfigCtrl, // Required
    QueryCtrl, // Required
    AnnotationsQueryCtrl,
    QueryOptionsCtrl
    };

    Tencent Cloud Monitor App 开发实践

    基于腾讯云云监控 API —— Tencent Cloud Monitor App 完整结构图如下所示:

    在整个应用开发中最为重要的是 Datasource Plugin 模块的开发,下面我们以该模块为例进行详细介绍。

    Datasource Plugin 的开发

    Datasource Plugin 中有3个必须文件:DatasourceQueryCtrlConfigCtrl


    Datasource

    Datasource 类作为数据入口,主要负责与数据源进行通信。 针对 Tencent Cloud Monitor App 中不同的产品,都必须有一个对应 Datasource 实现类。因此我们定义了一个 Datasource 类的接口协议,每个产品的 Datasource 类都必须遵循这个接口协议:

    interface DatasourceInterface {
    instanceSettings: any;
    backendSrv: any;
    templateSrv: any;
    query(options: any);
    testDatasource();
    metricFindQuery(query: any);
    getRegions(service: string);
    getMetrics(service: string, region: string);
    getInstances(service: string, region: string, params: any);
    getZones?: (service: string, region: string) => any;
    }

    备注:

    // Datasource 类如果要实现以下功能函数,则必须遵循 Grafana 命名协议约定,所以 Datasource 类的接口协议也是按照该要求进行设计。
    query(options) // Required, used by panels to get data
    testDatasource() // Required, used by datasource configuration page to make sure the connection is working
    annotationQuery(options) // used by dashboards to get annotations
    metricFindQuery(options) // used by query editor to get metric suggestions.

    Datasource 类的主要代码:

    /* Datasource Plugin 中的 datasource 类 */
    import { Datasources, SERVICES } from './tc_monitor'; // Datasources 是每个云产品对应的 Datasource 实现类组成的对象
    export class TCMonitorDatasource implements DatasourceInterface {
    instanceSettings: any;
    backendSrv: any;
    templateSrv: any;

    /** @ngInject */
    constructor(instanceSettings, backendSrv, templateSrv) {
    this.instanceSettings = instanceSettings;
    this.backendSrv = backendSrv;
    this.templateSrv = templateSrv;
    _.forEach(Datasources, (_class, key) => { // 自动实例化每个云产品的 Datasource 类
    this[key] = new _class(this.instanceSettings, this.backendSrv, this.templateSrv);
    });
    }
    testDatasource() {...} // 根据选中的云产品去调用每个云产品 Datasource 类中对应的 testDatasource()
    query(options) {...} // 根据选中的云产品去调用每个云产品 Datasource 类中对应的 query()
    metricFindQuery(query) {...} // 根据选中的云产品去调用每个云产品 Datasource 类中对应的 getRegions()
    getRegions() {...} // 根据选中的云产品去调用每个云产品 Datasource 类中对应的 getMetrics()
    getMetrics() {...} // 根据选中的云产品去调用每个云产品 Datasource 类中对应的 getZones()
    getInstances() {...}
    getZones() {...}
    }

    /*CVM 产品中的 datasource 模块*/
    export default class CVMDatasource implements DatasourceInterface {
    constructor() {...}
    testDatasource() {...}
    query(options) {...}
    metricFindQuery(query) {...}
    getRegions() {...}
    getMetrics() {...}
    getInstances() {...}
    getZones() {...}
    }

    在新增产品时只需在 tc_monitor 目录中增加对应子目录实现各自的 datasource.ts 类(继承DatasourceInterface 协议),再在tc_monitor 目录的 index.tx 文件中通过 Datasources 配置该类入口。

    QueryCtrl

    当用户在 Dashboard 页面对 Panel 进行编辑时,QueryCtrl 类将被实例化并作为 Angular 控制器,并根据类中的 templateUrl 去加载对应的 View 视图,以图形化的界面提供接口数据查询。该类必须继承自 grafana/app/plugins/sdk。具体页面展示以及主要代码逻辑如下:

    import { QueryCtrl } from 'grafana/app/plugins/sdk';

    export class TCMonitorDatasourceQueryCtrl extends QueryCtrl {
    static templateUrl = 'datasource/partials/query.editor.html';
    datasource: any; // 对应 datasource.ts 实例的对象
    panelCtrl: any; // 对应 Panel 的实例对象
    target: { // 具体的查询条件信息保存
    refId: string;
    namespace: string;
    service: string;
    showInstanceDetails: boolean;
    };
    defaults = { // 初始化值
    namespace: '',
    service: '',
    showInstanceDetails: false,
    ...InitServiceState,
    };

    lastQuery: string;
    lastQueryError?: string;

    /** @ngInject */
    constructor($scope, $injector, private templateSrv) {
    super($scope, $injector);
    _.defaultsDeep(this.target, this.defaults);
    this.panelCtrl.events.on('data-received', this.onDataReceived.bind(this), $scope);
    }

    // Panel 实例的数据接收处理函数
    onDataReceived(dataList) {
    this.lastQueryError = undefined;
    this.lastQuery = '';
    const anySeriesFromQuery: any = _.find(dataList, { refId: this.target.refId });
    if (anySeriesFromQuery) {
    this.lastQuery = anySeriesFromQuery.query;
    }
    }

    // Panel 数据查询失败的调用函数
    onDataError(err) {
    this.handleQueryCtrlError(err);
    }

    handleQueryCtrlError(err) {...}
    // 省略其它详细代码
    }

    对应视图 View 中的部分代码如下,<query-editor-row query-ctrl="ctrl"></query-editor-row> 标签的内容会加入到Add Query模板中:

    <query-editor-row query-ctrl="ctrl" class="generic-datasource-query-row" has-text-edit-mode="true">
    <div class="gf-form-inline">
    <div class="gf-form">
    <label class="gf-form-label query-keyword width-9">Namespace</label>
    <div class="gf-form-select-wrapper gf-form-select-wrapper--caret-indent">
    <select class="gf-form-input min-width-12" ng-model="ctrl.target.namespace" ng-options="f as f for f in ctrl.namespaces"
    ng-change="ctrl.onNamespaceChange()"></select>
    </div>
    </div>
    </div>
    <!-- 省略更多详情 -->

    <!-- 新增不同的云产品,需要在该处增加新产品独有的配置页面 -->
    <!-- CVM -->
    <cvm-query
    ng-if="ctrl.target.service==='cvm'"
    target="ctrl.target.cvm"
    show-detail="ctrl.checkShowDetail('instance')"
    datasource="ctrl.datasource"
    on-change="ctrl.onInstanceQueryChange()"
    region="ctrl.replace(ctrl.target.cvm.region)"
    ></cvm-query>

    <!-- Global error message -->
    <div class="gf-form" ng-show="ctrl.lastQueryError">
    <pre class="gf-form-pre alert alert-error">{{ctrl.lastQueryError}}</pre>
    </div>
    </query-editor-row>

    QueryCtrl 类是查询面板的入口,其中 NamespaceRegionMetricNamePeriodInsatnce 查询条件是腾讯云产品共有的,其业务逻辑实现在 QueryCtrl 类中。对于自定义业务,则可在自定义QueryCtrl 类中实现单独的 Angular 组件。以上面图片显示的面板为例,其中 ShowDetail 控制获取特定业务的实例列表数据,因此需抽象到单独的 Angular 组件中。新增产品则需要在 tc_monitor 目录实现各自的 query.ts 类,并在 index.tx 文件中通过 import 注册该组件,则对应在 query.editor.html 中引入产品实现的组件即可。

    ConfigCtrl 类

    ConfigCtrl 类是添加数据源的面板进行控制。 当用户对该 App Plugin 的数据源进行配置时,该类会被实例化为 Angular 的控制器,并根据类中的 templateUrl 去加载对应的 View 视图,用于呈现数据源自定义配置的面板。具体页面展示示例如下:

    /* 文件路径为 /src/datasource/config.ctrl.ts */
    import * as _ from 'lodash';
    import { SERVICES } from './tc_monitor';

    export class TCMonitorDatasourceConfigCtrl {
    static templateUrl = 'datasource/partials/config.html'; // 指定该Controller 对应 View 文件,且实际路径为 /src/datasource/partials/config.html
    current: any;
    /** @ngInject */
    constructor($scope) {
    this.current.jsonData.services = SERVICES;
    _.forEach(this.current.jsonData.services, (service) => {
    this.current.jsonData[service.service] = true;
    });
    }
    }

    结束

    Tencent Cloud Monitor App 已经在 github.com 上开源了,欢迎大家多提 issues,顺便给我们 Star 鼓励一下。
    项目地址:TencentCloud/tencentcloud-monitor-grafana-app (github.com/TencentClou…)

    项目代码开发成员:


    本文转载自链接:https://juejin.im/post/5cdea925f265da1b7c60e702

     
     
  • 相关阅读:
    php 实现四种排序两种查找
    GIT常用命令
    2016-the brave never die
    Apache 的ab压力测试工具
    SQL语句优化实践
    C#设计模式:访问者模式(Vistor Pattern)
    泛型反射性能优化
    C#GC垃圾回收和析构函数和IDisposable的使用
    C#配合大数据开发,nest.dll的使用
    C#导出大量数据到excel,怎么提升性能
  • 原文地址:https://www.cnblogs.com/momoyan/p/11920390.html
Copyright © 2011-2022 走看看