内容简介:kibana官方没有插件的开发教程,Tim Rose的教程写的十分详尽,也是官方推荐的。由于这个系列的教程是英文版的,且基于kibana4,近日需要做kibana的开发,硬啃下这些教程之后,且根据kibana6.3.2版本做了些改进,记录下来,留下个爪。由于本人水平有限,错漏的地方欢迎大家指出。原文链接:原文标题:Writing Kibana 4 Plugins – Visualizations using Data
kibana官方没有插件的开发教程,Tim Rose的教程写的十分详尽,也是官方推荐的。由于这个系列的教程是英文版的,且基于kibana4,近日需要做kibana的开发,硬啃下这些教程之后,且根据kibana6.3.2版本做了些改进,记录下来,留下个爪。由于本人水平有限,错漏的地方欢迎大家指出。
原文链接: www.timroes.de/writing-kib…
原文标题:Writing Kibana 4 Plugins – Visualizations using Data
简单可视化插件
你需要先阅读简单可视化插件,才能阅读本文。
在前面的章节(在阅读本文前,一定要先阅读),你已经学会了如何创建一个简单的可视化插件,但并不从elasticsearch获取 任何数据。在这一章,我们将写另外一个插件,像其他插件一样,需要消费elasticsearch的数据。
我们将写一个很简单的标签云插件,我们会把桶的名称作为标签展示出来,度量聚合数据的大小将决定这个标签字体的大小。如果你对桶和度量还不是很熟悉,可以参考一下我这篇k4v教程。
这篇教程的源码可以在 GitHub 找到
在整个教程当中,我会用 tr-k4p-tagcloud
这个名字。你需要用一个全局唯一的名字来替代他。
标签云可视化插件
首先我们要想想,我们需要以何种方式来可视化何种数据,这意味着,我们需要考虑,我们的视化插件,会呈现什么桶和什么度量的数据。
我们会尽量保持插件的简单性,所以只采用了一个桶和一个度量。桶聚合决定了什么标签会被展示出来(一个桶就是一个标签),维度聚合决定了标签的大小,即聚合的度量结果越高,所显示的标签就会越大。
决定用多少维度和桶的聚合数据是很重要的,如果你能内嵌聚合,你一会还要再插件中定义。
定义和注册插件
跟前面章节的一样,第一步是创建 index.js
, package.json
,和注册一个简单的可视化provider。下面我们只展示主要的provider代码片段(你可以在 public/tagclouc.js
中找到):
function TagcloudProvider(Private) { var TemplateVisType = Private(require('ui/template_vis_type/TemplateVisType')); return new TemplateVisType({ name: 'trTagcloud', // The internal id of the visualization (must be unique) title: 'Tagcloud', // The title of the visualization, shown to the user description: 'Tagcloud visualization', // The description of this vis icon: 'fa-cloud', // The font awesome icon of this visualization template: require('plugins/tr-k4p-tagcloud/tagcloud.html') }); } require('ui/registry/vis_types').register(TagcloudProvider); 复制代码
跟前面的教程相比较,这里又两个不一样的地方:
-
我们在定义模块的时候,丢弃了
define()
函数(AMD 模块定义)。就像前面说的,这个是非必要的,由于我们使用了webpack作为打包工具,这也意味着你不再需要在模块中返回provider函数。 -
我们去除了
requiresSearch: false
选项,我们的tagcloud插件需要从elasticsearch中获取数据,所以我们的插件就可以像其他使用数据的插件一样来进行查询。由于requiresSearch: true
是默认选项,所以我们去掉这个选项就行了。
现在我们需要来创建 public/tagcloud.html
,现在可以让他置空。第一部分的代码可以在在github的 tag0.1.0
找到。
定义数据结构
一个需要使用聚合数据的插件,你需要明确的指出,你的插件需要什么样的聚合数据,或者说,什么样的数据是被我的插件接受的。这所谓的数据结构需要在插件定义的时候给出,我们来修改一下插件定义:
function TagcloudProvider(Private) { var TemplateVisType = /* ... */; // Include the Schemas class, which will be used to define schemas var Schemas = Private(require('ui/Vis/Schemas')); return new TemplateVisType({ /* every attribute shown above */, schemas: new Schemas([ { group: 'metrics', name: 'tagsize', title: 'Tagsize', min: 1, max: 1, aggFilter: ['count', 'avg', 'sum', 'min', 'max', 'cardinality', 'std_dev'] }, { group: 'buckets', name: 'tags', title: 'Tags', min: 1, max: 1, aggFilter: '!geohash_grid' } ]) }); } 复制代码
为了定义数据结构,我们需要实例化一个 Schemas
对象,我们需要传一个数组作为构造函数的参数,数组的每个对象定义了一个你所需要的聚合数据,每个聚合对象有如下属性:
-
group
metrics
或者buckets
二选一,定义了这个对象所属的聚合数据类型 - name 这个聚合数据的名字(id)。以后你可以用这个属性来引用不同的聚合数据
- title 这个是展示给用户看的,当他添加一个单项聚合的时候,这个会告诉他,这个数据将会被怎么使用,再本例中,桶数据会被用作标签,维度数据则影响的是标签的字体大小
- min/max 用户能够添加的此聚合的范围,例如,用户添加一个直方图,一个桶聚合的名称叫“图列”。这个是没有限制的,即没有最大值限制,就像用户想要有多少个直方图的条数,就能有多少个。在本例中,我们各种数据只允许一个聚合数据,由于我们的插件的工作方式。
- 过滤器 决定了哪种聚合数据是合法的。他的值是一个这里所允许的聚合类型的数组(下面可以看见),或者是一个所不允许的聚合类型的数组(每一个一定要以一个下划线为前缀),在接下来的场景中,其他的聚合类型是允许的。如果这个数组只有一个值,那你也可以把他声明称一个字符串(正如桶聚合所示)。
这里也还有其他的一些字段你可以使用的,但是在本例中不会被用到。
你可以声明的维度聚合的 aggFilter
类型有: svg, cardinality, count, max, median, min, percentileranks, percentiles, stddev, sum
桶聚合的 aggFilter
的类型有:** datehistogram, daterange, filters, geohashgrid, histogram, iprange, range, significant_terms, terms**
在github的tag 0.2.0 上可以找到这一步的代码。
编辑控制器controller
为了给我们的可视化插件天价一些逻辑,我们会再次需要一个angular的controller。与之前不同的是,我们会把这个controller放在一个单独的文件下(因为他会变得大一点),因此,我们需要在 tancloud.js
中添加如下代码:
require('plugins/tr-k4p-tagcloud/tagcloudController') 复制代码
现在我们需要创建一个新文件 public/tagcloudController.js
,先写上一个空白的controller:
var module = require('ui/modules').get('tr-k4p-tagcloud'); module.controller('TagcloudController', function($scope) { // Your logic will go here }); 复制代码
在模板中加载控制器 (public/tagcloud.html)
:
<div ng-controller="TagcloudController"></div> 复制代码
现在插件的模板就可以加载控制器了。
获取数据
我们需要从angular的scope中继承两个变量,一个是从之前章节就知道的 vis
,这个变量包含了插件的信息,和用户的设置信息。另外一个变量就是 esResponse
,这变量保存了 Elasticsearch
的返回数据,kibana'会自动请求elasticsearch,带上当前的query和filters,以及用户的聚合信息。
我们的插件需要把返回数据和用户的设置,通过可视化的方式展示出来,我们可以访问 $scope.esResponse.aggregations
变量来获取我们的查询所返回数据。我们需要获取聚合数据中的id,为了获取指定聚合数据的id,我们需要 $scope.vis.aggs
中的一些方法来找到is。
在我们的场景中,首先我们需要获取全部的桶数据(就是所有的tag名称),我们可以通过如下方式,来获取tags聚合的id
$scope.vis.aggs.bySchemaName['tags'][0].id 复制代码
bySchemaName 对象包含一个聚合数据设置的名字(在schema中指定的)的映射,tags属性是一个用户输入的全部聚合设置的数组,由于我们已经把这个属性的最大值和最小值都设置成了1,我们现在也只有一个对象可以获取他的id了。我们用这个id在 esResponse
中查找我们需要的数据。
我们一般是设置一个 watch
来监听 esResponse
的变化来更新数据,现在我们来把这个tag当成一个list展示出来:
$scope.$watch('esResponse', function(resp) { if (!resp) { $scope.tags = null; return; } // Retrieve the id of the configured tags aggregation var tagsAggId = $scope.vis.aggs.bySchemaName['tags'][0].id; // Get the buckets of that aggregation var buckets = resp.aggregations[tagsAggId].buckets; // Transform all buckets into tag objects $scope.tags = buckets.map(function(bucket) { return { label: bucket.key }; }); }); 复制代码
这样我们的 $scope.tags
就是一个数组,数组里的对象是有一个属性为label,值是bucket.key。相应的,我们也要修改 tagcloud.html
:
<div ng-controller="TagcloudController"> <span ng-repeat="tag in tags">{{tag.label}}</span> </div> 复制代码
完整的代码(包括一些css)可以在GitHub仓库的 0.3.0
获取维度聚合数据相对来说要简单一点,但也遵循这同样的步骤。首先,我们需要要拿到的桶数的维度聚合数据的一个引用:
var metricsAgg = $scope.vis.aggs.bySchemaName['tagsize'][0]; 复制代码
注意:我们并没有读取id,反而读取了整个聚合对象,同样的我们也只是读取了数组中的第一个元素,因为我们只允许配置一个维度聚合。我们可以来完善刚刚的桶数据,给桶数据加上维度数据:
$scope.tags = buckets.map(function(bucket) { return { label: bucket.key, value: metricsAgg.getValue(bucket) }; }); 复制代码
我们可以调用维度聚合对象上的getValue方法,参数是桶bucket,返回值就是这个桶数据想对应的维度数据了。之后我们就可以拿到一个tags的数组,里面的对象都是一个label和一个值。现在剩下的事情就是为我们每个tag计算一个font-size,首选需要统计tag的最大值和最小值,在收集tags数组的时候,我们会设定一个最大的font-size和最小的font-size,然后计算出每个tag相应的字体大小,由于这个跟kibana没有直接关联,只是angular的controller的一些东西,就不在这里展示了,我们会放在GitHub的 0.4.0
中的 tagcloudController.js
和 tagcloud.html
中。
数据累加
tag云是是一个很简单的读取数据的插件。他只有一个维度数据和一个桶数据,没有多维度,也没有内嵌的聚合,等等。在一个更复杂的插件中你会遇到上述的全部状况,那我们现在就来试试处理这些复杂的数据:
-
可以通过
$scope.vis.aggs
对象来获取配置的可视化对象,下面的bySchemaName
,bySchemaGroup
,byTypeName
(例如,count,terms等等),这些属性去获取,scheme里配置的不同name的聚合数据 -
聚合对象的
getValue
方法可以获取bucket对象的数据。
一般来说,还有很多其他的方法,来适应更加复杂的可视化场景,(例如你可以使用聚合对象的 getKey
方法来获取key或者bucket)。这些方法需要等一等,在官方的插件开发文档中找到。阅读源码,经常是最好的方法,在开发的过程中打个断点,然后在浏览器的dev-tool上面观察这些对象。
点击过滤
最后一个我们想添加的功能就是tags过滤,当用户点击tag的时候,仪表盘上应该添加一个该tag的值的过滤器。
第一步,我们要创建一个过滤器来实现过滤服务,我们会使用 Private
服务(这个服务是负责为需要的模块实例化angular服务,在前面章节已经说过了),来实例化一个filter服务,controller中需要做如下修改:
module.controller('TagcloudController', function($scope, Private) { var filterManager = Private(require('ui/filter_manager')); // ... }); 复制代码
filter manger
有一个 add
方法,可以调用来实现添加过滤器,首先我们修改HTML来当用户点击一个标签的时候,调用一个方法:
<span ng-click="filter(tag)" ng-repeat="tag in tags" ...> 复制代码
完整的filter方法:
$scope.filter = function(tag) { // Add a new filter via the filter manager filterManager.add( // The field to filter for, we can get it from the config $scope.vis.aggs.bySchemaName['tags'][0].params.field, // The value to filter for, we will read out the bucket key from the tag tag.label, // Whether the filter is negated. If you want to create a negated filter pass '-' here null, // The index pattern for the filter $scope.vis.indexPattern.title ); }; 复制代码
这一步的完整代码可以在GitHub的 0.5.0 找到。
接下来
现在你已经可以写一个展示来自elasticsearch数据的可视化插件了。写插件的时候,要时刻注意,什么样的scheme是你想展示的,要保证只允许配置你代码中处理了的scheme。所以,如果你允许多个bucket聚合,那你就要把每一个bucket都要在代码中进行处理,这样的话,你就需要从 $scope.vis.aggs.bySchemaName['foobar']
获取数据,而不是仅仅获取第一个。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 翻译 Tim Rose 的kibana插件教程-简单可视化插件
- 【webpack进阶】可视化展示webpack内部插件与钩子关系????
- EDEN-MACE 1.7.0 发布,增加可视化插件
- Grafana 7.0 发布:改进的界面、新的插件平台和可视化等
- 可视化 HTML 编辑器 CKEditor 4.10 发布,新增实用插件
- unity-ugui-XCharts v1.6.2 发布,数据可视化图表插件
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
构建高性能Web站点
郭欣 / 电子工业出版社 / 2012-6 / 75.00元
《构建高性能Web站点(修订版)》是畅销修订版,围绕如何构建高性能Web站点,从多个方面、多个角度进行了全面的阐述,几乎涵盖了Web站点性能优化的所有内容,包括数据的网络传输、服务器并发处理能力、动态网页缓存、动态网页静态化、应用层数据缓存、分布式缓存、Web服务器缓存、反向代理缓存、脚本解释速度、页面组件分离、浏览器本地缓存、浏览器并发请求、文件的分发、数据库I/O优化、数据库访问、数据库分布式......一起来看看 《构建高性能Web站点》 这本书的介绍吧!