Grafana 的插件开发_grafana 插件开发-程序员宅基地

技术标签: 前端环境  开发grafana的panel插件  

<1>推荐一个网址:http://blog.leanote.com/post/nixon/%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91

Grafana Panel Plugin 开发

Grafana 插件开发

上一次分享提到过Grafana的插件氛围三种类型(Panel, Datasource, App),这一次主要记录Panel类型的插件开发.

0. 起手式

根据官网的描述, 插件包一般放在/var/lib/grafana/plugins或者data/plugins(相对Grafana源码目录). 前者是生产环境, 后者是开发环境. 所以我们这一次选择后者, 毕竟一会儿要从源码修改Grafana的前端代码, 然后启动go语言编写的后端.

基础知识准备: 
angularjs, systemjs, typescript, jquery, echarts, grunt, nodejs and golang.

1. 目录结构

先把官网上说明需要的文件目录加上.

  1. johnnyb-awesome-datasource
  2. |-- dist # 存放编译打包后的插件代码
  3. |-- spec # 测试代码
  4. | |-- datasource_spec.js
  5. | |-- query_ctrl_spec.js
  6. | |-- test-main.js
  7. |-- src # 插件源码
  8. | |-- img # 需要的图片, 比如LOGO, 可选
  9. | | |-- logo.svg
  10. | |-- partials # 界面文件, 可选
  11. | | |-- annotations.editor.html
  12. | | |-- config.html
  13. | | |-- query.editor.html
  14. | |-- datasource.js
  15. | |-- module.js # 唯一入口文件
  16. | |-- plugin.json # 插件描述文件
  17. | |-- query_ctrl.js
  18. |-- Gruntfile.js # Grunt任务
  19. |-- LICENSE
  20. |-- package.json
  21. |-- README.md # 这也会显示在插件说明中

README.md: The only difference from how GitHub renders markdown is that html is not allowed.

实际上并不需要严格按照上述目录存放文件, 关键点在于: 插件目录下需要有src/dist/src/中需要有module.jsplugin.json. 其他开心就好.

所以实际上, 我的目录结构是这样:

  1. practice-panel
  2. |-- dist # 存放编译打包后的插件代码
  3. |-- src # 插件源码
  4. | |-- partials # 界面文件, 可选
  5. | | |-- module.html
  6. | | |-- module.editor.html
  7. | |-- module.js # 唯一入口文件
  8. | |-- plugin.json # 插件描述文件
  9. | |-- controller.js # 分离出来的Controller, 也可全部放在module.js里面
  10. |-- Gruntfile.js # Grunt任务描述
  11. |-- package.json
  12. |-- README.md

2. 插件描述文件(.json)

然后来认识一个文件, 这个文件是用来描述插件的. 包括插件的唯一标识, 名字, 作者, 版本等等. 全文是这样的:

  1. {
  2. "id": "",
  3. "type": "",
  4. "name": "",
  5. "info": {
  6. "description": "",
  7. "author": {
  8. "name": "",
  9. "url": ""
  10. },
  11. "keywords": [],
  12. "logos": [
  13. "small": "",
  14. "large": ""
  15. ],
  16. "version": ""
  17. },
  18. "dependencies": {
  19. "grafanaVersion": "",
  20. "plugins": []
  21. }
  22. }

具体的含义, 参考附录中的官方说明链接. 本次的内容参考源码文件.

3. 入口文件

这基本上就是约定, Grafana会从插件包的dist/第一个读取的文件就是module.js文件. 不管用什么语言编写, 最终都要保证dist/module.js可读.

4. 可用依赖资源

Grafana的前端模块化方案采用的Systemjs. 如果熟悉任何一种模块化方案都行, 这里的影响并不是很大, 除了需要添加依赖资源. 在插件开发过程中, 开发者是无法添加任何依赖资源的. 因为插件是作为Grafana前端整体的一部分在运行. 所有的资源配置都写在Grafana源码目录的public/app/system.conf.js文件中, 资源都放在public/vendor/目录中.

默认可用资源如下:

  1. virtual-scroll
  2. mousetrap
  3. remarkable
  4. tether
  5. eventemitter3
  6. tether-drop
  7. moment
  8. jquery
  9. lodash-src
  10. lodash
  11. angular
  12. bootstrap
  13. angular-route
  14. angular-sanitize
  15. angular-ui
  16. angular-strap
  17. angular-dragdrop
  18. angular-bindonce
  19. spectrum
  20. bootstrap-tagsinput
  21. jquery.flot
  22. jquery.flot.pie
  23. jquery.flot.selection
  24. jquery.flot.stack
  25. jquery.flot.stackpercent
  26. jquery.flot.time
  27. jquery.flot.crosshair
  28. jquery.flot.fillbelow
  29. jquery.flot.gauge
  30. d3
  31. jquery.flot.dashes

是的, 像D3, jquery, moment, lodash这些非常有用的图表基础库都有了, 甚至很贴心的连AngularJS全家桶都有. 美中不足的是AngularJS版本偏低: 1.6.1.

