主页入口

kibana 4 主页入口,分析方法跟 kibana 3 一样,看 index.html 和 require.config.js 即可。由此可以看到,首先进入的,应该是 index.js。主要分为两步。

第一步,route 设置

define(function (require) {
  var angular = require('angular');
  var _ = require('lodash');
  var $ = require('jquery');
  var modules = require('modules');
  var routes = require('routes');

  var configFile = JSON.parse(require('text!config'));

  var kibana = modules.get('kibana', [
    'elasticsearch',
    'pasvaz.bindonce',
    'ngRoute',
    'ngClipboard'
  ]);

  kibana
    .constant('kbnVersion', window.KIBANA_VERSION)
    .constant('minimumElasticsearchVersion', '1.6.0')
    .constant('sessionId', Date.now())
    .config(routes.config);

  routes
    .otherwise({
      redirectTo: '/' + configFile.default_app_id
    });

index.js 根据 configFile 设置默认 routes,设置要求的 Elasticsearch 版本;

设置 routes 的具体操作在加载的 utils/routes/index.js 文件里,其中会调用 utils/routes/_setup.js,在未设置 default index pattern 的时候跳转 URL 到 "/settings/indices" 页面。

此外,utils/routes/index.js 还会加载 components/setup/setup.js 完成整个环境的检查和启动(在 Kibana4.0 时,是在第二步 kibana plugin 加载的,4.1 开始往前挪到这里)。setup 过程包括:

也就是依次调用 components/setup/steps/ 下的 check_for_es, check_es_version, check_for_kibana_index,如果没有 kibana index,再调用一个 create_kibana_index。完成。

第二步,kibana 插件加载

执行 kibana.load() 函数,先加载 plugins/kibana/index.js,然后加载 configFile 里定义的其他 plugins。

plugins/kibana/index.js 里又有一系列操作:

  1. 加载 components/courier/courier.jscomponents/config/config.js 两个 angular.service;

  2. 加载 plugins/kibana/_init, plugins/kibana/_apps, plugins/kibana/_timepicker

components/config/config.js 主要是从 kibana index 里的 "config" type 中读取 "kbnVersion" id 的数据。这个 "kbnVersion" 就是之前 index.js 里的加载的第一个常量,在 grunt build 编译时会自动生成。

plugins/kibana/_init 里监听 application.load 事件,触发 courier.start() 函数。

plugins/kibana/_timepicker 提供时间选择器页面。

courier 概述

components/courier/courier.js 中定义了 Courier 类。Courier 是一个非常重要的东西,可以简单理解为 kibana 跟 ES 之间的一个 object mapper。简要的说,包括一下功能:

从类的方法中可以看出,其实主要就是五个属性的控制:

  • DocSource 和 SearchSource:继承自 components/courier/data_source/_abstract.js,调用 components/courier/data_source/data_source/_doc_send_to_es.js 完成跟 ES 数据的交互,用来做 savedObject 和 index_pattern 的读写:

这个 es 在是调用了 services/es.js 里定义的 service,里面内容超级简单,就是加载官方的 elasticsearch.js 库,然后初始化一个最简的 esFactory 客户端,包括超时都设成了 0,把这个控制交给 server 端。

  • searchLooper 和 docLooper:分别给 Looper.start 方法传递 searchStrategy 和 docStrategy,对应 ES 的 /_msearch/_mget 请求。searchLooper 的实现如下:

这里的关键方法是 fetch.these(),出自 components/courier/fetch/_fetch_these.js,其中调用的 components/courier/fetch/_call_client.js 有如下一段代码:

在这段代码中,我们可以看到 strategy.reqsFetchParamsToBody(), strategy.getResponses()strategy.clientMethod,正是之前 searchLooper 和 docLooper 传递的对象属性。而最终发送请求,同样用的是前面解释过的 es 这个 service。

此外,Courier 还提供了自动刷新的控制功能:

路径记忆功能的实现

plugins/kibana/_apps.js 中,我们可以看到路径记忆功能是怎么实现的:

这里使用的 sessionStorage 是 HTML5 自带的新特性,这样,每次标签页切换的时候,都可以把 $location.url 保存下来。至于整个 Kibana 页面上标签页的初始状态,则通过 registry/apps.js 获取。

插件的加载

那么,各标签页插件是怎么进到 registry/apps 里的呢?

之前我们已经说过,index.js 一开始加载完 kibana 以后,会挨个 require(configFile.plugins)。这个 configFile.plugins 按说就应该是列出来各个标签页了,但实际上,K4 的配置文件 server/config/kibana.yml 里并没有一个参数叫 plugins。所以,还得看看 server 端的实现了。

和阅读 Kibana 主页入口一样,找到 server 端的主入口 server/index.js

根据这段代码,我们知道,K4 的 server 端,统一也有插件机制,由 server/lib/plugins/require_plugins.js 加载内置 server 插件,然后再加上外部 server 插件目录。requirePlugins 中查找内置插件的方法如下:

也就是说,加载 server/plugins/ 下所有子目录的 index.js。目前 K4 自带的有:config, elasticsearch, static, status。分别用来返回 config 数据,代理 ES 请求,处理纯静态文件请求,显示 server 端各插件状态。

我们具体看这个 server/plugins/config/index.js 的内容:

很明显,一个标准的 node.js 的 route,用来响应对 "/config" 这个地址的 GET 请求,返回一个哈希 JSON,其中就有 plugins。没错,我们前面说的 configFiles.plugins 就是从这里获得的。

下面看这个 listPlugins 的实现。

这个 "bundledPluginsFolder" 也不是我们 kibana.yml 里存在的参数设置。所以,还得看上面这行 server.config() 了。回到最早先的 server/index.js 里,其实在 require_plugins 后面,还有一个 extend_hapi。Hapi 是 nodejs 的一个可扩展框架。我们看到 index.js 中,正是在 extendHapi(this.server) 后第一次获取了 server.config()

extendHapi 只有两行:

这个 server/lib/config/index.js 主要加载同目录下的:config.js 用来实现 Config 类,schema.js 用来实现具体的 Joi 对象。

然后我们看这个 server/lib/config/schema.js,就会发现各种配置属性全在这里了~和插件路径相关的几行如下:

这里有两个路径,因为一个是源码位置,一个是 grunt build 编译后的位置。就我们阅读源码来说,这个 __dirname/../../../kibana/plugins 就是我们最终找到的地方了,我们从 server 端源码里找了一圈,终于回到 kibana 前端页面的源码目录中,这就是 kibana/plugins 目录,自动加载其下所有子目录为内置插件。包括:

  • dashboard

  • discover

  • doc

  • kbn_vislib_vis_types

  • kibana

  • markdown_vis

  • metric_vis

  • settings

  • table_vis

  • vis_debug_spy

  • visualize

除 kibana 以外,随意进一个,(还记得 index.js 里是把 kibana 去除掉了吧),比如 visualize,看 visualize/index.js 的内容,最底下有这么一段:

其他目录也都一样。

这个 registry/apps.js 主要是加载 registry/_registry.js,把注册的 app 存入 utils/indexed_array/index 的 IndexedArray 对象。对象主要有几个值:id, name, order。前面说到的路径记忆功能要用的两个方法,assignPaths 里就是用 app.id 设置 lastPath,而 getShow 里就是用 order 来判断是否展示在页面上。

下一章,我们开始介绍官方提供的几个 apps。

Last updated

Was this helpful?