kibana官方没有插件的开发教程,Tim Rose的教程写的十分详尽,也是官方推荐的。因为这个系列的教程是英文版的,且基于kibana4,近日须要作kibana的开发,硬啃下这些教程以后,虽然这些教程比较古老,不少代码不能用了,可是开发思想仍是通用的。记录下来,留下个爪。因为本人水平有限,错漏的地方欢迎你们指出。css
原文连接:www.timroes.de/writing-kib…html
原文标题:Writing Kibana 4 Plugins – Visualizations using Datawebpack
你须要先阅读基础篇,才能阅读本文。git
在前面的章节(在阅读本文前,必定要先阅读),你已经学会了如何建立一个简单的可视化插件,但并不从elasticsearch获取 任何数据。在这一章,咱们将写另一个插件,像其余插件同样,须要消费elasticsearch的数据。github
咱们将写一个很简单的标签云插件,咱们会把桶的名称做为标签展现出来,度量聚合数据的大小将决定这个标签字体的大小。若是你对桶和度量还不是很熟悉,能够参考一下我这篇k4v教程。web
这篇教程的源码能够在GitHub找到json
在整个教程当中,我会用tr-k4p-tagcloud
这个名字。你须要用一个全局惟一的名字来替代他。数组
首先咱们要想一想,咱们须要以何种方式来可视化何种数据,这意味着,咱们须要考虑,咱们的视化插件,会呈现什么桶和什么度量的数据。浏览器
咱们会尽可能保持插件的简单性,因此只采用了一个桶和一个度量。桶聚合决定了什么标签会被展现出来(一个桶就是一个标签),维度聚合决定了标签的大小,即聚合的度量结果越高,所显示的标签就会越大。bash
决定用多少维度和桶的聚合数据是很重要的,若是你能内嵌聚合,你一会还要再插件中定义。
跟前面章节的同样,第一步是建立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
对象,咱们须要传一个数组做为构造函数的参数,数组的每一个对象定义了一个你所须要的聚合数据,每一个聚合对象有以下属性:
metrics
或者buckets
二选一,定义了这个对象所属的聚合数据类型这里也还有其余的一些字段你可使用的,可是在本例中不会被用到。
你能够声明的维度聚合的aggFilter
类型有:svg, cardinality, count, max, median, min, percentileranks, percentiles, stddev, sum
桶聚合的aggFilter
的类型有:** datehistogram, daterange, filters, geohashgrid, histogram, iprange, range, significant_terms, terms**
在github的tag0.2.0上能够找到这一步的代码。
为了给咱们的可视化插件天价一些逻辑,咱们会再次须要一个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']
获取数据,而不是仅仅获取第一个。