Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to Build Your Own Kibana Plug-ins

Elastic Co
February 19, 2016

How to Build Your Own Kibana Plug-ins

Meet the Kibana of the future. It’s the Kibana you know and love, but with extension points for you to add your own, custom functionality. In this talk Tanya and Spencer from the Kibana team will walk you through building your first Kibana plugin.

Elastic Co

February 19, 2016
Tweet

More Decks by Elastic Co

Other Decks in Technology

Transcript

  1. History of Kibana extensibility • Open source - can always

    fork it • Kibana 3 custom panels • Kibana 4 plugins 4
  2. Goals of Kibana plugins • Evolution of Elastic UI •

    Experimentation === Innovation • Building cross-stack applications • Crowd-sourcing extensions 5
  3. 11

  4. Starting a new plugin • Download kibana • Download boilerplate

    13 https://www.elastic.co/downloads/kibana/ https://github.com/spalger/kibana-plugin-boilerplate
  5. Using the plugin generator • Setup your kibana development environment

    • Install the kibana plugin generator 18 http://bit.ly/contributing-to-kibana https://npmjs.org/generator-kibana-plugin
  6. Using the plugin generator 19 $ mkdir my_plugin $ cd

    my_pulgin $ yo kibana-plugin ? Your Plugin Name my_kibana_plugin ? Short Description An awesome Kibana plugin create package.json create index.js create public/app.js create public/less/main.less create public/templates/index.html ...
  7. Using the plugin generator 20 my_kibana_plugin/ .eslintrc .gitignore package.json index.js

    public/ app.js less/main.less templates/index.html server/ routes/example.js
  8. Using the plugin generator 21 my_kibana_plugin/ .eslintrc .gitignore package.json index.js

    public/ app.js less/main.less templates/index.html server/ routes/example.js
  9. Using the plugin generator 22 my_kibana_plugin/ .eslintrc .gitignore package.json index.js

    public/ app.js less/main.less templates/index.html server/ routes/example.js
  10. Using the plugin generator 23 npm start Start kibana and

    have it include this plugin npm run build Build a distributable archive npm run test:browser Run the browser tests in a real web browser npm tun test:server Run the server tests using mocha
  11. Meet index.js 25 import exampleRoute from './server/routes/example'; export default function

    (kibana) { return new kibana.Plugin({ require: ['elasticsearch'], uiExports: { app: { title: 'My Kibana Plugin', description: 'An awesome Kibana plugin', // ... }); };
  12. Meet index.js 26 import exampleRoute from './server/routes/example'; export default function

    (kibana) { return new kibana.Plugin({ require: ['elasticsearch'], uiExports: { app: { title: 'My Kibana Plugin', description: 'An awesome Kibana plugin', // ... }); };
  13. Meet index.js 27 // ... return new kibana.Plugin({ require: ['elasticsearch'],

    uiExports: { app: { title: 'My Kibana Plugin', description: 'An awesome Kibana plugin', main: 'plugins/my_kibana_plugin/app' } }, config(Joi) { return Joi.object({
  14. Meet index.js 28 // ... return new kibana.Plugin({ require: ['elasticsearch'],

    uiExports: { app: { title: 'My Kibana Plugin', description: 'An awesome Kibana plugin', main: 'plugins/my_kibana_plugin/app' } }, config(Joi) { return Joi.object({
  15. Meet index.js 29 // ... uiExports: { app: { title:

    'My Kibana Plugin', description: 'An awesome Kibana plugin', main: 'plugins/my_kibana_plugin/app' }, hacks: [ 'plugins/my_kibana_plugin/hack' ] }, config(Joi) {
  16. Meet index.js 30 //... config(Joi) { return Joi.object({ enabled: Joi.boolean().default(true),

    esIndex: Joi.string().required(), }).default(); }, init(server, options) { exampleRoute(server); } });
  17. Meet index.js 32 export default function (server) { server.route({ path:

    '/api/my_kibana_plugin/example', method: 'GET', handler(req, reply) { reply({ time: (new Date()).toISOString() }); } }); };
  18. Make some noise use your init() function 35 export default

    function (kibana) { return new kibana.Plugin({ //... init(server) { exampleRoute(server); const msg = `server address is: ${server.info.uri}`; console.log(msg);
 } }); };
  19. Starting a new plugin 36 $ npm start > [email protected]

    start /dev/my_kibana_plugin > ../kibana/bin/kibana --dev --plugin-path=. watching for changes (112 files) server log [info][optimize] Waiting for optimizer completion optmzr log [info][optimize] Lazy optimization of bundles for kiba server address is: https://localhost:5603 server log [info][status][plugin:my-kibana-plugin] Status changed server log [info][status][plugin:devMode] Status changed from uni server log [info][status][plugin:kibana] Status changed from unin ......
  20. Starting a new plugin 37 export default function (kibana) {

    return new kibana.Plugin({ //... init(server) { exampleRoute(server); const msg = `server address is: ${server.info.uri}`; server.log(['info'], msg);
 } }); };
  21. Starting a new plugin 38 $ npm start > [email protected]

    start /dev/my_kibana_plugin > ../kibana/bin/kibana --dev --plugin-path=. watching for changes (112 files) server log [info][optimize] Waiting for optimizer completion optmzr log [info][optimize] Lazy optimization of bundles for kiba server log [info] server address is: https://localhost:5603 server log [info][status][plugin:my-kibana-plugin] Status changed server log [info][status][plugin:devMode] Status changed from uni server log [info][status][plugin:kibana] Status changed from unin ......
  22. Starting a new plugin 39 $ npm start -- --logging.json=true

    > [email protected] start /Users/spalger/dev/es/my_kibana_plugin > ../kibana/bin/kibana --dev --plugin-path=. "--logging.json=true" watching for changes (112 files) {"type":"log","@timestamp":"2016-02-16T05:24:54+00:00","tags":["listening","info"],"pid":41523,"message":"basePath Proxy running at https:/ {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info","optimize"],"pid":41527,"message":"Waiting for optimizer completion"} {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info","optimize"],"pid":41526,"bundles":["kibana","statusPage"],"message":" {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info"],"pid":41526,"message":"Plugin initialization disabled."} {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info"],"pid":41527,"message":"server address is: https://localhost:5603"} {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:my-kibana-plug","info"],"pid":41527,"name":"plugin:my-kiban {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:devMode","info"],"pid":41527,"name":"plugin:devMode","state {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:kibana","info"],"pid":41527,"name":"plugin:kibana","state": {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:elasticsearch","info"],"pid":41527,"name":"plugin:elasticse {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:kbn_doc_views","info"],"pid":41527,"name":"plugin:kbn_doc_v {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:kbn_vislib_vis_types","info"],"pid":41527,"name":"plugin:kb {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:markdown_vis","info"],"pid":41527,"name":"plugin:markdown_v {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:metric_vis","info"],"pid":41527,"name":"plugin:metric_vis", {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:spyModes","info"],"pid":41527,"name":"plugin:spyModes","sta {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:statusPage","info"],"pid":41527,"name":"plugin:statusPage", {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:table_vis","info"],"pid":41527,"name":"plugin:table_vis","s {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info","optimize"],"pid":41526,"bundles":["kibana","statusPage"],"message":" {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:testsBundle","info"],"pid":41527,"name":"plugin:testsBundle {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:elasticsearch","info"],"pid":41527,"name":"plugin:elasticse {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["listening","info"],"pid":41527,"message":"Server running at https://localho $ npm start -- --logging.json=true > [email protected] start /Users/spalger/dev/es/my_kibana_plugin > ../kibana/bin/kibana --dev --plugin-path=. "--logging.json=true" watching for changes (112 files) {"type":"log","@timestamp":"2016-02-16T05:24:54+00:00","tags":["listening","info"],"pid":41523,"message":"basePath Proxy running at https:/ {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info","optimize"],"pid":41527,"message":"Waiting for optimizer completion"} {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info","optimize"],"pid":41526,"bundles":["kibana","statusPage"],"message":" {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info"],"pid":41526,"message":"Plugin initialization disabled."} {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info"],"pid":41527,"message":"server address is: https://localhost:5603"} {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:my-kibana-plug","info"],"pid":41527,"name":"plugin:my-kiban {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:devMode","info"],"pid":41527,"name":"plugin:devMode","state {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:kibana","info"],"pid":41527,"name":"plugin:kibana","state": {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:elasticsearch","info"],"pid":41527,"name":"plugin:elasticse {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:kbn_doc_views","info"],"pid":41527,"name":"plugin:kbn_doc_v {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:kbn_vislib_vis_types","info"],"pid":41527,"name":"plugin:kb {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:markdown_vis","info"],"pid":41527,"name":"plugin:markdown_v {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:metric_vis","info"],"pid":41527,"name":"plugin:metric_vis", {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:spyModes","info"],"pid":41527,"name":"plugin:spyModes","sta {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:statusPage","info"],"pid":41527,"name":"plugin:statusPage", {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:table_vis","info"],"pid":41527,"name":"plugin:table_vis","s {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["info","optimize"],"pid":41526,"bundles":["kibana","statusPage"],"message":" {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:testsBundle","info"],"pid":41527,"name":"plugin:testsBundle {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["status","plugin:elasticsearch","info"],"pid":41527,"name":"plugin:elasticse {"type":"log","@timestamp":"2016-02-16T05:24:56+00:00","tags":["listening","info"],"pid":41527,"message":"Server running at https://localho
  23. 41

  24. 42

  25. UI Export Types • apps • Can use exports from

    any plugins • Listed in the App Switcher • Has full control of the viewport • Can use existing directives, services, filters, styles, etc. • Can also be build totally custom 45
  26. UI Export Types • visTypes • Use in Visualize •

    Support for "embed" mode • Viewable on the Dashboard 46
  27. UI Export Types • docViews • Render any document •

    Works inside dashboard search panels 47
  28. UI Export Types • Hacks • Included in every application

    • No restrictions • Hook into angular • Manipulate the DOM • Inject stylesheets • Whatever! 48
  29. UI Export Types • fieldFormats • spyModes • chromeNavControls •

    chromeConfigControls • navbarExtensions • settingsSections • aliases 49
  30. Try it out! • Check us out on Github •

    Ask questions on the Discuss forum • Engage with us on IRC (#kibana on Freenode) • Leverage community resources 60 bit.ly/kibana-plugins