但这一次练习, 我们要用echarts来构建图表. 很遗憾, Grafana没有这项资源. 所以总共需要修改二个地方.

  • echarts.min.js放入public/vendor/目录
  • 修改public/app/system.conf.js文件, 在paths节点中添加代码: 'echarts': 'vendor/echarts.min.js', 上下文看起来像这样:

    1. 'tether-drop': 'vendor/npm/tether-drop/dist/js/drop.js',
    2. 'moment': 'vendor/moment.js',
    3. 'echarts': 'vendor/echarts.min.js',
    4. 'jquery': 'vendor/jquery/dist/jquery.js',

5. 开始编码

MetricsPanelCtrl类

准备工作基本完成了, 但是编码之前, 需要认识一个类: MetricsPanelCtrl. 这个类的源码文件位于Grafana源码目录下public/app/features/panel/metrics_panel_ctrl.tsMetricsPanelCtrl类继承自PanelCtrl类, 是我们完成本次Panel类型插件开发必须要用到的. 它主要是解决了以下三个问题:

  1. 在进入编辑状态后, 使metrics Tab成为默认面板.

    1. constructor($scope, $injector) {
    2. super($scope, $injector);
    3. // make metrics tab the default
    4. this.editorTabIndex = 1;
    5. // ... other code
    6. }
  2. 订阅事件:

    1. this.events.on('refresh', this.onMetricsPanelRefresh.bind(this));
    2. this.events.on('init-edit-mode', this.onInitMetricsPanelEditMode.bind(this));
    3. this.events.on('panel-teardown', this.onPanelTearDown.bind(this));
  3. 提供设置数据源后的响应:

    1. setDatasource(datasource) {
    2. // ... other code
    3.  
    4. this.panel.datasource = datasource.value;
    5. this.datasourceName = datasource.name;
    6. this.datasource = null;
    7. this.refresh();
    8. }

插件事件

因为文档中并无特别描述, 所以以下是已知的插件支持的事件:

  • refresh can be used to response when refresh button was clicked.
  • init-edit-mode can be used to add tabs when editing a panel
  • panel-teardown can be used for clean up
  • data-received is an event in that is triggered on data refresh and can be hooked into
  • data-snapshot-load is an event triggered to load data when in snapshot mode.
  • data-error is used to handle errors on dashboard refresh.

编写一个controller.js

Controller类必须实现link方法或者init方法. 这是Grafana的插件机制决定的. 与此同时, Controller的实例对象也将作为AngularJS组件的上下文对象存在.

  1. // app/core/directives/plugin_component.ts
  2. function getPluginComponentDirective(options) {
  3. // other code
  4. return function() {
  5. return {
  6. // other code
  7. link: (scope, elem, attrs, ctrl) => {
  8. if (ctrl.link) {
  9. ctrl.link(scope, elem, attrs, ctrl);
  10. }
  11. if (ctrl.init) {
  12. ctrl.init();
  13. }
  14. }
  15. }
  16. }
  17. }

而这个函数是作为AngularJS的指令处理函数存在的. 所以我们的controller.js看起来至少应该是这样的:

  1. import { MetricsPanelCtrl } from 'app/plugins/sdk';
  2.  
  3. export class Controller extends MetricsPanelCtrl {
  4. constructor() {
  5. // initialize
  6. // subscribe events
  7. }
  8.  
  9. link(scope, elem, attrs, ctrl) {
  10. // impelement linking
  11. }
  12. }

完整实现细节请参考源码文件.

是的, 此时还没有界面. 在编写界面之前, 我们先了解一下插件的二种状态.

6. 插件状态

插件有二种状态, 一种是只读状态, 一种是编辑状态. 只读状态就是打开一个dashboard时各个Panel表现的状态. 编辑状态是点击”Edit”之后, 进入的可以影响数据源的状态. 我们需要分别为这二种状态编写页面.

完整实现细节参考源码文件.

7. HTML + CSS

Grafana提供一些布局样式和外观样式. 非常不幸, 我没有在官方文档上找到对应的样式说明. 不过幸运的是, 插件目前只有三种, 而且三种都提供了Example代码. 分别是:

https://github.com/grafana/piechart-panel

https://github.com/grafana/simple-json-datasource

https://github.com/grafana/kubernetes-app

这一次练习则是copy的piechart-panel的编辑页面. 用起来有点类似bootstrap的感觉.

好了, 重点来了: 在编写完成界面后, 需要将界面和controller关联在一起.

只读状态的界面关联方法是在controller.js中声明完Controller类后, 添加静态属性字段:

  1. Controller.templateUrl = './partials/module.html';

编辑状态的界面则需要在init-edit-mode事件处理函数中注册:

  1. onInitEditMode() {
  2. this.addEditorTab('Options', 'public/plugins/practice-panel/partials/module.editor.html', 2);
  3. }

完整实现细节参考源码文件.

8. 编译打包

编译Grafana官方使用的是Grunt, 实际上只要按照目录结构来, 用什么打包工具并不重要.

grunt

一个练习插件就这么完成了.

9. 总结

success.png
一种数据的四种表现形式. 其中右下角红色的柱状图即本次练习插件.

图表数据Grafana只支持二种, 时序图和非时序图. 非时序图仅返回一个普通的数据结构:

type_choice.png
dev.png

附录

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41646716/article/details/82733410

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签