Slide 1

Slide 1 text

‹#› Tanya Bragin Spencer Alger Feb 19 2016 How to Build Your Own Kibana Plug-ins

Slide 2

Slide 2 text

‹#› Extensibility In Kibana

Slide 3

Slide 3 text

Why is extensibility important? 3

Slide 4

Slide 4 text

History of Kibana extensibility • Open source - can always fork it • Kibana 3 custom panels • Kibana 4 plugins 4

Slide 5

Slide 5 text

Goals of Kibana plugins • Evolution of Elastic UI • Experimentation === Innovation • Building cross-stack applications • Crowd-sourcing extensions 5

Slide 6

Slide 6 text

Disclaimer: Plugin framework will continue to evolve 6

Slide 7

Slide 7 text

Quick Poll 7

Slide 8

Slide 8 text

‹#› Plugin Development

Slide 9

Slide 9 text

Plugin Resources Remember this 9 bit.ly/kibana-plugins

Slide 10

Slide 10 text

I'm not talking about Kibana 10 When I say Kibana... !

Slide 11

Slide 11 text

11

Slide 12

Slide 12 text

12 Server UiExports Kibana bin/kibana Plugins HTTP Config Logging ! ! ! !

Slide 13

Slide 13 text

Starting a new plugin • Download kibana • Download boilerplate 13 https://www.elastic.co/downloads/kibana/ https://github.com/spalger/kibana-plugin-boilerplate

Slide 14

Slide 14 text

14 ! The simplest plugin first

Slide 15

Slide 15 text

15 DEMO

Slide 16

Slide 16 text

16 DEMO

Slide 17

Slide 17 text

17 ! Using the plugin generator

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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 ...

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

where the party starts 24 Meet index.js !

Slide 25

Slide 25 text

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', // ... }); };

Slide 26

Slide 26 text

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', // ... }); };

Slide 27

Slide 27 text

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({

Slide 28

Slide 28 text

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({

Slide 29

Slide 29 text

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) {

Slide 30

Slide 30 text

Meet index.js 30 //... config(Joi) { return Joi.object({ enabled: Joi.boolean().default(true), esIndex: Joi.string().required(), }).default(); }, init(server, options) { exampleRoute(server); } });

Slide 31

Slide 31 text

Meet index.js 31 //... init(server, options) { exampleRoute(server); } }); };

Slide 32

Slide 32 text

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() }); } }); };

Slide 33

Slide 33 text

33 Server UiExports Kibana bin/kibana Plugins HTTP Config Logging ! ! ! !

Slide 34

Slide 34 text

34 Logging from a kibana plugin Make some noise ! ! ! !

Slide 35

Slide 35 text

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);
 } }); };

Slide 36

Slide 36 text

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 ......

Slide 37

Slide 37 text

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);
 } }); };

Slide 38

Slide 38 text

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 ......

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

40 Lets do something client side ! ! ! !

Slide 41

Slide 41 text

41

Slide 42

Slide 42 text

42

Slide 43

Slide 43 text

43 http://bl.ocks.org/tomerd/1499279

Slide 44

Slide 44 text

44 DEMO

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

UI Export Types • visTypes • Use in Visualize • Support for "embed" mode • Viewable on the Dashboard 46

Slide 47

Slide 47 text

UI Export Types • docViews • Render any document • Works inside dashboard search panels 47

Slide 48

Slide 48 text

UI Export Types • Hacks • Included in every application • No restrictions • Hook into angular • Manipulate the DOM • Inject stylesheets • Whatever! 48

Slide 49

Slide 49 text

UI Export Types • fieldFormats • spyModes • chromeNavControls • chromeConfigControls • navbarExtensions • settingsSections • aliases 49

Slide 50

Slide 50 text

‹#› Plugins by Elastic

Slide 51

Slide 51 text

Sense 51

Slide 52

Slide 52 text

Timelion 52 {re}search app by rashidkpc

Slide 53

Slide 53 text

Monitoring 53

Slide 54

Slide 54 text

Security 54

Slide 55

Slide 55 text

Reporting 55

Slide 56

Slide 56 text

‹#› Plugins by the Community

Slide 57

Slide 57 text

Prelert Anomaly Detective Elastic{ON} partner sponsor 57

Slide 58

Slide 58 text

Radar 58 by SIREN

Slide 59

Slide 59 text

Tag cloud 59 by stormpython

Slide 60

Slide 60 text

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