技术标签: 前端环境 开发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的插件氛围三种类型(Panel, Datasource, App),这一次主要记录Panel类型的插件开发.
根据官网的描述, 插件包一般放在/var/lib/grafana/plugins
或者data/plugins
(相对Grafana源码目录). 前者是生产环境, 后者是开发环境. 所以我们这一次选择后者, 毕竟一会儿要从源码修改Grafana的前端代码, 然后启动go语言编写的后端.
基础知识准备:
angularjs, systemjs, typescript, jquery, echarts, grunt, nodejs and golang.
先把官网上说明需要的文件目录加上.
johnnyb-awesome-datasource
|-- dist # 存放编译打包后的插件代码
|-- spec # 测试代码
| |-- datasource_spec.js
| |-- query_ctrl_spec.js
| |-- test-main.js
|-- src # 插件源码
| |-- img # 需要的图片, 比如LOGO, 可选
| | |-- logo.svg
| |-- partials # 界面文件, 可选
| | |-- annotations.editor.html
| | |-- config.html
| | |-- query.editor.html
| |-- datasource.js
| |-- module.js # 唯一入口文件
| |-- plugin.json # 插件描述文件
| |-- query_ctrl.js
|-- Gruntfile.js # Grunt任务
|-- LICENSE
|-- package.json
|-- README.md # 这也会显示在插件说明中
README.md: The only difference from how GitHub renders markdown is that html is not allowed.
实际上并不需要严格按照上述目录存放文件, 关键点在于: 插件目录下需要有src/
, dist/
. src/
中需要有module.js
和plugin.json
. 其他开心就好.
所以实际上, 我的目录结构是这样:
practice-panel
|-- dist # 存放编译打包后的插件代码
|-- src # 插件源码
| |-- partials # 界面文件, 可选
| | |-- module.html
| | |-- module.editor.html
| |-- module.js # 唯一入口文件
| |-- plugin.json # 插件描述文件
| |-- controller.js # 分离出来的Controller, 也可全部放在module.js里面
|-- Gruntfile.js # Grunt任务描述
|-- package.json
|-- README.md
然后来认识一个文件, 这个文件是用来描述插件的. 包括插件的唯一标识, 名字, 作者, 版本等等. 全文是这样的:
{
"id": "",
"type": "",
"name": "",
"info": {
"description": "",
"author": {
"name": "",
"url": ""
},
"keywords": [],
"logos": [
"small": "",
"large": ""
],
"version": ""
},
"dependencies": {
"grafanaVersion": "",
"plugins": []
}
}
具体的含义, 参考附录中的官方说明链接. 本次的内容参考源码文件.
这基本上就是约定, Grafana会从插件包的dist/
第一个读取的文件就是module.js
文件. 不管用什么语言编写, 最终都要保证dist/module.js
可读.
Grafana的前端模块化方案采用的Systemjs. 如果熟悉任何一种模块化方案都行, 这里的影响并不是很大, 除了需要添加依赖资源. 在插件开发过程中, 开发者是无法添加任何依赖资源的. 因为插件是作为Grafana前端整体的一部分在运行. 所有的资源配置都写在Grafana源码目录的public/app/system.conf.js
文件中, 资源都放在public/vendor/
目录中.
默认可用资源如下:
virtual-scroll
mousetrap
remarkable
tether
eventemitter3
tether-drop
moment
jquery
lodash-src
lodash
angular
bootstrap
angular-route
angular-sanitize
angular-ui
angular-strap
angular-dragdrop
angular-bindonce
spectrum
bootstrap-tagsinput
jquery.flot
jquery.flot.pie
jquery.flot.selection
jquery.flot.stack
jquery.flot.stackpercent
jquery.flot.time
jquery.flot.crosshair
jquery.flot.fillbelow
jquery.flot.gauge
d3
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',
上下文看起来像这样:
'tether-drop': 'vendor/npm/tether-drop/dist/js/drop.js',
'moment': 'vendor/moment.js',
'echarts': 'vendor/echarts.min.js',
'jquery': 'vendor/jquery/dist/jquery.js',
准备工作基本完成了, 但是编码之前, 需要认识一个类: MetricsPanelCtrl
. 这个类的源码文件位于Grafana源码目录下public/app/features/panel/metrics_panel_ctrl.ts
. MetricsPanelCtrl
类继承自PanelCtrl
类, 是我们完成本次Panel类型插件开发必须要用到的. 它主要是解决了以下三个问题:
在进入编辑状态后, 使metrics Tab成为默认面板.
constructor($scope, $injector) {
super($scope, $injector);
// make metrics tab the default
this.editorTabIndex = 1;
// ... other code
}
订阅事件:
this.events.on('refresh', this.onMetricsPanelRefresh.bind(this));
this.events.on('init-edit-mode', this.onInitMetricsPanelEditMode.bind(this));
this.events.on('panel-teardown', this.onPanelTearDown.bind(this));
提供设置数据源后的响应:
setDatasource(datasource) {
// ... other code
this.panel.datasource = datasource.value;
this.datasourceName = datasource.name;
this.datasource = null;
this.refresh();
}
因为文档中并无特别描述, 所以以下是已知的插件支持的事件:
refresh
can be used to response when refresh button was clicked.init-edit-mode
can be used to add tabs when editing a panelpanel-teardown
can be used for clean updata-received
is an event in that is triggered on data refresh and can be hooked intodata-snapshot-load
is an event triggered to load data when in snapshot mode.data-error
is used to handle errors on dashboard refresh.Controller类必须实现link方法或者init方法. 这是Grafana的插件机制决定的. 与此同时, Controller的实例对象也将作为AngularJS组件的上下文对象存在.
// app/core/directives/plugin_component.ts
function getPluginComponentDirective(options) {
// other code
return function() {
return {
// other code
link: (scope, elem, attrs, ctrl) => {
if (ctrl.link) {
ctrl.link(scope, elem, attrs, ctrl);
}
if (ctrl.init) {
ctrl.init();
}
}
}
}
}
而这个函数是作为AngularJS的指令处理函数存在的. 所以我们的controller.js看起来至少应该是这样的:
import { MetricsPanelCtrl } from 'app/plugins/sdk';
export class Controller extends MetricsPanelCtrl {
constructor() {
// initialize
// subscribe events
}
link(scope, elem, attrs, ctrl) {
// impelement linking
}
}
完整实现细节请参考源码文件.
是的, 此时还没有界面. 在编写界面之前, 我们先了解一下插件的二种状态.
插件有二种状态, 一种是只读状态, 一种是编辑状态. 只读状态就是打开一个dashboard时各个Panel表现的状态. 编辑状态是点击”Edit”之后, 进入的可以影响数据源的状态. 我们需要分别为这二种状态编写页面.
完整实现细节参考源码文件.
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类后, 添加静态属性字段:
Controller.templateUrl = './partials/module.html';
编辑状态的界面则需要在init-edit-mode
事件处理函数中注册:
onInitEditMode() {
this.addEditorTab('Options', 'public/plugins/practice-panel/partials/module.editor.html', 2);
}
完整实现细节参考源码文件.
编译Grafana官方使用的是Grunt, 实际上只要按照目录结构来, 用什么打包工具并不重要.
grunt
一个练习插件就这么完成了.
一种数据的四种表现形式. 其中右下角红色的柱状图即本次练习插件.
图表数据Grafana只支持二种, 时序图和非时序图. 非时序图仅返回一个普通的数据结构:
文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态
文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境
文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn
文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker
文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机
文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk
文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入
文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。 Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。
文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动
文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计
文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;gt;Jni-&amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图
文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法