译 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'] 获取数据,而不是仅仅获取第一个。


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

查看所有标签

猜你喜欢:

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

构建高性能Web站点

构建高性能Web站点

郭欣 / 电子工业出版社 / 2012-6 / 75.00元

《构建高性能Web站点(修订版)》是畅销修订版,围绕如何构建高性能Web站点,从多个方面、多个角度进行了全面的阐述,几乎涵盖了Web站点性能优化的所有内容,包括数据的网络传输、服务器并发处理能力、动态网页缓存、动态网页静态化、应用层数据缓存、分布式缓存、Web服务器缓存、反向代理缓存、脚本解释速度、页面组件分离、浏览器本地缓存、浏览器并发请求、文件的分发、数据库I/O优化、数据库访问、数据库分布式......一起来看看 《构建高性能Web站点》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具