Developing Kibana Plugins

Front-end

For quite some time I’ve been meaning to rewrite an old Elasticsearch plugin to a new Kibana plugin. It’s quite different than you were used to. The Kibana plugins are quite new and were released in version 4.2.0. There are quite a few warnings on the Kibana Github issues regarding not having a public API yet or not making plugins at all. Essentially this means you need to keep up with the Kibana releases if you’d like to proceed anyway.

Starting

First you would need to set-up a Kibana development environment. In order to do this you can follow these steps: https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#development-environment-setup. I would recommend not to pick the master branch.

Kibana Plugin Yeoman Generator

Next up is generating the boilerplate for your Kibana plugin using the Kibana Plugin Yeoman Generator. When following the instructions of the readme please notice there is an instruction to put the Kibana development environment at the same folder level as your plugin named kibana.

What did you get?

After we generated the project there is in the root of the project a file called index.js listed below, which ties up the whole project together. In this file we see the configuration of a Kibana plugin. The uiExports object configures your frontend of the plugin. There are more variants other than ‘app’ that can be found here. The properties an app can have are listed in the source code here. The ‘main’ property lists the path to your angular code, which is in fact the public folder of your project.

code
import exampleRoute from './server/routes/example';
 
export default function (kibana) {
  return new kibana.Plugin({
    require: ['elasticsearch'],
     
    // Your frontend app
    uiExports: {
      app: {
        title: 'Example',
        description: 'An awesome Kibana plugin',
        main: 'plugins/example/app'
      }
    },
 
    config(Joi) {
      return Joi.object({
        enabled: Joi.boolean().default(true),
      }).default();
    },
 
    init(server, options) {
      // Add server routes and initalize the plugin here
      exampleRoute(server);
    }
 
  });
};

The latter part of the sample above contains configuration for a hapijs server. With this you’re able to write your custom backend API. More of this you can find in the server/routes folder.

The frontend

In the public/app.js file we can find two important parts of code. One of which is the part with uiRoutes. This object allows you to embed your routing within Kibana. The syntax of the routing is according angular’s ngRoute module. When you don’t need routing remove it.

code
uiRoutes.enable();
uiRoutes
    .when('/', {
        template,
        resolve: {
            currentTime($http) {
                return $http.get('../api/example/example').then(function (resp) {
                    return resp.data.time;
                });
            }
        }
    });

The latter part has the uiModules object which is in charge of generating dynamic modules on the fly and coupling them. You can see the uiModules.get() function as replacement for angular.module().

code
uiModules
    .get('app/example', [])
    .controller('exampleHelloWorld', function ($scope, $route, $interval) {
        $scope.title = 'Example';
        $scope.description = 'An awesome Kibana plugin';
 
        var currentTime = moment($route.current.locals.currentTime);
        $scope.currentTime = currentTime.format('HH:mm:ss');
        var unsubscribe = $interval(function () {
            $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
        }, 1000);
        $scope.$watch('$destroy', unsubscribe);
    });

When writing the templates and styles you should keep in mind that Kibana uses Twitter Bootstrap. Another note is that in the previous file mentioned there is also a chrome object, which you can ignore it will be deprecated in Kibana 5.0.0. It was used to control the navbar.

Result

When all went well this should be the result.
Kibana Plugin Example Screenshot

Useful links

Source Sense
Source Timelion
Kibana styleguide
The plugin I’m converting
More information about plugins

Front-end