kibana插件开发

来源:互联网 发布:查询数据库所有触发器 编辑:程序博客网 时间:2024/06/08 20:01

本文翻译timrose的文章,原文地址:https://www.timroes.de/2016/02/21/writing-kibana-plugins-custom-applications/

在阅读本教程之前,您需要阅读第1部分 - 基础知识。

本教程系列介绍了Kibana中如何创建一个应用程序。一个应用程序是一个插件,它是Kibana平台内部的一部分,可以放置任何你展示的东西。Kibana只是链接到这个部分,你可以随心所欲的设计这个插件。插件众所周知的例子就是Elastic 的timelion插件。

在本教程中,我们将构建一个非常简单的Elasticsearch状态页面应用程序。它列出所有索引,单击一个将带您到有关该索引的信息页面。您可以在下面的动画中看到这个效果。
这里写图片描述
在本教程中,我们将学习:

  • 创建应用程序插件的基本结构
  • 插件如何和elasticsearch进行通信
  • 插件中如何创建多个子页面并如何导航

完整插件的源代码可以在GitHub上找到。这个插件我用了很多ECMAScript 2015 语法。Kibana使用Webpack将您的插件文件捆绑在一起,所以您可以安全地使用ECMAScript 2015。。
github地址:

https://github.com/timroes/elasticsearch_status

创建插件基本结构

以前的教程中我们看到了index.js的结构。要注册一个新的插件,您可以使用对象app内的键uiExport,如下所示:

