译 Tim Rose 的kibana插件教程-消费数据的可视化插件

栏目: 后端 · 发布时间: 5年前

内容简介: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.jspackage.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.jstagcloud.html 中。

数据累加

tag云是是一个很简单的读取数据的插件。他只有一个维度数据和一个桶数据,没有多维度,也没有内嵌的聚合,等等。在一个更复杂的插件中你会遇到上述的全部状况,那我们现在就来试试处理这些复杂的数据:

  • 可以通过 $scope.vis.aggs 对象来获取配置的可视化对象,下面的 bySchemaNamebySchemaGroupbyTypeName (例如,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'] 获取数据,而不是仅仅获取第一个。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

代码整洁之道:程序员的职业素养

代码整洁之道:程序员的职业素养

罗伯特·C.马丁 (Robert C.Martin) / 余晟、章显洲 / 人民邮电出版社 / 2016-9-1 / 49.00元

1. 汇聚编程大师40余年编程生涯的心得体会 2. 阐释软件工艺中的原理、技术、工具和实践 3. 助力专业软件开发人员具备令人敬佩的职业素养 成功的程序员在以往的工作和生活中都曾经历过大大小小的不确定性,承受过永无休止的压力。他们之所以能够成功,是因为拥有一个共同点,都深切关注创建软件所需的各项实践。他们将软件开发视为一种需要精雕细琢加以修炼的技艺,他们以专业人士的标准要求自己,......一起来看看 《代码整洁之道:程序员的职业素养》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具