export default function (kibana) {  return new kibana.Plugin({   require: ['elasticsearch'],    uiExports: {      app: {        title: 'Indices',        description: 'An awesome Kibana plugin',        main: 'plugins/elasticsearch_status/app',        icon: 'plugins/elasticsearch_status/icon.svg'      }    }});

在require中,我们可以引用其他的模块。常见的值是kibana和elasticsearch。指定这些模块因为kibana是在加载完这些模块后加载我们的插件,保证了引用的模块加载成功。我们在这里引用了elasticsearch模块,因为我们在后面要使用elasticsearch的数据。
在uiExports中的信息是来描述这个插件信息的。
- title:插件的名字。
- description:简单介绍插件信息。
- icon:插件的图表
- main:插件的源码位置。默认plugins/插件名字/js文件名

还有其他的一些参数,比如你如果不想让插件显示在导航中,可以添加参数hidden:true。(kibana 的状态页面就是这样。)

创建服务器API

如果要从插件中查询Elasticsearch,那么最好的解决方案就是创建一个新的给Kibana服务器API。你插件中调用这个API,它会为你查询Elasticsearch。

为什么不直接从您的插件中查询Elasticsearch?当然,您也可以使用Elasticsearch JavaScript客户端直接从您的前端查询ES。但这些调用将在用户的浏览器中执行,从而导致CORS(交叉原始资源共享)问题。最好的解决方案是使用Kibana服务器。

因此,如上所述,我们的插件将会获取所有索引的列表,并且需要检索特定索引的统计信息。我们来看看第二个界面。

要向Kibana添加新的服务器API,使用init方法可以指定:

// ...return new kibana.Plugin({  // ...  init(server, options) {    // Initialization goes here  }});

如果你不熟悉这个JavaScript语法,这有一个快捷方式init: function(server, options) {…}。

传递给该方法的服务器对象实际上是一个hapiJS服务器对象。您可以按如下方式创建新界面:

// inside your init method:server.route({  path: '/api/elasticsearch_status/index/{name}',  method: 'GET',  handler(req, reply) {    // more to come here in the next step    reply("Hello World");  }});

这样,您可以在Kibana服务器上创建一个新的GET API。你现在可以调用该/api/elasticsearch_status/index/接口(现在也没有做任何事情)。处理程序方法将获得两个参数:第一个是已经创建的请求。您可以从此处的请求中访问很多(例如,使用req.params.name您将获取在URL中传递的索引的名称)。第二个参数是回复函数。您必须调用此函数并将其应该返回的数据传递给调用此API的客户端。

有关完整的文档,请查看路由方法的官方hapi文档。(https://hapijs.com/api#serverrouteoptions)

查询elasticsearch

现在我们需要以某种方式从实际上处理查询Elasticsearch以相关索引的数据。有一个实用方法来调用Elasticsearch,我们可以使用。这个方法也是我们在index.js中对弹性搜索模块的要求的原因。以下代码将进入我们API的处理函数:

server.plugins.elasticsearch.callWithRequest(req, 'cluster.state', {  metric: 'metadata',  index: req.params.name}).then(function (response) {  reply(response.metadata.indices[req.params.name]);});

我们需要将API中的请求作为第一个参数传递给该callWithRequest方法。这种方法在Kibana服务器的调用和Elasticsearch的调用之间进行传递认证。第二个参数是我们要调用的Elasticsearch JavaScript客户端的函数的名称- 在我们的例子中,我们要调用该cluster.state()方法,并且我们要将索引(从请求参数读出)传递给方法。

该方法返回一个将通过Elasticsearch的响应解决的承诺。在resolve函数中,我们将从响应(在我们的例子中是索引stats)中提取我们需要的数据,并返回它(通过该reply方法)。

如果您正在为Kibana 5.2开发callWithRequest,这个博客中概述的使用会有轻微的变化。

我们创建了一个Kibana服务器API,现在可以调用它了。如果您注意GitHub的源代码,您将注意到,我将API生成提取到另一个模块,并且从init方法中调用此方法。我建议这样做,以保持你的代码可读 - 如果你有很多API你创建,你甚至可能想要使用多个模块。

第二个服务器API(用于获取所有索引的列表)可以在源代码中找到。我不会在这篇博文中详细介绍,因为我们已经涵盖了所有主题,你可以自己写。

创建前端

我们应该为我们的插件创建一个前端。我们之前已经注册了一个特定app.js和index.js作为主文件。现在是来写他们的时候了。

我们将插入文件的前两行如下:

import 'ui/autoload/styles';import './less/main.less';

如果您使用 Kibana 5,则第一行很重要,您应该始终将其放在插件中。这将使Kibana加载其通常具有的所有样式。如果您不导入(或要求,如果您喜欢ES5语法)此模块,您的应用程序会和kibana框架看起来格格不入。如果您使用Kibana 4,此文件不存在,您无法导入(这让我们回到第一篇文章中的巨大警告,关于缺少稳定的公共API)。

第二行是可选的,并显示如何为您的应用程序插入自己的LESS样式。您只需导入您的LESS文件。您也可以使用SASS。我建议使用相对路径,这些文件也在您的public件夹,所以你不需要重复你的插件ID。

创建路由选项

Kibana使用AngularJS’ngRouter在页面之间进行路由。如果您的应用程序想要使用路由,则必须明确启用它,并在app.js文件中配置一些路由:

import uiRoutes from 'ui/routes';import overviewTemplate from './templates/index.html';import detailTemplate from './templates/detail.html';uiRoutes.enable();uiRoutes.when('/', {  template: overviewTemplate,  controller: 'elasticsearchStatusController',  controllerAs: 'ctrl'}).when('/index/:name', {  template: detailTemplate,  controller: 'elasticsearchDetailController',  controllerAs: 'ctrl'});

如果需要使用路由,必须定义uiRoutes.enable()。之后,您可以使用when和otherwise调用,就像您使用$routeProvider。在这种情况下,我们要配置两个路由:一个用于基本路径,一个用于路径/index/:name,该名称是索引名称的占位符。可以通过使用import上面的语句将实际的html文件(这些templates文件放在本例中的文件夹中)来设置两个路由的模板。我们还使用两个控制器,我们还没有写。

下面我们写控制器,我们使用全局模块注册表Kibana:

import uiModules from 'ui/modules';uiModules.get('app/elasticsearch_status').controller('elasticsearchStatusController', function ($http) {  $http.get('../api/elasticsearch_status/indices').then((response) => {    this.indices = response.data;  });});

uiModules是Kibana的核心服务,负责应用中的所有模块。如果要获取或创建一个,请使用其get方法。第一个参数是要获取或创建的模块的名称。如果模块已经存在或者没有创建它,该服务将负责返回模块。第二个参数可以是一个模块数组,模块依赖。如果模块已经存在,那么这些模块在返回之前将被添加到模块的依赖关系列表中。这些模块不存在,只需将它们添加到新创建的模块中即可。

当您看到此行为与angular.module方法不同时,您在指定依赖关系时创建模块,并在不传递第二个参数时获取模块。使用这种服务,Kibana也会关心加载我们的角度模块。

上面的控制器本身就是使用$http服务来从我们的接口获取索引列表,并将其存储在控制器中。

最后一个缺失的部分现在是我们的模板templates/index.html:

<div class="container">  <div class="row">    <div class="col-12-sm">      <h1>Elasticsearch Status</h1>      <ul class="indexList">        <li ng-repeat="index in ctrl.indices">          <a href="#/index/{{index}}">{{ index }}</a>        </li>      </ul>    </div>  </div></div>

我们的教程中的HTML保持相当简单。我们只是ng-repeat用来迭代所有的索引,我们从API中检索并链接到它们。此外,我们使用一些Bootstrap的CSS类来设计我们的内容。详细页面的HTML可以在GitHub的源代码中找到。

在Kibana 5开始,Kibana将只给你旁边的导航,如上图所示。一旦你被切换到你的插件,没有标题栏或任何东西。如果你想要这种样式,你将不得不在你的创建它。在Kibana 5之前,您仍然可以获得bar,并可以通过服务进行修改:

import chrome from 'ui/chrome';chrome.setNavBackground('#FF00FF') // Turns the navbar in beautiful pink.setBrand({  logo: '<CSS background property value for the logo>',  smallLogo: '<CSS background property value a smaller version>'});
1 0
原创粉丝点击